github-actions[bot] 36df852972 [1.x] Publish packages (#916) 2 zile în urmă
..
src 855c094e0a Use `ReadonlyUint8Arrays` with `InstructionWithData` types (#714) 4 luni în urmă
test c698fe5555 Add `dynamic-parsers` package (#294) 1 an în urmă
.gitignore c698fe5555 Add `dynamic-parsers` package (#294) 1 an în urmă
.prettierignore 760dda5775 Inline scripts in packages (#842) 2 luni în urmă
LICENSE 1794ecdd3f Update license dates (#835) 2 luni în urmă
README.md 364578e45e Remove `I` prefixes in Kit types (#713) 4 luni în urmă
package.json 36df852972 [1.x] Publish packages (#916) 2 zile în urmă
tsconfig.declarations.json c698fe5555 Add `dynamic-parsers` package (#294) 1 an în urmă
tsconfig.json 760dda5775 Inline scripts in packages (#842) 2 luni în urmă
tsup.config.ts 760dda5775 Inline scripts in packages (#842) 2 luni în urmă
vitest.config.mts 760dda5775 Inline scripts in packages (#842) 2 luni în urmă

README.md

Codama ➤ Dynamic Parsers

npm npm-downloads

This package provides a set of helpers that, given any Codama IDL, dynamically identifies and parses any byte array into deserialized accounts and instructions.

Installation

pnpm install @codama/dynamic-parsers

[!NOTE] This package is not included in the main codama package.

Types

ParsedData<TNode>

This type represents the result of identifying and parsing a byte array from a given root node. It provides us with the full NodePath of the identified node, as well as the data deserialized from the provided bytes.

type ParsedData<TNode extends AccountNode | InstructionNode> = {
    data: unknown;
    path: NodePath<TNode>;
};

Functions

parseAccountData(rootNode, bytes)

Given a RootNode and a byte array, this function will attempt to identify the correct account node and use it to deserialize the provided bytes. Therefore, it returns a ParsedData<AccountNode> object if the parsing was successful, or undefined otherwise.

const parsedData = parseAccountData(rootNode, bytes);
// ^ ParsedData<AccountNode> | undefined

if (parsedData) {
    const accountNode: AccountNode = getLastNodeFromPath(parsedData.path);
    const decodedData: unknown = parsedData.data;
}

parseInstructionData(rootNode, bytes)

Similarly to parseAccountData, this function will match the provided bytes to an instruction node and deserialize them accordingly. It returns a ParsedData<InstructionNode> object if the parsing was successful, or undefined otherwise.

const parsedData = parseInstructionData(rootNode, bytes);
// ^ ParsedData<InstructionNode> | undefined

if (parsedData) {
    const instructionNode: InstructionNode = getLastNodeFromPath(parsedData.path);
    const decodedData: unknown = parsedData.data;
}

parseInstruction(rootNode, instruction)

This function accepts a RootNode and an Instruction type — as defined in @solana/instructions — in order to return a ParsedData<InstructionNode> object that also includes an accounts array that match each AccountMeta with its corresponding account name.

const parsedData = parseInstruction(rootNode, instruction);

if (parsedData) {
    const namedAccounts = parsedData.accounts;
    // ^ Array<AccountMeta & { name: string }>
}

identifyAccountData

This function tries to match the provided bytes to an account node, returning a NodePath<AccountNode> object if the identification was successful, or undefined otherwise. It is used by the parseAccountData function under the hood.

const path = identifyAccountData(root, bytes);
// ^ NodePath<AccountNode> | undefined

if (path) {
    const accountNode: AccountNode = getLastNodeFromPath(path);
}

identifyInstructionData

This function tries to match the provided bytes to an instruction node, returning a NodePath<InstructionNode> object if the identification was successful, or undefined otherwise. It is used by the parseInstructionData function under the hood.

const path = identifyInstructionData(root, bytes);
// ^ NodePath<InstructionNode> | undefined

if (path) {
    const instructionNode: InstructionNode = getLastNodeFromPath(path);
}