GithubHelp home page GithubHelp logo

explorer-kit's Introduction

SolanaFM logo

Solana Data Parser for Developers

Framework agnostic and can be used by anyone, everywhere



Features

  • ๐Ÿ“ฆ Framework agnostic - Use it with any framework you want
  • โ™ป๏ธ Space efficient - Reduce package size overhead as you don't have to generate SDKs for your project to use
  • ๐Ÿง‘โ€๐Ÿ’ป User friendly - Easy to use and understand

Getting Started

โšก๏ธ Installation

Install ExplorerKit with these simple commands:

  • Use any package manager that you desire to install ExplorerKit

Using npm:

npm add @solanafm/explorer-kit
npm add @solanafm/explorer-kit-idls

Using yarn:

yarn add @solanafm/explorer-kit
yarn add @solanafm/explorer-kit-idls

Using pnpm:

pnpm add @solanafm/explorer-kit
pnpm add @solanafm/explorer-kit-idls

Once the packages have been installed, you can start using ExplorerKit in your project ๐ŸŽ‰

๐Ÿš€ Usage

How to get a SolanaFM IdlItem to start parsing a transaction or account state for a particular program:

import { getProgramIdl } from "@solanafm/explorer-kit-idls";

const programId = "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY";
// Get the IDL for a specific program hash
const SFMIdlItem = await getProgramIdl(programId);
// You can also get an IDL at a specific slot context if you're trying to histroically parse a transaction / account
// but the IDL might not be backwards compatible.
const historicalSFMIdlItem = await getProgramIdl(programId, {
  slotContext: 132322893,
});

Parsing a transaction:

import { SolanaFMParser, checkIfInstructionParser, ParserType } from "@solanafm/explorer-kit"
import { getProgramIdl } from "@solanafm/explorer-kit-idls";

const programId = "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY";
// Get the IDL for a specific program hash
const SFMIdlItem = await getProgramIdl(programId);
// You can also get an IDL at a specific slot context if you're trying to histroically parse a transaction / account
// but the IDL might not be backwards compatible.
const historicalSFMIdlItem = await getProgramIdl(programId, {
    slotContext: 132322893,
});
// For now, we only support parsing transactions with an encoded base 58 message
const ixData = "1AMTAauCh9UPEJKKd6LnGGtWqFvRs2aUZkv9r6wNe3PTzB1KS9TbwYzM8Cp7vUSDYZXTxXJp5M"
// Checks if SFMIdlItem is defined, if not you will not be able to initialize the parser layout
if (SFMIdlItem) {
    const parser = new SolanaFMParser(SFMIdlItem, programId);
    const instructionParser = parser.createParser(ParserType.INSTRUCTION);

    if (instructionParser && checkIfInstructionParser(instructionParser)) {
        // Parse the transaction
        const decodedData = instructionParser.parseInstructions(ixData);
    }
}

Parsing an event data:

import { SolanaFMParser. checkIfEventParser, ParserType } from "@solanafm/explorer-kit"

// For event data they have to base-64 encoded and they can be extracted from logs or a inner instruction with CPI logs.
// Phoenix Program Event Data
const eventData = "DwEABF2SDQAAAABDfDtlAAAAAKiVfA0AAAAAL9p3EN7QVm+wCbiCUn2jVyJyazsZQYgqVRhf6h2a/pX5SjR+9eBu2sQU7NYr1TEeH7vRFNOiXSyDLJ9g+fDJrwMAAgAABPzrK7CsLqR5NiVFXYwyp7QgatDNQXbn3JA8wOVXQfANFxMTAAAAAIB/AAAAAAAAg7MAAAAAAAAAAAAAAAAAAAIBAAT86yuwrC6keTYlRV2MMqe0IGrQzUF259yQPMDlV0HwDhcTEwAAAACCfwAAAAAAAByBAAAAAAAA6EwCAAAAAAAGAgAAAAAAAAAAAAAAAAAAAAAAnzQBAAAAAABzEb6ZAAAAALveBwAAAAAA"
const parser = new SolanaFMParser(SFMIdlItem);
const eventParser = parser.createParser(ParserType.EVENT);

if (eventParser && checkIfEventParser(eventParser)) {
    // Parse the transaction
    const decodedData = parser.parseEvents(eventData);
}

Parsing an account data:

import { SolanaFMParser, checkIfAccountParser, ParserType } from "@solanafm/explorer-kit";

const SFMIdlItem = await getProgramIdl(programId);

// Account data have to be base-64 encoded
// Stake Pool Account Data
const accountData =
  "AWq1iyr99ATwNekhxZcljopQjeBixmWt+p/5CTXBmRbd3Noj1MlCDU6CVh08awajdvCUB/G3tPyo/emrHFdD8Wfh4Pippvxf8kLk81F78B7Wst0ZUaC6ttlDVyWShgT3cP/LqkIDCUdVLBkThURwDuYX1RR+JyWBHNvgnIkDCm914o2jckW1NrCzDbv9Jn/RWcT0cAMYKm8U4SfG/F878wV0XwxEYxirEMlfQJSVhXDNBXRlpU2rFNnd40gahv7V/Mvj/aPav/vdTOwRdFALTRZQlijB9G5myz+0QWe7U7EGIQbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpE2P1ZIWKAQDUAp5GdmQBAMkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQJwAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECcAAAAAAAAAAAAAAAAAAABWHWK1dGQBAAgnQqFYigEAv0rw1gHIAQAPfXpGLPQBABAnAAAAAAAAAAAAAAAAAAAAicd7jscBANVMdCNW7gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";

const parser = new SolanaFMParser(SFMIdlItem);
const eventParser = parser.createParser(ParserType.ACCOUNT);

if (eventParser && checkIfAccountParser(eventParser)) {
  // Parse the transaction
  const decodedData = eventParser.parseAccount(accountData);
}

Once the data is parsed, the returned data type will look something like this

export type ParserOutput = {
  // The name of the struct that's being used to parse the data
  name: string;
  // The parsed data according to the IDL schema
  data: any;
  // ParserType depends on the type of parser you have initialized
  type: ParserType;
} | null;

More to be added soon...

You can also checkout the examples as well!

Caveats and Limitations

  • IDLs found in @solanafm/explorer-kit-idls are usually IDLs for programs that are immutable and are not expected to change. These IDLs can be imported directly from the package and used in your project without interacting with our API. If you wish to get the latest IDLs that might be on chain, getProgramIdl() will do a API call to our API to query for the relevant IDLs
  • Account and Event parsers only takes in a base64 encoded string at the moment
  • Instruction parsers only takes in a base58 encoded string at the moment

Supported Programs

Program IDs Program Working Parsers
11111111111111111111111111111111 System Program Account, Instructions
Config1111111111111111111111111111111111111 Config Program Account, Instructions
Stake11111111111111111111111111111111111111 Stake Program Account, Instructions
Vote111111111111111111111111111111111111111 Vote Program Account, Instructions
ComputeBudget111111111111111111111111111111 Compute Budget Program Instructions
BPFLoaderUpgradeab1e11111111111111111111111 BPF Upgradeable Loader Program Account, Instructions
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA Token Program Account, Instructions
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb Token 2022 Program Account, Instructions, Extensions (built-in)
namesLPneVptA9Z5rqUDD9tMTWEJwofgaYwp8cawRkX Name Service Program Account, Instructions
SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy Stake Pool Program Account, Instructions
ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL Associated Token Program Instructions
PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY Phoenix Program Account, Instructions, Events
metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s Token Metadata Program Account, Instructions
auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg Token Auth Rules Program Instructions
AddressLookupTab1e1111111111111111111111111 Address Lookup Table Account, Instructions
SysvarC1ock11111111111111111111111111111111 Clock Sysvar Account
SysvarEpochSchedu1e111111111111111111111111 Epoch Schedule Sysvar Account
SysvarFees111111111111111111111111111111111 Fees Sysvar Account
SysvarRecentB1ockHashes11111111111111111111 Recent Blockhashes Sysvar Account
SysvarRent111111111111111111111111111111111 Rent Sysvar Account
SysvarRewards111111111111111111111111111111 Rewards Sysvar Account
SysvarS1otHashes111111111111111111111111111 Slot Hashes Sysvar Account
SysvarStakeHistory1111111111111111111111111 Stake History Sysvar Account
MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo Memo Program Instructions
cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK SPL Account Compression Instructions, Events
BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY Bubblegum Instructions, Events
TCMPhJdwDryooaGtiocG1u3xcYbRpiJzb283XfCZsDp Tensor Compression Instructions, Events

And many more programs that have their IDLs uploaded on chain. Feel free to contact anyone in the team or open a pull request to have your IDLs added to the list!

Credits

Explorer Kit is hugely inspired and built upon Kinobi. Without Kinobi, Explorer Kit would not have been possible at it's current iteration.

Also, huge thanks to the following projects and engineers for making this possible:

  • Loris - For all the work and help he has poured into Kinobi and Umi
  • Umi - Usage of their deserializers to decode the various data types
  • Kinobi - Kinobi parsing of IDLs to a Kinobi Tree has been a great inspiration in creating a layout to be stored in memory for deserialization
  • Anchor

Contributing

We welcome all contributions to Explorer Kit! Feel free to open a pull request or issues to discuss your ideas and suggestions. You may checkout our contributing guide for more information on how to contribute to Explorer Kit.

License

Explorer Kit is licensed under the GNU v3

explorer-kit's People

Contributors

doodoo-aihc avatar em-ctc avatar fabioberger avatar github-actions[bot] avatar mcintyre94 avatar turbobot-temp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

explorer-kit's Issues

ESM Import Fails

Describe the bug

A clear and concise description of what the bug is.

I've installed the package into my CommonJS typescript application, however I get the following error when attempting to import the module:

Error [ERR_REQUIRE_ESM]: require() of ES Module ... /node_modules/change-case/dist/index.js

Can this get updated to support CommonJS? The cause appears to be the change-case package that only gets used once to change a string to snake case.

This could easily be updated to use a local copy instead of relying on this module:

https://www.30secondsofcode.org/js/s/string-case-conversion/#convert-any-case-to-snake-case

Support IDLs generated from Anchor 0.3.0

Describe the solution you'd like
Anchor recently released 0.3.0 of Anchor and there are breaking changes with regards to the IDL after it's generated from a 0.3.0 Anchor program. The IDLs from 0.29.0 and earlier will not be compatible with the 0.3.0 typescript client.

  • We should most probably be running a dual-client set up at the moment to ensure compatatibility between both versions

Additional context

Instruction parsing fails

Describe the bug
I created an instruction parser for bubblegum. The parsing of innerInstructions fails with error

return str
67 |   }
68 |   function decodeUnsafe (source) {
69 |     console.log("DECODE UNSAFE");
70 |     console.log(source);
71 |     if (typeof source !== 'string') { throw new TypeError('Expected String') }
                                                 ^
TypeError: Expected String
      at decodeUnsafe (/home/almei/Documents/solana/solana-scripts/node_modules/@solanafm/utils/node_modules/bs58/node_modules/base-x/src/index.js:71:45)
      at decode (/home/almei/Documents/solana/solana-scripts/node_modules/@solanafm/utils/node_modules/bs58/node_modules/base-x/src/index.js:115:18)
      at z (/home/almei/Documents/solana/solana-scripts/node_modules/@solanafm/utils/dist/index.js:1:1956)
      at parseInstructions (/home/almei/Documents/solana/solana-scripts/node_modules/@solanafm/explorer-kit/dist/index.mjs:5018:26)
      at /home/almei/Documents/solana/solana-scripts/parsers/bubblegum.ts:61:40
      at processTicksAndRejections (:61:77)

I added log statements in:

  1. node_modules/@solanafm/utils/node_modules/bs58/node_modules/base-x/src/index.js:69
  function decodeUnsafe (source) {
    console.log("DECODE UNSAFE");
    console.log(source);
    if (typeof source !== 'string') { throw new TypeError('Expected String') }

The output is undefined

  1. node_modules/@solanafm/utils/node_modules/bs58/node_modules/base-x/src/index.js
  function decode (string) {
    console.log("STRING TO DECODE");
    console.log(string);
    var buffer = decodeUnsafe(string)

The output is undefined

My:

  • programHash: BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY
  • transaction: 4FZvTLqp3CutUBdq4ja9gtfvuF3NkhvRWBDGYaiQ1cptRBes8gpEpqfCKc83eM35GeGYGziX6K4kr7652KxLUWrG

I'm using the example script from #6

Screenshots
Here's a screenshot of my instruction data, accounts which exist and then the logs & error
image

Desktop (please complete the following information):

  • OS: Ubuntu 22.04.3 LTS
  • Bun: 1.0.22

Additional context
I cloned the repo and added a test with the programHash & transaction mentioned above and it errored the same there as well. Can this be a dependency issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.