1 unstable release
new 0.1.1 | Dec 28, 2024 |
---|
#120 in Magic Beans
81 downloads per month
54KB
1K
SLoC
Atlas IDL Schema
This repo contains a library to transform JSON IDL files for Solana programs into normal Rust objects.
How It Works
The Solana Program IDL pipeline is extremely convoluted. One might even argue that it creates a programming anti-pattern. However, given the prevalence of IDLs for SVM programs, developers should adapt to the situation and develop tooling to make it easier to work with what is available
flowchart TD
A[SVM Program] -->|*Generates via* IDL Parser| B[IDL JSON File]
B --> |*Feeds into*| C[Reverse IDL Parser]
E[Account Data] -.-> |*Queries with* Raw Account Data| D
G[Instruction Data] -.-> |*Queries with* Raw Instruction Data| D
C -->|*Generates via* Schema Parser| D[Schema Nodes] -.-> |*Generates via* Value Parser| F[Value Nodes] -.-> |*Derives*| H[Formatted JSON Data]
This library can convert a JSON IDL string into an intermediate Rust SchemaNode
type. The SchemaNode
is a recursively defined type that takes in an opaque byte object as input and decodes it into a ValueNode
(another recursively defined type). Serializing the ValueNode
will yield the parsed byte object as human-readable JSON.
Example
Here's an example of how to read a Drift V2 State account from Solana Mainnet given the Drift IDL file.
use atlas_idl_schema::parse_idl;
use solana_client::rpc_client::RpcClient;
use std::str::FromStr;
fn main() -> anyhow::Result<()> {
let drift_idl = parse_idl::parse_idl_file("tests/idls/drift.json")
.map_err(|e| anyhow::anyhow!("Failed to parse IDL file: {}", e))?;
let client = RpcClient::new("https://api.mainnet-beta.solana.com".to_string());
// State
let account_data = client.get_account_data(
&solana_sdk::pubkey::Pubkey::from_str("5zpq7DvB6UdFFvpmBPspGPNfUGoBRRCE2HHg5u3gxcsN")
.unwrap(),
)?;
let parsed_account = drift_idl.get_parsed_account(account_data, true)?;
println!("{}\n", serde_json::to_string(&parsed_account).unwrap());
}
Output:
{"name":"State","schema":{"admin":"pubkey","whitelistMint":"pubkey","discountMint":"pubkey","signer":"pubkey","srmVault":"pubkey","perpFeeStructure":{"feeTiers":{"feeNumerator":"u32","feeDenominator":"u32","makerRebateNumerator":"u32","makerRebateDenominator":"u32","referrerRewardNumerator":"u32","referrerRewardDenominator":"u32","refereeFeeNumerator":"u32","refereeFeeDenominator":"u32"},"fillerRewardStructure":{"rewardNumerator":"u32","rewardDenominator":"u32","timeBasedRewardLowerBound":"u128"},"referrerRewardEpochUpperBound":"u64","flatFillerFee":"u64"},"spotFeeStructure":{"feeTiers":{"feeNumerator":"u32","feeDenominator":"u32","makerRebateNumerator":"u32","makerRebateDenominator":"u32","referrerRewardNumerator":"u32","referrerRewardDenominator":"u32","refereeFeeNumerator":"u32","refereeFeeDenominator":"u32"},"fillerRewardStructure":{"rewardNumerator":"u32","rewardDenominator":"u32","timeBasedRewardLowerBound":"u128"},"referrerRewardEpochUpperBound":"u64","flatFillerFee":"u64"},"oracleGuardRails":{"priceDivergence":{"markOraclePercentDivergence":"u64","oracleTwap5minPercentDivergence":"u64"},"validity":{"slotsBeforeStaleForAmm":"i64","slotsBeforeStaleForMargin":"i64","confidenceIntervalMaxSize":"u64","tooVolatileRatio":"i64"}},"numberOfAuthorities":"u64","numberOfSubAccounts":"u64","lpCooldownTime":"u64","liquidationMarginBufferRatio":"u32","settlementDuration":"u16","numberOfMarkets":"u16","numberOfSpotMarkets":"u16","signerNonce":"u8","minPerpAuctionDuration":"u8","defaultMarketOrderTimeInForce":"u8","defaultSpotAuctionDuration":"u8","exchangeStatus":"u8","liquidationDuration":"u8","initialPctToLiquidate":"u16","maxNumberOfSubAccounts":"u16","maxInitializeUserFee":"u16","padding":{"size":10,"type":"u8"}},"value":{"admin":"E1admb4tW2Y6bpbnpE5jYZsc4TE2NArG7siZqDsafnob","whitelistMint":"11111111111111111111111111111111","discountMint":"11111111111111111111111111111111","signer":"JCNCMFXo5M5qwUPg2Utu1u6YWp3MbygxqBsBeXXJfrw","srmVault":"11111111111111111111111111111111","perpFeeStructure":{"feeTiers":{"feeNumerator":100,"feeDenominator":100000,"makerRebateNumerator":10,"makerRebateDenominator":100000,"referrerRewardNumerator":15,"referrerRewardDenominator":100,"refereeFeeNumerator":5,"refereeFeeDenominator":100},"fillerRewardStructure":{"rewardNumerator":90,"rewardDenominator":100000,"timeBasedRewardLowerBound":"7922816251703135349956767907850"},"referrerRewardEpochUpperBound":"429496729605","flatFillerFee":"429496729600080"},"spotFeeStructure":{"feeTiers":{"feeNumerator":10,"feeDenominator":100000,"makerRebateNumerator":15,"makerRebateDenominator":100,"referrerRewardNumerator":5,"referrerRewardDenominator":100,"refereeFeeNumerator":70,"refereeFeeDenominator":100000},"fillerRewardStructure":{"rewardNumerator":10,"rewardDenominator":100000,"timeBasedRewardLowerBound":"7922816251518667480152439521295"},"referrerRewardEpochUpperBound":"429496729600060","flatFillerFee":"429496729600010"},"oracleGuardRails":{"priceDivergence":{"markOraclePercentDivergence":"429496729615","oracleTwap5minPercentDivergence":"429496729605"},"validity":{"slotsBeforeStaleForAmm":"429496729600030","slotsBeforeStaleForMargin":"429496729600010","confidenceIntervalMaxSize":"429496729615","tooVolatileRatio":"429496729605"}},"numberOfAuthorities":"429496729600000","numberOfSubAccounts":"429496729600000","lpCooldownTime":"429496729600","liquidationMarginBufferRatio":0,"settlementDuration":100,"numberOfMarkets":0,"numberOfSpotMarkets":0,"signerNonce":0,"minPerpAuctionDuration":0,"defaultMarketOrderTimeInForce":160,"defaultSpotAuctionDuration":134,"exchangeStatus":1,"liquidationDuration":0,"initialPctToLiquidate":0,"maxNumberOfSubAccounts":0,"maxInitializeUserFee":34464,"padding":[1,0,0,0,0,0,100,0,0,0]}}
Dependencies
~11–19MB
~285K SLoC