chainsaw Build+Test

Deserializing Solana accounts using their progam IDL.

Table of Contents generated with DocToc

Installation

cargo add sol-chainsaw

Example

```rs let opts = SerializationOpts { pubkeyasbase58: true, n64asstring: false, n128asstring: true, };

let mut chainsaw = ChainsawDeserializer::new(&opts);

// 1. Add IDLS

// Candy Machine IDL let cndyprogramid = "cndy3Z4yapfJBmL3ShUp5exZKqR3z33thTzeNMm2gRZ"; { let idljson = readidljson(&cndyprogramid); chainsaw .addidljson(cndyprogramid.tostring(), &idljson, IdlProvider::Anchor) .expect("failed adding IDL JSON"); } // Staking Program IDL let stakeprogramid = "StakeSSzfxn391k3LvdKbZP5WVwWd6AsY1DNiXHjQfK"; { let idljson = readidljson(&stakeprogramid); chainsaw .addidljson(stakeprogramid.tostring(), &idljson, IdlProvider::Anchor) .expect("failed adding IDL JSON"); }

// 2. Read Accounts Data

// Stake Account let stakeaccdata = readaccount( &stakeprogram_id, "EscrowHistory", "5AEHnKRonYWeXWQTCqbfaEY6jHy38ifutWsriVsxsgbL", );

// Candy Machine Account let cndyaccdata = readaccount( &cndyprogram_id, "CollectionPDA", "4gt6YPtgZp2MYJUP7cAH8E3UiL6mUruYaPprEiyJytQ4", );

// 3. Deserialize Accounts

// Stake Account { let mut accjson = String::new(); chainsaw .deserializeaccount( &stakeprogramid, &mut stakeaccdata.asslice(), &mut accjson, ) .expect("failed to deserialize account"); assert!(acc_json.contains("{\"escrow\":\"4uj6fRJzqoNRPktmYqGX1nBkjAJBsimJ4ug77S3Tzj7y\"")); }

// Candy Machine Account { let mut accjson = String::new(); chainsaw .deserializeaccount( &cndyprogramid, &mut cndyaccdata.asslice(), &mut accjson, ) .expect("failed to deserialize account"); asserteq!(accjson, "{\"mint\":\"BrqNo3sQFTaq9JevoWYhgagJEjE3MmTgYonfaHV5Mf3E\",\"candyMachine\":\"DpBwktkJsEPTtsRpD8kCFGwEUjwTkXARSGSTQ7MJr4kE\"}"); } ```

See ./examples/multipleidlsand_accounts.rs for the full example.

Run it via: cargo run --example multiple_idls_and_accounts

Network Feature

To make retrieving IDLs from chain easier an idl client implementation is included which is only enabled when the network feature is enabled.

rs let idl_client = IdlClient::for_anchor_on_mainnet(); let program_idl = idl_client.fetch(program_id)?;

_more detailed example inside tests/task_update_idls.rs.

Development

Test Tasks

Various tasks related to tests were included via the ./Makefile. They are part of the tests folder but gated behind features. Thus to activate them specific features need to be enabled.

In order to use a custom RPC cluster when running those tasks please provide it via the RPC_URL env var, i.e.:

sh export RPC_URL="https://solana-mainnet.g.alchemy.com/v2/<mykey>"

Updating IDLs

Inside ./tests/data/programs_with_idl.json are program ids which have IDLs uploaded on chain.

Those IDLs are stored inside ./fixtures/idls to be used by integration tests.

Fetching Test Data from Chain

Triaging Account Deserialization

In order to isolate deserialization issues for specific accounts use on of the following tasks and provide the required env vars.

Examples:

sh export PROGRAM_ID=1USDCmv8QmvZ9JaL7bmevGsNHn7ez8TNahJzCN551sb export ACCOUNT_TYPE=DepositReceipt make deserialize_account_type_address_for_program ADDRESS=AyMxDEJPvJv6XQaFK9ZZ9XxDxHuVB8d7NUxP8TfLX45K

sh export PROGRAM_ID=1USDCmv8QmvZ9JaL7bmevGsNHn7ez8TNahJzCN551sb make deserialize_account_type_for_program ACCOUNT_TYPE=Realm

sh export PROGRAM_ID=1USDCmv8QmvZ9JaL7bmevGsNHn7ez8TNahJzCN551sb make deserialize_accounts_for_program

LICENSE

MIT