Meteora Vault decoder

Decode Meteora Vault instructions, accounts and events in Rust with carbon-meteora-vault-decoder 2.0.0. Program ID 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi.

On this page

carbon-meteora-vault-decoder decodes the instructions, accounts and events of the Meteora Vault program (24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi): 14 instructions, 2 account types, 8 events. It is generated with Codama from the program's IDL; see decoders for how decoders plug into a pipeline.

Cratecarbon-meteora-vault-decoder 2.0.0
Installcargo add carbon-meteora-vault-decoder@2.0.0
Program ID24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi (carbon_meteora_vault_decoder::PROGRAM_ID)
CategoryLending
Decodercarbon_meteora_vault_decoder::MeteoraVaultDecoder
Instruction enuminstructions::MeteoraVaultInstruction
Account enumaccounts::MeteoraVaultAccount
Event enuminstructions::CpiEvent
Featuresserde, postgres, graphql (none enabled by default)
API docsdocs.rs/carbon-meteora-vault-decoder/2.0.0
Sourcedecoders/meteora-vault-decoder

Other lending decoders: Jupiter Lend, Kamino Lending, Kamino Vault, marginfi v2, Sharky. To decode several in one pipeline, see lending decoders.

The serde feature derives Serialize/Deserialize on every type, postgres adds tables and processors for Postgres, and graphql adds a schema for the GraphQL server.

Usage#

This program crawls recent Meteora Vault transactions from the public RPC and prints every decoded Deposit instruction. Add the dependencies:

Terminal
cargo add carbon-core@2.0.0 carbon-meteora-vault-decoder@2.0.0 carbon-rpc-transaction-crawler-datasource@2.0.0 carbon-log-metrics@2.0.0 env_logger tokio --features tokio/full
src/main.rs
use {
    carbon_core::{
        error::CarbonResult, instruction::InstructionProcessorInputType, pipeline::Pipeline,
        processor::Processor,
    },
    carbon_log_metrics::LogMetrics,
    carbon_meteora_vault_decoder::{
        instructions::MeteoraVaultInstruction, MeteoraVaultDecoder, PROGRAM_ID,
    },
    carbon_rpc_transaction_crawler_datasource::{ConnectionConfig, Filters, RpcTransactionCrawler},
    std::sync::Arc,
};

#[tokio::main]
async fn main() -> CarbonResult<()> {
    env_logger::init();

    // Fetches the program's recent transactions over JSON-RPC, newest first.
    let datasource = RpcTransactionCrawler::new(
        "https://api.mainnet-beta.solana.com".to_string(),
        PROGRAM_ID,
        ConnectionConfig::default(),
        Filters::new(None, None, None),
        None,
    );

    Pipeline::builder()
        .datasource(datasource)
        .metrics(Arc::new(LogMetrics::new()))
        .instruction(MeteoraVaultDecoder, InstructionLogger)
        .build()?
        .run()
        .await
}

struct InstructionLogger;

impl Processor<InstructionProcessorInputType<'_, MeteoraVaultInstruction>> for InstructionLogger {
    async fn process(
        &mut self,
        input: &InstructionProcessorInputType<'_, MeteoraVaultInstruction>,
    ) -> CarbonResult<()> {
        let signature = input.metadata.transaction_metadata.signature;
        if let MeteoraVaultInstruction::Deposit { data, accounts, .. } = input.decoded_instruction {
            println!("deposit {signature}: {data:?} vault={}", accounts.vault);
        }
        Ok(())
    }
}
Terminal
RUST_LOG=info cargo run

Each Deposit instruction prints one line with the transaction signature and the decoded Deposit data. The public endpoint rate-limits requests, so the first lines can take a while; use your own RPC URL for anything beyond a test. See stream with RPC for the crawler options.

Events published with Anchor's emit_cpi! arrive as the CpiEvent instruction. Match them with MeteoraVaultInstruction::CpiEvent { data: CpiEvent::AddLiquidity(event), .. } (import instructions::CpiEvent); see Events. If CpiEvent never arrives, the program logs its events with emit! instead: decode them with decode_log_events.

Decode accounts#

The transaction crawler emits transactions only. To decode accounts, use a datasource that emits account updates. This program subscribes to the program's accounts with programSubscribe on the public WebSocket endpoint and prints every decoded Vault account as it changes. Add the datasource and the Solana RPC types it takes:

Terminal
cargo add carbon-rpc-program-subscribe-datasource@2.0.0 solana-client@4.2.2
src/main.rs
use {
    carbon_core::{
        account::AccountProcessorInputType, error::CarbonResult, pipeline::Pipeline,
        processor::Processor,
    },
    carbon_log_metrics::LogMetrics,
    carbon_meteora_vault_decoder::{accounts::MeteoraVaultAccount, MeteoraVaultDecoder, PROGRAM_ID},
    carbon_rpc_program_subscribe_datasource::{Filters, RpcProgramSubscribe},
    solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig, UiAccountEncoding},
    std::sync::Arc,
};

#[tokio::main]
async fn main() -> CarbonResult<()> {
    env_logger::init();

    // Streams every change to an account owned by the program (programSubscribe).
    let config = RpcProgramAccountsConfig {
        account_config: RpcAccountInfoConfig {
            encoding: Some(UiAccountEncoding::Base64),
            ..Default::default()
        },
        ..Default::default()
    };
    let datasource = RpcProgramSubscribe::new(
        "wss://api.mainnet-beta.solana.com".to_string(),
        Filters::new(PROGRAM_ID, Some(config)),
    );

    Pipeline::builder()
        .datasource(datasource)
        .metrics(Arc::new(LogMetrics::new()))
        .account(MeteoraVaultDecoder, AccountLogger)
        .build()?
        .run()
        .await
}

struct AccountLogger;

impl Processor<AccountProcessorInputType<'_, MeteoraVaultAccount>> for AccountLogger {
    async fn process(
        &mut self,
        input: &AccountProcessorInputType<'_, MeteoraVaultAccount>,
    ) -> CarbonResult<()> {
        if let MeteoraVaultAccount::Vault(vault) = &input.decoded_account.data {
            println!("vault {}: {vault:?}", input.metadata.pubkey);
        }
        Ok(())
    }
}
Terminal
RUST_LOG=info cargo run

Each update to a Vault account prints its address and decoded fields; the program runs until you stop it. Cargo resolves solana-client to 4.2.2, the exact version the datasource pins, so both use the same RpcProgramAccountsConfig type. To load every existing account once instead of streaming changes, see load account state.

Instructions#

Variants of MeteoraVaultInstruction. Each is MeteoraVaultInstruction::<Variant> { program_id, data, accounts }, where data and accounts are the types listed under the variant, exported from carbon_meteora_vault_decoder::instructions. Discriminators are the leading bytes of the instruction data, in hex.

How an instruction decodes. The decoder returns a variant only when all of these hold; otherwise the instruction is skipped and no processor is called:

  1. The instruction's program ID is 24Uqj9JCLxUeoC3hGfh5W3s9FM9uCHDS2SG3LYwBpyTi.
  2. The data starts with the variant's discriminator, and the rest deserializes into its data type.
  3. The instruction has at least as many accounts as the variant requires (the "Required accounts" count under each variant).

Accounts. They are matched by position, in the order listed. An account marked optional is None only when the instruction ends before it; Anchor programs pass the program ID as a placeholder for an omitted optional account, so check for Some(PROGRAM_ID) too. Accounts after the listed ones are in accounts.remaining as AccountMetas. The decoder doesn't record whether an account signed or was writable: read that from input.raw_instruction.accounts[i].is_signer and .is_writable, which follow the same order. It doesn't check signer, writable, owner or PDA constraints either; the program enforced those when the transaction executed, so a decoded instruction from a successful transaction already satisfied them.

AddStrategy#

From the program's IDL:

add a strategy

Discriminator 407b7fe3c0eac614 · data AddStrategy · accounts AddStrategyInstructionAccounts.

No data fields.

Required accounts: 3; extras go to remaining.

Fields of AddStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2adminPubkey
3…remainingVec<AccountMeta>

CollectDust#

From the program's IDL:

collect token, that someone send wrongly also help in case Mango reimbursement

Discriminator f6951552a04afef0 · data CollectDust · accounts CollectDustInstructionAccounts.

No data fields.

Required accounts: 5; extras go to remaining.

Fields of CollectDustInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1token_vaultPubkey
2token_adminPubkey
3adminPubkey
4token_programPubkey
5…remainingVec<AccountMeta>

Deposit#

From the program's IDL:

user deposit liquidity to vault

Discriminator f223c68952e1f2b6 · data Deposit · accounts DepositInstructionAccounts.

FieldType
token_amountu64
minimum_lp_token_amountu64

Required accounts: 7; extras go to remaining.

Fields of DepositInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1token_vaultPubkey
2lp_mintPubkey
3user_tokenPubkey
4user_lpPubkey
5userPubkey
6token_programPubkey
7…remainingVec<AccountMeta>

DepositStrategy#

From the program's IDL:

deposit liquidity to a strategy

Discriminator f65239e283defdf9 · data DepositStrategy · accounts DepositStrategyInstructionAccounts.

FieldType
amountu64

Required accounts: 10; extras go to remaining.

Fields of DepositStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2token_vaultPubkey
3fee_vaultPubkey
4lp_mintPubkey
5strategy_programPubkey
6collateral_vaultPubkey
7reservePubkey
8token_programPubkey
9operatorPubkey
10…remainingVec<AccountMeta>

EnableVault#

From the program's IDL:

enable vault

Discriminator 9152f19c1a9ae9d3 · data EnableVault · accounts EnableVaultInstructionAccounts.

FieldType
enabledu8

Required accounts: 2; extras go to remaining.

Fields of EnableVaultInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1adminPubkey
2…remainingVec<AccountMeta>

Initialize#

From the program's IDL:

initialize new vault

Discriminator afaf6d1f0d989bed · data Initialize · accounts InitializeInstructionAccounts.

No data fields.

Required accounts: 8; extras go to remaining.

Fields of InitializeInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1payerPubkey
2token_vaultPubkey
3token_mintPubkey
4lp_mintPubkey
5rentPubkey
6token_programPubkey
7system_programPubkey
8…remainingVec<AccountMeta>

InitializeStrategy#

From the program's IDL:

Initialize a strategy and add strategy to vault.strategies index

Discriminator d0779091b23969fc · data InitializeStrategy · accounts InitializeStrategyInstructionAccounts.

FieldType
bumpsStrategyBumps
strategy_typeStrategyType

Required accounts: 10; extras go to remaining.

Fields of InitializeStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategy_programPubkey
2strategyPubkey
3reservePubkey
4collateral_vaultPubkey
5collateral_mintPubkey
6adminPubkey
7system_programPubkey
8rentPubkey
9token_programPubkey
10…remainingVec<AccountMeta>

RemoveStrategy#

From the program's IDL:

remove a strategy

Discriminator b9ee215b86d2611a · data RemoveStrategy · accounts RemoveStrategyInstructionAccounts.

No data fields.

Required accounts: 10; extras go to remaining.

Fields of RemoveStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2strategy_programPubkey
3collateral_vaultPubkey
4reservePubkey
5token_vaultPubkey
6fee_vaultPubkey
7lp_mintPubkey
8token_programPubkey
9adminPubkey
10…remainingVec<AccountMeta>

RemoveStrategy2#

From the program's IDL:

remove a strategy by advance payment

Discriminator 8a68d0947e23c30e · data RemoveStrategy2 · accounts RemoveStrategy2InstructionAccounts.

FieldType
max_admin_pay_amountu64

Required accounts: 12; extras go to remaining.

Fields of RemoveStrategy2InstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2strategy_programPubkey
3collateral_vaultPubkey
4reservePubkey
5token_vaultPubkey
6token_admin_advance_paymentPubkey
7token_vault_advance_paymentPubkey
8fee_vaultPubkey
9lp_mintPubkey
10token_programPubkey
11adminPubkey
12…remainingVec<AccountMeta>

SetOperator#

From the program's IDL:

set new operator

Discriminator ee9965a9f3832401 · data SetOperator · accounts SetOperatorInstructionAccounts.

No data fields.

Required accounts: 3; extras go to remaining.

Fields of SetOperatorInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1operatorPubkey
2adminPubkey
3…remainingVec<AccountMeta>

Withdraw#

From the program's IDL:

user withdraw liquidity from vault

Discriminator b712469c946da122 · data Withdraw · accounts WithdrawInstructionAccounts.

FieldType
unmint_amountu64
min_out_amountu64

Required accounts: 7; extras go to remaining.

Fields of WithdrawInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1token_vaultPubkey
2lp_mintPubkey
3user_tokenPubkey
4user_lpPubkey
5userPubkey
6token_programPubkey
7…remainingVec<AccountMeta>

Withdraw2#

From the program's IDL:

Withdraw v2. Withdraw from token vault if no remaining accounts are available. Else, it will attempt to withdraw from strategy and token vault.
This method just proxy between 2 methods. Protocol integration should be using withdraw instead of this function.

Discriminator 50066f49aed34284 · data Withdraw2 · accounts Withdraw2InstructionAccounts.

FieldType
unmint_amountu64
min_out_amountu64

Required accounts: 7; extras go to remaining.

Fields of Withdraw2InstructionAccounts, in account order:

#FieldType
0vaultPubkey
1token_vaultPubkey
2lp_mintPubkey
3user_tokenPubkey
4user_lpPubkey
5userPubkey
6token_programPubkey
7…remainingVec<AccountMeta>

WithdrawDirectlyFromStrategy#

From the program's IDL:

user withdraw liquidity from vault, if vault reserve doesn't have enough liquidity, it will withdraw from the strategy firstly

Discriminator c98d922ead74c616 · data WithdrawDirectlyFromStrategy · accounts WithdrawDirectlyFromStrategyInstructionAccounts.

FieldType
unmint_amountu64
min_out_amountu64

Required accounts: 12; extras go to remaining.

Fields of WithdrawDirectlyFromStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2reservePubkey
3strategy_programPubkey
4collateral_vaultPubkey
5token_vaultPubkey
6lp_mintPubkey
7fee_vaultPubkey
8user_tokenPubkey
9user_lpPubkey
10userPubkey
11token_programPubkey
12…remainingVec<AccountMeta>

WithdrawStrategy#

From the program's IDL:

withdraw liquidity from a strategy

Discriminator 1f2da205c1d986bc · data WithdrawStrategy · accounts WithdrawStrategyInstructionAccounts.

FieldType
amountu64

Required accounts: 10; extras go to remaining.

Fields of WithdrawStrategyInstructionAccounts, in account order:

#FieldType
0vaultPubkey
1strategyPubkey
2token_vaultPubkey
3fee_vaultPubkey
4lp_mintPubkey
5strategy_programPubkey
6collateral_vaultPubkey
7reservePubkey
8token_programPubkey
9operatorPubkey
10…remainingVec<AccountMeta>

CpiEvent#

Anchor self-CPI that carries one of the program's events. data is the CpiEvent enum.

Discriminator e445a52e51cb9a1d · data CpiEvent · accounts CpiEventInstructionAccounts.

Required accounts: 2; extras go to remaining.

Fields of CpiEventInstructionAccounts, in account order:

#FieldType
0programPubkey
1event_authorityPubkey
2…remainingVec<AccountMeta>

Accounts#

Variants of MeteoraVaultAccount. Each wraps a boxed struct from carbon_meteora_vault_decoder::accounts::<module>. decode_account only considers accounts owned by PROGRAM_ID and returns the first variant that matches.

Strategy#

From the program's IDL:

Strategy struct

Discriminator ae6e2777526aa966 · accounts::strategy::Strategy.

FieldTypeDescription
reservePubkeyLending pool address, that the strategy will deposit/withdraw balance
collateral_vaultPubkeyThe token account, that holds the collateral token
strategy_typeStrategyTypeSpecify type of strategy
current_liquidityu64The liquidity in strategy at the time vault deposit/withdraw from a lending protocol
bumps[u8; 10]Hold some bumps, in case the strategy needs to use other seeds to sign a CPI call.
vaultPubkeyVault address, that the strategy belongs
is_disableu8If we remove strategy by remove_strategy2 endpoint, this account will be never added again

Vault#

From the program's IDL:

Vault struct

Discriminator d308e82b02987577 · accounts::vault::Vault.

FieldTypeDescription
enabledu8The flag, if admin set enable = false, then the user can only withdraw and cannot deposit in the vault.
bumpsVaultBumpsVault nonce, to create vault seeds
total_amountu64The total liquidity of the vault, including remaining tokens in token_vault and the liquidity in all strategies.
token_vaultPubkeyToken account, hold liquidity in vault reserve
fee_vaultPubkeyHold lp token of vault, each time rebalance crank is called, vault calculate performance fee and mint corresponding lp token amount to fee_vault. fee_vault is owned by treasury address
token_mintPubkeyToken mint that vault supports
lp_mintPubkeyLp mint of vault
strategies[Pubkey; 30]The list of strategy addresses that vault supports, vault can support up to MAX_STRATEGY strategies at the same time.
basePubkeyThe base address to create vault seeds
adminPubkeyAdmin of vault
operatorPubkeyPerson who can send the crank. Operator can only send liquidity to strategies that admin defined, and claim reward to account of treasury address
locked_profit_trackerLockedProfitTrackerStores information for locked profit.

Events#

Variants of instructions::CpiEvent, decoded from the CpiEvent instruction. Each wraps a struct from carbon_meteora_vault_decoder::events::<module>. The discriminator is the 8-byte event discriminator that follows the e445a52e51cb9a1d CPI-event tag.

AddLiquidity#

Discriminator 1f5e7d5ae3343dba · events::add_liquidity::AddLiquidityEvent.

FieldType
lp_mint_amountu64
token_amountu64

RemoveLiquidity#

Discriminator 74f461e8671f983a · events::remove_liquidity::RemoveLiquidityEvent.

FieldType
lp_unmint_amountu64
token_amountu64

StrategyDeposit#

Discriminator cd355bef2288492f · events::strategy_deposit::StrategyDepositEvent.

FieldType
strategy_typeStrategyType
token_amountu64

StrategyWithdraw#

Discriminator 784cd05fddd2e5bd · events::strategy_withdraw::StrategyWithdrawEvent.

FieldType
strategy_typeStrategyType
collateral_amountu64
estimated_token_amountu64

ClaimReward#

Discriminator 947486cc16ab555f · events::claim_reward::ClaimRewardEvent.

FieldType
strategy_typeStrategyType
token_amountu64
mint_accountPubkey

PerformanceFee#

Discriminator 1c46e7df516defa7 · events::performance_fee::PerformanceFeeEvent.

FieldType
lp_mint_moreu64

ReportLoss#

Discriminator 9a249ec420a37b7e · events::report_loss::ReportLossEvent.

FieldType
strategyPubkey
lossu64

TotalAmount#

Discriminator 5cc87a91d3cb31cd · events::total_amount::TotalAmountEvent.

FieldType
total_amountu64

Types#

Types used by the instructions, accounts and events above, exported from carbon_meteora_vault_decoder::types.

AddLiquidity#

Struct types::AddLiquidity. Same fields as the AddLiquidity event.

ClaimReward#

Struct types::ClaimReward. Same fields as the ClaimReward event.

LockedProfitTracker#

From the program's IDL:

LockedProfitTracker struct

Struct types::LockedProfitTracker.

FieldTypeDescription
last_updated_locked_profitu64The total locked profit from the last report
last_reportu64The last timestamp (in seconds) rebalancing
locked_profit_degradationu64Rate per second of degradation

PerformanceFee#

Struct types::PerformanceFee. Same fields as the PerformanceFee event.

RemoveLiquidity#

Struct types::RemoveLiquidity. Same fields as the RemoveLiquidity event.

ReportLoss#

Struct types::ReportLoss. Same fields as the ReportLoss event.

StrategyBumps#

From the program's IDL:

Strategy bumps struct

Struct types::StrategyBumps.

FieldTypeDescription
strategy_indexu8strategy_index
other_bumps[u8; 10]Bumps of PDAs for the integrated protocol.

StrategyDeposit#

Struct types::StrategyDeposit. Same fields as the StrategyDeposit event.

StrategyType#

From the program's IDL:

StrategyType struct

Enum types::StrategyType.

Variant
PortFinanceWithoutLM
PortFinanceWithLM
SolendWithoutLM
Mango
SolendWithLM
ApricotWithoutLM
Francium
Tulip
Vault
Drift
Frakt
Marginfi

StrategyWithdraw#

Struct types::StrategyWithdraw. Same fields as the StrategyWithdraw event.

TotalAmount#

Struct types::TotalAmount. Same fields as the TotalAmount event.

VaultBumps#

From the program's IDL:

Vault bumps struct

Struct types::VaultBumps.

FieldTypeDescription
vault_bumpu8vault_bump
token_vault_bumpu8token_vault_bump

Generated from the crate’s source at Carbon v2.0.0, so it always matches the published code. Spotted a problem? Report it; edits to this page itself are overwritten on the next release.

Your endpoints

Code samples use these instead of the placeholders, so you can copy and run them as they are. They’re stored only in this browser and never sent anywhere.