3

I figured out how to decode the data buffer manually for a solana account data. I used the USDC account address to get the account data and then I used the @solana/buffer-layout for u64 buffer decoding and javascript Buffer functions to read the data bytes and decode them manually. The data for this case represents the fields of Mint struct defined in the state.rs located at https://github.com/solana-labs/solana-program-library/blob/8f75f5905cbd402e1853153117506193277f70f0/token/program/src/state.rs#L16.

Below is my code and the results of the code. The results match what is shown on the solana explorer. I am hoping that this will help other solana developers.

import {Connection, PublicKey} from '@solana/web3.js'; import {Buffer} from "buffer"; import * as BufferLayout from '@solana/buffer-layout';

let connection: Connection = new Connection("http://api.mainnet-beta.solana.com", "confirmed");;


async function main() {

    let usdc = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
    let usdcAcctInfo = await connection.getAccountInfo(usdc);
    console.log('\n USDC Token Account Info:')
    console.log(usdcAcctInfo);
    console.log("\n usdc data is ");
    console.log(usdcAcctInfo.data);

    // Decode first 4 bytes of the "data" buffer for the usdcAcctInfo
    // little endian reading of buffer for the first four bytes using
    // Buffer library functions of Javascript
    let mintAuthorityCoption = usdcAcctInfo.data.readUIntLE(0,4);
    console.log("\n Mint_Authority_Coption value is");
    console.log(mintAuthorityCoption);

    // Decode next 32 bytes to a PublicKey based on the Mint Struct
    let mintAuthority = new PublicKey(usdcAcctInfo.data.subarray(4, 36)).toBase58();
    console.log("\n Mint Authoriy Public Key is ");
    console.log(mintAuthority);

    let ns64 = new BufferLayout.NearUInt64();
    let supplySlice = usdcAcctInfo.data.subarray(36, 44);
    let arr = new Uint8Array(supplySlice);
    console.log("Uint8Array is");
    console.log(arr);
    let supply = ns64.decode(arr);
    console.log("\n Supply decoded ");
    console.log(supply);


    // decode next 1 byte representing the field decimal u8
    let decimal = usdcAcctInfo.data.readUIntLE(44, 1);
    console.log("\n decimal value is");
    console.log(decimal);

}

main().then(
    () => process.exit(),
    err => {
        console.error(err);
        process.exit(-1)
    } )

The output of the above code is as follows:

enter image description here

1 Answer 1

2

Did you know that the Buffer has convenient methods to read numbers? for instance you could use readBigInt64LE for the supply like this:

let supply = usdcAcctInfo.data.readBigInt64LE(36);

Then you don't need to manually handle the BufferLayout. Makes it a bit simpler imo. Though you do get back a bigInt and not a number.

And for people wondering why 36 and 44, those are the offsets in the token mint account. To quickly find the correct offset I find this illustration by Loris very helpful: Account offsets image

I know you didn't ask for this but you didn't ask anything so I though I might still answer :P

1
  • Thanks Solandy. I did not have a question but I like your suggestions. My intent was to get others to chime in on this and the information you provided is definitely extending my knowledge on this.
    – andromeda
    Commented Aug 3, 2022 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.