Ir al contenido principal

Solana gRPC Vixen: supervisión en tiempo real de las órdenes limitadas de Jupiter en Rust

Actualizado el
Aug 07, 2026

19 minutos de lectura

Resumen

Esta guía explica cómo crear un monitor de órdenes limitadas de Jupiter en tiempo real en Rust utilizando Solana gRPC (Geyser gRPCYellowstone) y Vixen, un conjunto de herramientas de análisis Solana basado en Rust. La aplicación streams las transacciones streams de órdenes limitadas y registra las órdenes introducidas, las ejecuciones y las cancelaciones con importes y símbolos de tokens legibles para el usuario. A lo largo del proceso, la guía muestra tres características de Vixen v0.6.1: la generación de código para el analizador basado en IDL mediante proc-macro, la falló campo en Prefiltro de transacciones para filtrar las transacciones fallidas y el seguimiento estructurado para facilitar la observabilidad.


En resumen
  • Crea un monitor en tiempo real de órdenes limitadas de Jupiter v2 en Rust utilizando Solana gRPC Vixen
  • Genera un analizador sintáctico con seguridad de tipos directamente a partir del IDL de órdenes limitadas de Jupiter utilizando Vixen's include_vixen_parser! proc-macro
  • Transmite únicamente las transacciones confirmadas (que no hayan fallado) utilizando Vixen v0.6.1 Prefiltro de transacciones
  • Registra las órdenes, las ejecuciones y las cancelaciones utilizando símbolos de tokens y importes legibles para las personas
  • Ejecutarse engRPC Solana QuicknodegRPC mainnetSolana )

Tus funciones


  • Configurar un proyecto de Rust con las dependencias de Vixen v0.6.1
  • Recuperar y convertir el código IDL de Jupiter Limit Order v2 al formato Codama
  • Generar un analizador sintáctico de instrucciones con seguridad de tipos utilizando la macro «proc» de Vixen
  • Implementa un controlador que registre los eventos relacionados con las órdenes limitadas con una salida legible para el usuario.
  • Compilar y ejecutar un entorno de ejecución de Vixen conectado alendpointgRPC Solana Quicknode

Lo que necesitarás


Esta guía también utiliza los siguientes paquetes:

DependenciaVersión
rustc1.85.0
yellowstone0.6.1
yellowstone0.6.1
yellowstone0.6.1
yellowstone0.6.1
grpc0.6.1
borsh1
bs580.5
crono0.4
solicitud0.12
serde1
aplauso4
susurros0.23
toml0.8
rastreo0.1
localización de abonados0.3

¿Qué es Solana gRPC?

Solana gRPC una solución de transmisión de datos de alto rendimiento para Solana en el sistema de complementos Geyser. En lugar de consultar un endpoint RPC endpoint nuevos datos o gestionar las reconexiones de WebSocket, Solana gRPC las actualizaciones de cuentas, las transacciones y las notificaciones de slots a tu aplicación en forma de flujo continuo. Esto proporciona una menor latencia y un mayor rendimiento en comparación con los enfoques tradicionales.

Quicknode unendpointgRPC Solana gestionado. Está incluido en los planes Scale y Business; en los planes Build y Accelerate, sigue estando disponible a través del gRPC Solana . Puedes activarlo en cualquierendpoint Solana endpoint el Quicknode , que proporciona unendpoint gRPC específicoendpoint un token de autenticación para tu aplicación.

Entre las principales funciones de filtrado se incluyen:


  • Filtra por dirección de programa para recibir únicamente las transacciones relacionadas con un programa concreto
  • Filtrar las transacciones fallidas para que solo se procesen los eventos confirmados en la cadena de bloques
  • Filtrar las transacciones de voto para reducir el ruido

¿Qué es Vixen?

Vixen es un marco de trabajo de código abierto escrito en Rust que permite crear flujos Solana basados engRPC Solana . Se encarga automáticamente de gRPC , el filtrado de transacciones y la deserialización, de modo que el código de la aplicación recibe estructuras de Rust tipadas en lugar de bytes sin procesar.

Vixen utiliza una arquitectura de «analizador + controlador » para separar la extracción de datos de la lógica de negocio:


  • Analizador sintáctico: Deserializa datos de transacciones sin procesar en estructuras tipadas de Rust
  • Manejador: Recibe los datos analizados e implementa la lógica de tu aplicación
  • Canalización: conecta un analizador con uno o varios controladores
  • Tiempo de ejecución: gestiona la gRPC , la suscripción al flujo y la ejecución del proceso.

Según las notas de la versión 0.6.1 de Vixen, esta versión incorpora tres mejoras orientadas a la producción que se muestran en esta guía:


  1. Generación de código basada en IDL mediante una macro de procedimiento: Generar un analizador sintáctico con seguridad de tipos directamente a partir del IDL de un programa utilizando include_vixen_parser!, lo que elimina el código de deserialización manual
  2. falló campo en Prefiltro de transacciones: Excluye las transacciones fallidas del flujo para que solo los eventos confirmados en la cadena de bloques lleguen a tu controlador
  3. Seguimiento de tramos para la observabilidad: Salida de registro estructurada y filtrable a través de la rastreo «crate» en lugar de «plain» registro/env_logger

Vixen contra Carbon

Tanto Vixen como Carbon son marcos de trabajo de Rust para el análisis de datos Solana . Comparten el mismo enfoque básico: procesan las transacciones en tiempo real a través de Solana gRPC, descodifican los datos de las instrucciones en estructuras tipadas y procesan los eventos en los controladores; sin embargo, difieren en cómo generan los analizadores y en las fuentes de datos que admiten:

CaracterísticaVixenCarbono
Generación de analizadores sintácticosGenerador de código IDL a través de include_vixen_parser! macro de procedimiento en tiempo de compilaciónCajas de decodificadores preconfiguradas + generador de código desde la línea de comandos a partir de IDL
Fuentes de datosSolana gRPCSolana gRPC, JITO Shredstream, JSON RPC
Compatibilidad integrada con programasNinguno — generar a partir de cualquier IDL de AnchorMás de 60 decodificadores preconfigurados para programas populares
Configuración de un programa compatibleObtener IDL → convertir a Codama → invocación de macroAñadir una única dependencia de «Cargo crate»
Observabilidadrastreo caja con tramos estructuradosMétricas y registro de Prometheus
Modelo de canalizaciónEntorno de ejecución → Canalización → Analizador → GestorCanal → Fuente de datos → Decodificador → Procesador

Para consultar una guía sobre Carbon, véase Solana gRPC Carbon: Analizar datos Solana en tiempo real».

La aplicación de ejemplo: Jupiter Limit Order Monitor

Jupiter Limit Orders es un libro de órdenes en cadena que permite a los operadores realizar órdenes que se ejecutan automáticamente cuando el mercado alcanza un precio determinado. A diferencia de los intercambios instantáneos, las órdenes limitadas permanecen en la cadena hasta que un «keeper» (denominado receptor en las cuentas del programa) las ejecuta al precio solicitado o a un precio mejor. El creador también puede cancelar una orden no ejecutada en cualquier momento para recuperar sus tokens.

En esta guía se utilizan las órdenes limitadas de Júpiter por tres razones:


  1. Toda la actividad se canaliza a través de un único programa Anchor (j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X), que se ajusta perfectamente al modelo de canal único de Vixen.
  2. El programa publica un IDL en la cadena de bloques, lo que nos permite demostrar de principio a fin la función de generación de código IDL de Vixen.
  3. El programa emite tres tipos de instrucciones independientes y semánticamente distintas (una por cada evento del ciclo de vida), lo que hace que la lógica del controlador sea fácil de leer y ampliar.

Las tres instrucciones que supervisa esta guía son:


  • Inicializar pedido: Un creador realiza una nueva orden limitada en la que especifica los tokens de entrada y salida, así como las cantidades correspondientes
  • FillOrder: Una orden de mantenimiento se ejecuta al precio solicitado o a un precio mejor que este.
  • Cancelar pedido: Un creador cancela su orden no ejecutada y recupera sus tokens

Para cada evento, el gestor obtiene los símbolos de los tokens legibles para el usuario a partir de la API de tokens de Jupiter y formatea los importes brutos de los tokens utilizando la precisión decimal que figura en los metadatos del saldo de tokens de la transacción.

Configurar el proyecto

Crea el directorio del proyecto y un idls carpeta para guardar el IDL de la orden limitada de Jupiter:

carga nuevo jupiter-lo-vixen
cd jupiter-lo-vixen
mkdir idls

Sustituye el contenido de Cargo.toml con lo siguiente. Todas las crates de Vixen están fijadas a la versión v0.6.1:

Cargo.toml
[package]
name = "jupiter-lo-vixen"
version = "0.1.0"
edition = "2021"

[dependencies]
yellowstone-vixen = "0.6.1"
yellowstone-vixen-core = "0.6.1"
yellowstone-vixen-parser = "0.6.1"
yellowstone-vixen-proc-macro = "0.6.1"
yellowstone-vixen-yellowstone-grpc-source = "0.6.1"
borsh = { version = "1", features = ["derive"] }
bs58 = "0.5"
chrono = { version = "0.4", features = ["clock"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
clap = { version = "4", features = ["derive"] }
rustls = { version = "0.23", features = ["ring"] }
toml = "0.8"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

Ten en cuenta que yellowstone debe ser un directo dependencia (no solo transitiva a través de yellowstone) porque la macro «proc» genera código que hace referencia a ella por el nombre del crate.

A continuación se explica la función de las dependencias clave:


  • yellowstone / yellowstone: El entorno de ejecución de Vixen y sus características principales (Parser, Handler, Pipeline)
  • yellowstone: El include_vixen_parser! macro para la generación de código basada en IDL
  • grpc: Conecta el entorno de ejecución de Vixen a unendpointgRPC Solana
  • borsh: Formato de serialización utilizado por Solana (requerido por el analizador generado)
  • bs58: Codificación Base58 para las firmas de las transacciones
  • crono: Formato de las marcas de tiempo en la salida del registro
  • solicitud: Cliente HTTP para obtener símbolos de tokens desde la API de Jupiter
  • aplauso: Análisis de los argumentos de la línea de comandos para el --config bandera
  • susurros: Se requiere un proveedor TLS para la gRPC
  • rastreo / localización de abonados: Registro estructurado con filtrado basado en el entorno

Crear Vixen.toml en el directorio raíz del proyecto. Este es el único archivo de configuración que necesita la aplicación:

Vixen.toml
[source]
endpoint = "YOUR_QN_ENDPOINT:10000"
x-token = "YOUR_X_TOKEN"
timeout = 120
commitment-level = "confirmed"
accept-compression = "zstd"

Puedes encontrar estos valores en el Quicknode engRPC Solana endpoint tuendpointmainnet Solana . El panel de control muestra endpoint tu endpoint en el formato https://your-endpoint-name.solana-mainnet.quiknode.pro/abc123. Añadir :10000 al nombre de host de la endpoint campo, y utiliza el token final (abc123) como tu x-token. Para obtener más información, consulta el gRPC degRPC de Solana.

Generar un analizador a partir del IDL de una orden limitada

En lugar de escribir código de deserialización manual para cada instrucción, se proporciona el IDL del programa en formato Codama y el include_vixen_parser! macro generates a complete type-safe parser at compile time. This section walks through the full flow so you can apply it to any Anchor program.

Descarga el código IDL de la orden limitada de Júpiter v2:

El repositorio Vixen ya incluye un IDL de Codama listo para usar para Jupiter Limit Order v2 en tests/idls/lo_v2.json. Puedes copiarlo directamente en tu idls/ carpeta y pasar directamente a Ejecutar la macro Proc-Macro. Los pasos que se indican a continuación describen el flow completo de obtención y conversión, flow puedas aplicar el mismo procedimiento a cualquier programa de Anchor que aún no disponga de un IDL de Codama.

Utiliza la CLI de Anchor para obtener el IDL en cadena del programa «Jupiter Limit Order v2». Sustituye TU_QN_RPC_URL con tu endpointmainnet Solana Quicknode :

anchor idl fetch j1o2qRpjcyUwEvwtcfhEQefh773ZgjxcVRry7LDqg5X \
--provider.cluster YOUR_QN_RPC_URL \
-o idls/lo_v2_raw.json

El IDL contiene la definición completa de la interfaz del programa: nombres de instrucciones, estructuras de cuentas, tipos de argumentos y la dirección del programa. Esto es lo que utiliza Vixen para generar código Rust tipado.


Un detalle a tener en cuenta con Anchor IDL

Cuando descargaste el IDL utilizando el ancla idl comando, presentaba una pequeña inconsistencia que hace que el conversor de Codama falle. En el inicializar_pedido En esta instrucción, una semilla de PDA hace referencia a un argumento denominado unique_id, pero en este IDL, unique_id en realidad está anidado dentro de un parámetros struct, no un argumento de primer nivel. Codama lo busca en el primer nivel, no lo encuentra y genera un error.

Esto es algo con lo que te puedes encontrar al utilizar Codama con IDL de otros programas, en los que el IDL es técnicamente una salida válida de Anchor, pero la referencia de ruta no coincide con la estructura real de los argumentos. Es posible que tengas que resolver manualmente problemas como estos cuando utilices un IDL que aún no tenga un formato Codama al usar Vixen.

Para solucionar este problema, abre idls/lo_v2_raw.json y busca esta línea (alrededor de la línea n.º 621) en las semillas de las cuentas de la instrucción «initialize_order»:

idls/lo_v2_raw.json
{
"kind": "arg",
"path": "unique_id"
}

Cámbialo por:

idls/lo_v2_raw.json
{
"kind": "arg",
"path": "params.unique_id"
}

Convertir al formato Codama:

Inicializa la carpeta raíz del proyecto como un proyecto de Node.js para que podamos ejecutar comandos de Codama:

npm init -y
npm install -g @codama/cli
npm install @codama/nodes-from-anchor

@codama/nodos-de-anchor Es necesario conocer el formato IDL de Anchor durante la conversión.

Convertir el IDL de Anchor sin procesar al formato Codama:

codama convertir idls/lo_v2_raw.json idls/lo_v2.json

Este paso de conversión único es lo que permite utilizar la generación de código en tiempo de compilación de Vixen para cualquier programa de Anchor.

Ejecutar la macro Proc-Macro

Crear src/parser.rs con lo siguiente:

src/parser.rs
use yellowstone_vixen_proc_macro::include_vixen_parser;

include_vixen_parser!("idls/lo_v2.json");

Esta única llamada a una macro genera, en tiempo de compilación:


  • A orden_límite2 módulo que contiene todos los tipos generados
  • Un texto mecanografiado Instrucciones enumeración con variantes para cada instrucción del IDL (Inicializar pedido, FillOrder, Cancelar pedido, y otros)
  • Estructuras de tipos y argumentos definidas para cada instrucción
  • Un Analizador de instrucciones que implementa el rasgo de analizador de Vixen
  • A Prefiltro de transacciones configurado con tres filtros: dirección de programa (solo Jupiter LO v2), falló: Algunos (falso) (novedad en la versión 0.6.1) para excluir las transacciones fallidas, y voto: Algunos (falso) para excluir las transacciones de voto

Implementar el monitor

Vixen v0.6.1 utiliza el rastreo biblioteca para generar registros estructurados y filtrables, que sustituye a la antigua log/env_logger patrón utilizado en versiones anteriores de Vixen.

El abonado que realiza el rastreo respeta las RUST_LOG variable de entorno, lo que te permite controlar el nivel de detalle en tiempo de ejecución sin necesidad de recompilar:


  • RUST_LOG=info: Muestra la salida del controlador y los eventos del ciclo de vida de Vixen
  • RUST_LOG=debug: Añade los detalles gRPC y la actividad de suscripción a flujos
  • RUST_LOG=warn: Muestra únicamente advertencias y errores

La inicialización se lleva a cabo en main() antes de que se ejecute cualquier otro código, lo que garantiza que tanto los componentes internos de Vixen como tu código de gestión se beneficien del registro estructurado.

Implementar el gestor de órdenes limitadas

Crear src/handlers.rs. El controlador recibe las instrucciones analizadas del analizador generado y registra los tres tipos de eventos relacionados con las órdenes: órdenes introducidas, órdenes ejecutadas y cancelaciones.

El controlador incluye funciones auxiliares que obtienen símbolos de tokens legibles para el usuario a partir de la API de tokens de Jupiter y los almacenan en caché para evitar búsquedas repetidas. Además, extrae la precisión decimal de los metadatos del saldo del token de la transacción para mostrar los importes en un formato legible para el usuario (por ejemplo, 1,5 USDC en lugar de 1500000).

src/handlers.rs
use std::{collections::HashMap, sync::Mutex};

use yellowstone_vixen::vixen_core::instruction::InstructionUpdate;

use crate::parser::limit_order2;

fn fmt_amount(raw: u64, decimals: u32) -> String {
if decimals == 0 {
return raw.to_string();
}
let s = format!("{:.prec$}", raw as f64 / 10f64.powi(decimals as i32), prec = decimals as usize);
s.trim_end_matches('0').trim_end_matches('.').to_string()
}

fn fmt_token(amount: &str, symbol: &str, mint: &str) -> String {
if symbol == mint {
format!("{amount} {mint}")
} else {
format!("{amount} {symbol} ({mint})")
}
}

async fn fetch_symbol(mint: &str) -> String {
#[derive(serde::Deserialize)]
struct Token {
id: String,
symbol: String,
}

let url = format!("https://api.jup.ag/tokens/v2/search?query={mint}");
let fallback = mint.to_string();

let Ok(resp) = reqwest::get(&url).await else {
return fallback;
};
let Ok(tokens) = resp.json::<Vec<Token>>().await else {
return fallback;
};
fichas
.into_iter()
.find(|t| t.id == mint)
.map(|t| t.symbol)
.unwrap_or(fallback)
}

#[derive(Debug, Default)]
pub struct LimitOrderHandler {
symbol_cache: Mutex<HashMap<String, String>>,
}

impl LimitOrderHandler {
async fn get_symbol(&self, mint: &str) -> String {
{
let cache = self.symbol_cache.lock().unwrap();
if let Some(sym) = cache.get(mint) {
return sym.clone();
}
}
let symbol = fetch_symbol(mint).await;
self.symbol_cache
.lock()
.unwrap()
.insert(mint.to_string(), symbol.clone());
symbol
}
}

impl yellowstone_vixen::Handler<limit_order2::Instructions, InstructionUpdate>
for LimitOrderHandler
{
async fn handle(
&self,
value: &limit_order2::Instructions,
raw: &InstructionUpdate,
) -> yellowstone_vixen::HandlerResult<()> {
use limit_order2::instruction::Instruction;

let sig = bs58::encode(&raw.shared.signature).into_string();
let ts = chrono::Utc::now().format("%Y-%m-%dT%H:%M:%S%.6fZ");

let pre = &raw.shared.pre_token_balances;
let post = &raw.shared.post_token_balances;
let find_decimals = |mint: &str| {
pre.iter()
.chain(post.iter())
.find(|b| b.mint == mint)
.and_then(|b| b.ui_token_amount.as_ref())
.map(|u| u.decimals)
};

match &value.instruction {
Instruction::InitializeOrder { accounts, args } => {
let input_mint_str = accounts.input_mint.to_string();
let output_mint_str = accounts.output_mint.to_string();

let input_symbol = self.get_symbol(&input_mint_str).await;
let output_symbol = self.get_symbol(&output_mint_str).await;

let making_amount = find_decimals(&input_mint_str)
.map(|d| fmt_amount(args.making_amount, d))
.unwrap_or_else(|| args.making_amount.to_string());
let taking_amount = find_decimals(&output_mint_str)
.map(|d| fmt_amount(args.taking_amount, d))
.unwrap_or_else(|| args.taking_amount.to_string());

let expired_at = args.expired_at
.and_then(|t| chrono::DateTime::from_timestamp(t, 0))
.map(|dt| dt.format("%Y-%m-%dT%H:%M:%SZ").to_string())
.unwrap_or_else(|| "None".to_string());

let making = fmt_token(&making_amount, &input_symbol, &input_mint_str);
let taking = fmt_token(&taking_amount, &output_symbol, &output_mint_str);
tracing::info!(
tx = %sig,
maker = %accounts.maker,
making_amount = %making,
taking_amount = %taking,
expired_at = %expired_at,
"New limit order placed - {ts}",
);
},
Instruction::FillOrder { accounts, args } => {
let input_mint_str = accounts.input_mint.to_string();
let output_mint_str = accounts.output_mint.to_string();

let input_symbol = self.get_symbol(&input_mint_str).await;

let input_amount = find_decimals(&input_mint_str)
.map(|d| fmt_amount(args.input_amount, d))
.unwrap_or_else(|| args.input_amount.to_string());

let input = fmt_token(&input_amount, &input_symbol, &input_mint_str);
tracing::info!(
tx = %sig,
taker = %accounts.taker,
output_mint = %output_mint_str,
input_amount = %input,
"Limit order filled - {ts}",
);
},
Instruction::CancelOrder { accounts, .. } => {
tracing::info!(
tx = %sig,
maker = %accounts.maker,
order = %accounts.order,
"Limit order cancelled - {ts}",
);
},
_ => {},
}

Ok(())
}
}

El controlador implementa la interfaz de Vixen Entrenador característica del archivo generado limit_order2::Instrucciones tipo. Realiza una coincidencia de patrones con tres variantes de instrucción:


  • Inicializar pedido: Registra la dirección del creador, los tokens de entrada y salida con importes legibles para el usuario y la marca de tiempo de caducidad del pedido
  • FillOrder: Registra la dirección del comprador, la casa de emisión y el importe de la entrada que se está completando
  • Cancelar pedido: Registra la dirección del fabricante y la cuenta del pedido que se va a cancelar
  • _ (comodín): Ignora silenciosamente el resto de instrucciones (actualizaciones de comisiones, operaciones administrativas, etc.)

El controlador también incluye funciones de formato fáciles de usar, como la conversión a decimales de los importes de los tokens y la búsqueda de símbolos bursátiles a través de la API de tokens de Jupiter. En el caso de una aplicación de rendimiento ultraalto, estas llamadas a la API salientes podrían afectar al rendimiento.

Compilar el entorno de ejecución de Vixen

Sustituye el texto generado src/main.rs con el siguiente código. Esto integra todos los elementos: la inicialización del seguimiento, el proveedor de cifrado TLS, la carga de la configuración y el entorno de ejecución de Vixen con la cadena de instrucciones.

src/main.rs
use std::path::PathBuf;

use clap::Parser as _;
use yellowstone_vixen::Pipeline;
use yellowstone_vixen_yellowstone_grpc_source::YellowstoneGrpcSource;

mod handlers;
mod parser;

use handlers::LimitOrderHandler;
use parser::limit_order2;

#[derive(clap::Parser)]
#[command(version, author, about = "Monitor Jupiter Limit Order v2 events via Yellowstone Vixen")]
struct Opts {
#[arg(long, short)]
config: PathBuf,
}

fn main() {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.init();

rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");

let Opts { config } = Opts::parse();
let config = std::fs::read_to_string(config).expect("Error reading config file");
let config = toml::from_str(&config).expect("Error parsing config");

yellowstone_vixen::Runtime::<YellowstoneGrpcSource>::builder()
.instruction(Pipeline::new(limit_order2::InstructionParser, [LimitOrderHandler::default()]))
.build(config)
.run();
}

La configuración del tiempo de ejecución consta de cuatro pasos:


  1. Trazado: Inicializa localización de abonados con EnvFilter así que el RUST_LOG La variable de entorno controla el nivel de detalle de los registros en tiempo de ejecución sin necesidad de recompilar
  2. TLS: Instala el susurros proveedor de cifrado, necesario para la conexión gRPC con Quicknode
  3. Configuración: Lee y analiza Vixen.toml para la configuración endpoint, el token y el flujo
  4. Duración: Construye una Vixen Duración con una sola instrucción Conducto que conecta el generado Analizador de instrucciones a la LimitOrderHandler, y a continuación comienza la retransmisión

El Pipeline::new llama al analizador sintáctico del controlador. El código generado Analizador de instrucciones se encarga del filtrado de suscripciones (dirección del programa, transacciones fallidas, transacciones de voto) y de la deserialización. Tu controlador solo recibe datos de instrucciones analizados y tipificados para el programa Jupiter Limit Order v2.

Compilar y ejecutar la aplicación

Compilar el proyecto:

carga compilación

Ejecútalo con el parámetro de configuración. Establece RUST_LOG=info Para ver la salida del controlador y los eventos del ciclo de vida de Vixen:

RUST_LOG=info cargo ejecutar -- --config ./Vixen.toml

Resultado esperado

Una vez conectado, verás las líneas del registro del ciclo de vida de Vixen, seguidas de los eventos de órdenes limitadas a medida que se produzcan en mainnet. A continuación se muestra un ejemplo de salida para cada uno de los tres tipos de eventos:

2026-04-08T14:32:01.123456Z INFO jupiter_lo_vixen: New limit order placed - 2026-04-08T14:32:01.123456Z tx=5UjQ...abc maker=7xKm...def making_amount="100 USDC (EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v)" taking_amount="1.5 SOL (So11111111111111111111111111111111111111112)" expired_at=2026-04-15T00:00:00Z
2026-04-08T14:33:15.654321Z INFO jupiter_lo_vixen: Limit order filled - 2026-04-08T14:33:15.654321Z tx=3Kpx...ghi taker=9mRv...jkl output_mint=So11111111111111111111111111111111111111112 input_amount="100 USDC (EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v)"
2026-04-08T14:35:42.789012Z INFO jupiter_lo_vixen: Limit order cancelled - 2026-04-08T14:35:42.789012Z tx=8FnY...mno maker=7xKm...def order=4vTq...pqr

Cada entrada incluye una marca de tiempo según la norma ISO 8601, la firma de la transacción y las cuentas y cantidades correspondientes al tipo de evento. Las cantidades de tokens se muestran en un formato legible para el usuario, con los símbolos bursátiles obtenidos a partir de la API de tokens de Jupiter.

Amplía tu pantalla

La arquitectura que has creado es flexible. A continuación te indicamos algunas formas de ampliarla:


  • Supervisar otro programa de Jupiter: sustituye el IDL por el de Jupiter DCA, Perps o cualquier otro programa de Anchor. La estructura del proceso sigue siendo la misma; solo cambian el archivo IDL y la lógica del controlador.
  • Ve varios programas a la vez: Vixen v0.6.1 admite suscripciones a varios programas. Añade una segunda cadena de instrucciones para supervisar tanto Limit Order v1 como v2 en el mismo entorno de ejecución.
  • Añadir supervisión de cuentas: además de la supervisión de órdenes, añade un flujo de trabajo de cuentas para realizar un seguimiento de los cambios en el estado de cuentas específicas con órdenes limitadas.
  • Almacenar eventos en una base de datos: Amplía el controlador para escribir los eventos analizados en PostgreSQL, ClickHouse u otro almacén de datos con fines de análisis histórico.

Preguntas frecuentes

¿Qué es Solana gRPC cómo permite la monitorización en tiempo real en Solana?

Solana gRPC una gRPC de alto rendimiento para la transmisión en tiempo real de datos Solana , incluidas las transacciones y las actualizaciones de cuentas. Permite a las aplicaciones escritas en Rust suscribirse a programas específicos, como Jupiter, para recibir flujos de órdenes limitadas con baja latencia sin necesidad de realizar consultas periódicas.

¿Qué es Vixen en el contexto del Solana ?

Vixen es un marco de trabajo de código abierto escrito en Rust para crear flujos de datos tipados basados engRPC Solana . Se encarga automáticamente de gRPC , el filtrado de flujos y la deserialización de instrucciones, por lo que la lógica de negocio se escribe sobre estructuras tipadas de Rust en lugar de bytes sin procesar. Sus abstracciones principales son un «Parser», que decodifica las instrucciones; un «Handler», que las procesa; y un «Pipeline», que conecta ambos dentro de un entorno de ejecución gestionado.

¿Puedo utilizar Vixen para supervisar otros programas además de Jupiter Limit Orders?

Sí. La macro «proc-macro» de Vixen funciona con cualquier programa de Anchor que publique un IDL. Obtén el IDL con la CLI de Anchor, conviértelo al formato Codama y pásalo a «include_vixen_parser!». El analizador y la estructura del proceso generados siguen siendo los mismos. Solo cambian el archivo IDL y tu lógica de gestión.

¿Por qué el TransactionPrefilter excluye las transacciones fallidas?

La versión 0.6.1 de Vixen introdujo un campo «failed» en su TransactionPrefilter. Al configurarlo para excluir las transacciones fallidas, se garantiza que solo las transacciones confirmadas y ejecutadas con éxito lleguen a tu controlador. En el caso de un monitor de órdenes limitadas, esto evita que se registren eventos como intentos de ejecución fallidos que nunca se han ejecutado realmente en la cadena de bloques.

¿Necesito una Quicknode para utilizar Vixen?

Vixen es, en sí mismo, un marco de código abierto. Sin embargo, requiere unendpoint gRPC Solana endpoint transmitir datos. Quicknode gRPC Solana gRPC incluido en los planes Scale y Business, o disponible a través del complemento en los planes Build y Accelerate) que puedes activar en cualquierendpoint Solana Quicknode endpoint el panel de control.

¿Qué es Codama y por qué es necesario un paso de conversión?

Codama es un formato IDL que proporciona información de tipos más detallada que el formato IDL nativo de Anchor. La macro de procedimiento de Vixen requiere el formato Codama para generar estructuras y enumeraciones con tipos precisos. El comando «codama convert» sirve de puente entre ambos formatos. Este paso de conversión, que solo hay que realizar una vez, es lo que permite la generación de código en tiempo de compilación de Vixen para cualquier programa de Anchor.

Conclusión

Has creado un monitor de órdenes limitadas de Jupiter en tiempo real que streams transacciones streams a través degRPC Solana , las analiza y las convierte en estructuras tipadas de Rust utilizando el generador de código IDL de Vixen, y registra la introducción, ejecución y cancelación de órdenes con una salida de tokens legible para los humanos. A partir de aquí, puedes aplicar el mismo patrón a cualquier programa de Anchor sustituyendo su IDL, lo que convierte a Vixen en una base versátil para crear flujos Solana .

Recursos


¿Tienes alguna duda? Únete al servidor Quicknode o sigue a quicknode para estar al día.