Skip to content

Conversation

@Resister-boy
Copy link
Contributor

@Resister-boy Resister-boy commented Mar 22, 2025

Pull Request Description

Changes Made

This PR adds the following changes:

Add a SolanaFMParser to the SolanaAgentKit. An Action has been added to parse instruction raw data and account raw data in base64 format. The SolanaAgent can decode raw data by taking either a programId and instruction data or a programId and account data as input parameters.

  • raw data of instruction for SolanaParseInstructionTool.
  • raw data of account for SolanaParseAccountTool

Implementation Details

This PR includes the implementation of parse instruction data and parse account data from transaction. User(or Agent) can parse base64 encoded data based on the SolanaFMParser library by providing programId and encoded data as a parameters.

Among the agent tools for data parsing, there is a transaction parser that leverages helius API, This feature is available at the transaction level rather than for individual instructions or accounts, and it comes with the limitation of requiring the Helius API Key. The SolanaFMParser introduced in the above PR allows you to decode data for each instruction or account without requiring an additional API key.

Fetch the IDL using the provided programId as the first argument, and decode the data given as the second argument based on that IDL.
If the programId is invalid or the data does not conform to the defined format, throw an error.

If the data is successfully decoded, return the provided programId, the data layout, and the decoded data.

Transaction executed by agent

This feature does not generate any transactions on-chain. It is designed to decode the given data.

Prompt Used

For the parsing instruction data:

const systemPrompt = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. 
    You can parse raw data of instructions from a Solana transaction.`;

const userPrompt = `
    Parse the raw data of the following Solana programId and instructionData:

    programId: metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
    instructionData: 3UwpeiMtquiTRwEh3LDXQ2ackEUawDAPVnEmbcfFU66N4Knmo4ArVS1XPSjj5UvUtsdQSxGcksSP5ERNDR36DFz8VnkSNBBFt5LfGc3WV7nDpqSfrcguxcMSgE7it74MGBBXUix9tPdKxxete8o4DKEUyt4b6mWnR9DbnyiNL8JnhAddSh99YP8zXGAFboUYejp5sVoZrpcyj2i1BMoogv1Hu2BucZHEdzPSQ4Ws6g8x8aUmx7StsesEPU7cFMpCtfes9xzcCE9M

    After parsing the raw data, provide a human-readable explanation of the instruction.
    `;

For the parsing account data:

const systemPrompt = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. 
    You can parse raw data of account from a Solana transaction.`;

const userPrompt = `
    Parse the raw data of the following Solana programId and accountData:

    programId: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
    accountData: AQAAAKNtpf5xH4vTOhHcj+c7iFOBtiodZCZHvMJUCmaAWfmwAMqaOwAAAAAGAQEAAAAngUPsMTO0Ea8yotiDMEigFh6e3Pq4ZJzsKSQdW3kXsg==

    After parsing the raw data, provide a human-readable explanation of the instruction.
    `;

Additional Notes

Checklist

  • I have tested these changes locally
  • I have updated the documentation
  • I have added a transaction link
  • I have added the prompt used to test it

@Resister-boy
Copy link
Contributor Author

Resister-boy commented Mar 22, 2025

Code to testing parse instruction data:

export const ENV = cleanEnv(process.env, {
  OPENAI_API_KEY: str(),
  SOLANA_TESTNET_RPC: str(),
  WALLET_PRIVATE_KEY: str(),
});

const messageModifier = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
    empowered to interact onchain using your tools. If you ever need funds, you can request them from the
    faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
    (internal) HTTP error code, ask the user to try again later.
  `;

const systemPrompt = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. 
    You can parse raw data of instructions from a Solana transaction.`;

const userPrompt = `
    Parse the raw data of the following Solana programId and instructionData:

    programId: metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
    instructionData: 3UwpeiMtquiTRwEh3LDXQ2ackEUawDAPVnEmbcfFU66N4Knmo4ArVS1XPSjj5UvUtsdQSxGcksSP5ERNDR36DFz8VnkSNBBFt5LfGc3WV7nDpqSfrcguxcMSgE7it74MGBBXUix9tPdKxxete8o4DKEUyt4b6mWnR9DbnyiNL8JnhAddSh99YP8zXGAFboUYejp5sVoZrpcyj2i1BMoogv1Hu2BucZHEdzPSQ4Ws6g8x8aUmx7StsesEPU7cFMpCtfes9xzcCE9M

    After parsing the raw data, provide a human-readable explanation of the instruction.
    `;

const main = async () => {
  const llm = new ChatOpenAI({
    modelName: "gpt-4o",
    apiKey: ENV.OPENAI_API_KEY,
  });
  const memory = new MemorySaver();

  const solanaAgent = new SolanaAgentKit(
    ENV.WALLET_PRIVATE_KEY,
    ENV.SOLANA_TESTNET_RPC,
    {
      OPENAI_API_KEY: ENV.OPENAI_API_KEY,
    },
  );

  const parseInstructionTool = new SolanaParseInstructionTool(solanaAgent);

  const agent = createReactAgent({
    llm,
    tools: [parseInstructionTool],
    checkpointSaver: memory,
    messageModifier,
  });

  const response = await agent.invoke(
    {
      messages: [new SystemMessage(systemPrompt), new HumanMessage(userPrompt)],
    },
    {
      configurable: {
        thread_id: "parse solana raw_data",
      },
    },
  );

  for (const message of response.messages) {
    if (message instanceof AIMessage) {
      console.log(message.content);
    }
  }
};

main();

@Resister-boy
Copy link
Contributor Author

Code to testing parse account data:

export const ENV = cleanEnv(process.env, {
  OPENAI_API_KEY: str(),
  SOLANA_TESTNET_RPC: str(),
  WALLET_PRIVATE_KEY: str(),
});

const messageModifier = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
    empowered to interact onchain using your tools. If you ever need funds, you can request them from the
    faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
    (internal) HTTP error code, ask the user to try again later.
  `;

const systemPrompt = `
    You are a helpful agent that can interact onchain using the Solana Agent Kit. 
    You can parse raw data of account from a Solana transaction.`;

const userPrompt = `
    Parse the raw data of the following Solana programId and accountData:

    programId: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
    accountData: AQAAAKNtpf5xH4vTOhHcj+c7iFOBtiodZCZHvMJUCmaAWfmwAMqaOwAAAAAGAQEAAAAngUPsMTO0Ea8yotiDMEigFh6e3Pq4ZJzsKSQdW3kXsg==

    After parsing the raw data, provide a human-readable explanation of the instruction.
    `;

const main = async () => {
  try {
    const llm = new ChatOpenAI({
      modelName: "gpt-4o",
      apiKey: ENV.OPENAI_API_KEY,
    });
    const memory = new MemorySaver();

    const solanaAgent = new SolanaAgentKit(
      ENV.WALLET_PRIVATE_KEY,
      ENV.SOLANA_TESTNET_RPC,
      {
        OPENAI_API_KEY: ENV.OPENAI_API_KEY,
      },
    );

    const parseAccountTool = new SolanaParseAccountTool(solanaAgent);

    const agent = createReactAgent({
      llm,
      tools: [parseAccountTool],
      checkpointSaver: memory,
      messageModifier,
    });

    const response = await agent.invoke(
      {
        messages: [
          new SystemMessage(systemPrompt),
          new HumanMessage(userPrompt),
        ],
      },
      {
        configurable: {
          thread_id: "parse solana raw_data",
        },
      },
    );

    for (const message of response.messages) {
      if (message instanceof AIMessage) {
        console.log(message.content);
      }
    }
  } catch (error: any) {
    console.log(error);
  }
};

main();

@Resister-boy Resister-boy force-pushed the feature/solana-fm-parser branch from 6ea531e to eed4945 Compare March 22, 2025 09:37
@Resister-boy Resister-boy deleted the feature/solana-fm-parser branch March 22, 2025 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant