solana-labs / solana-web3.js

Solana JavaScript SDK
https://solana-labs.github.io/solana-web3.js
MIT License
2.27k stars 893 forks source link

[GraphQL]: Token-2022 Extension Instructions #2406

Closed buffalojoec closed 6 months ago

buffalojoec commented 8 months ago

Motivation

Token-2022 extensions are live and gaining popularity on all clusters. The GraphQL library must offer support for these extension instructions within the schema.

Hrushi20 commented 7 months ago

Hey! I'm interested in working on this issue. Can I get more context on getting started?

buffalojoec commented 7 months ago

Basically we need to add schema support for Token-2022 extensions. These will appear in a JSON-parsed instruction from an RPC-retrieved transaction or block.

I've marked a little placeholder in the instructions schema module where they can live: https://github.com/solana-labs/solana-web3.js/blob/acd929d95124df0f5b3e9d22fa97e7d870fe947f/packages/rpc-graphql/src/schema/instruction.ts#L515-L529

I think the easiest way to roll each of these is to grab their layouts from the Solana Transaction Status crate: https://github.com/anza-xyz/agave/blob/master/transaction-status/src/parse_token.rs

That file should have all the Token-2022 extensions that are parseable by the RPC's JSON-parsed, and we can just adapt them into GraphQL schema types!

The tricky bit is going to be querying the RPC manually (likely via CLI or something) and finding transaction payloads that have some of these instructions and using them in tests. You can just copy-paste them into the __setup__ module as we've done already: https://github.com/solana-labs/solana-web3.js/blob/master/packages/rpc-graphql/src/__tests__/__setup__.ts

Hrushi20 commented 7 months ago

Looking into it.

Hrushi20 commented 7 months ago

Hey! I was going through transfer_fee.rs file. I see that mint field is stored as a String in json. In rpc-grpc module, in some places mint is used as Account type.. Not sure what is the right data type to use

Edit: Or Should the type of mint be address?

buffalojoec commented 7 months ago

Hey! I was going through transfer_fee.rs file. I see that mint field is stored as a String in json. In rpc-grpc module, in some places mint is used as Account type.. Not sure what is the right data type to use

Edit: Or Should the type of mint be address?

So, with the way the GraphQL schema is configured, we can choose to use Account where the RPC would otherwise place an address. This allows queries to embed an account query on that address.

In other words, if initializeTransferFeeConfig comes back with:

mint: 'BrdbK35MgB3keCWx87eMpWf5v1QudW9vddxyH2Hb2m5r'

You could do something like:

query notARealQuery {
  transaction(signature: '5UJYEYLqHrdmnMU546Gs3Tj6PTnWPpwjarYAcG7Fp165PTnWPpwjarYAcG7Fp165') {
    instructions {
       ... on TransferFeeInitializeTransferFeeConfig {
         mint {
            lamports
            # More fields from `Account`...
            ... on MintAccount {
              supply
              # More fields from `MintAccount`...
            }
         }
       }
    }
  }
}

Note this only works if you add the field to the schema's resolver! https://github.com/solana-labs/solana-web3.js/blob/f9ddff548be9b510d17265ce885731533243c819/packages/rpc-graphql/src/resolvers/instruction.ts#L128

Hrushi20 commented 7 months ago

I'm unable to tick the checkbox in the PR.

Hrushi20 commented 7 months ago
Determining test suites to run...../../scripts/start-shared-test-validator.sh: line 31: pidof: command not found

I'm getting this error while running the tests locally. Not sure why???

I try starting the validator script,

Started test validator (PID 6856)
./start-shared-test-validator.sh: line 31: pidof: command not found
Leaving test validator (PID ) running for other lock participants
buffalojoec commented 7 months ago

pidof: command not found

You don't want to run that script yourself. Jest will run it when you run pnpm test:unit:node. As a side note, maybe you don't have the pidof command.

Hrushi20 commented 7 months ago

Thanks it works now, however I get the following error while running the test.

 FAIL   Unit Test (Node)  src/__tests__/account-test.ts
  ● Test suite failed to run

    Cannot find module '@solana/rpc' from 'src/__tests__/__setup__.ts'

    Require stack:
      src/__tests__/__setup__.ts
      src/__tests__/account-test.ts

      56 |             'Program Vote111111111111111111111111111111111111111 success',
      57 |         ],
    > 58 |         postBalances: [1007369134736714, 100000000000, 1],
         |              ^
      59 |         postTokenBalances: [],
      60 |         preBalances: [1007369134741714, 100000000000, 1],
      61 |         preTokenBalances: [],

      at Resolver._throwModNotFoundError (../../node_modules/.pnpm/jest-resolve@30.0.0-alpha.3/node_modules/jest-resolve/build/index.js:927:11)
      at Object.<anonymous> (src/__tests__/__setup__.ts:58:14)
      at Object.<anonymous> (src/__tests__/account-test.ts:6:19)

I've done an pnpm install at root directory level. Still 5 tests are failing. Due to this I'm unable to check the build passing locally.

buffalojoec commented 7 months ago

Thanks it works now, however I get the following error while running the test.

 FAIL   Unit Test (Node)  src/__tests__/account-test.ts
  ● Test suite failed to run

    Cannot find module '@solana/rpc' from 'src/__tests__/__setup__.ts'

    Require stack:
      src/__tests__/__setup__.ts
      src/__tests__/account-test.ts

      56 |             'Program Vote111111111111111111111111111111111111111 success',
      57 |         ],
    > 58 |         postBalances: [1007369134736714, 100000000000, 1],
         |              ^
      59 |         postTokenBalances: [],
      60 |         preBalances: [1007369134741714, 100000000000, 1],
      61 |         preTokenBalances: [],

      at Resolver._throwModNotFoundError (../../node_modules/.pnpm/jest-resolve@30.0.0-alpha.3/node_modules/jest-resolve/build/index.js:927:11)
      at Object.<anonymous> (src/__tests__/__setup__.ts:58:14)
      at Object.<anonymous> (src/__tests__/account-test.ts:6:19)

I've done an pnpm install at root directory level. Still 5 tests are failing. Due to this I'm unable to check the build passing locally.

Hm, I'm not able to reproduce it locally. I can see that your error is saying the dependency isn't found. Maybe try this from root.

pnpm i
pnpm turbo compile:js compile:typedefs
cd packages/rpc-graphql
pnpm test:unit:node
Hrushi20 commented 7 months ago

What is the node.js, npm and turbo version you are using?

buffalojoec commented 7 months ago

What is the node.js, npm and turbo version you are using?

$ node --version
v20.8.1

$ npm --version
10.1.0

$ pnpm turbo --version
1.13.3
Hrushi20 commented 7 months ago

I tried this on a new machine. I installed node & npm using nvm. I tried install pnpm in below image and I get this error.

Screenshot 2024-05-04 at 9 40 02 PM
buffalojoec commented 7 months ago

Ohh I've installed pnpm with Homebrew on MacOS. I should have posted that version as well.

$pnpm --version
9.0.6

Plus your command npm i pnpm is going to try to install pnpm to the workspace, and I think npm is barfing on the dependency structure of the workspace, which is really specific to pnpm.

Try either npm i -g pnpm or brew install pnpm or whatever OS you're on.

Hrushi20 commented 7 months ago

Thanks mate. Was trying since forever. Got it to work now.

nasjuice commented 7 months ago

Hello, could I help with this also? I can start InterestBearingMintInstruction

Hrushi20 commented 7 months ago

Hello, could I help with this also? I can start InterestBearingMintInstruction

I already started working on it. Feel free to start with another extension. It would be helpful if you mention what your working on so we don't work on duplicate things.

nasjuice commented 7 months ago

Sounds good, I'll start with this extension then ConfidentialTransfer

nasjuice commented 6 months ago

I believe InitializeMint has been done for ConfidentialTransfer

https://github.com/solana-labs/solana-web3.js/blob/d275ba641b3d65f81c7a2c200824f195583b0c9c/packages/rpc-graphql/src/schema/instruction.ts#L745

nasjuice commented 6 months ago

Also just noticed this

https://github.com/solana-labs/solana-web3.js/blob/16bb0b86410fe326d2f617f6ee800ce68f918864/packages/rpc-graphql/src/schema/instruction.ts#L626

I believe that should be a BigInt since it is a u64 https://github.com/anza-xyz/agave/blob/a645d07e06a5b2da8076539d5799a5087c5cff52/transaction-status/src/parse_token/extension/transfer_fee.rs#L21

buffalojoec commented 6 months ago

Also just noticed this

https://github.com/solana-labs/solana-web3.js/blob/16bb0b86410fe326d2f617f6ee800ce68f918864/packages/rpc-graphql/src/schema/instruction.ts#L626

I believe that should be a BigInt since it is a u64

https://github.com/anza-xyz/agave/blob/a645d07e06a5b2da8076539d5799a5087c5cff52/transaction-status/src/parse_token/extension/transfer_fee.rs#L21

Thanks I'll look into this. I think all Int fields in the instructions may need to become BigInt, but I can make that change.

buffalojoec commented 6 months ago

@Hrushi20 @nasjuice Hey guys, let's make sure to use the type aliases, such as Slot, Epoch and Lamports wherever appropriate.

I've added more of them in this PR: https://github.com/solana-labs/solana-web3.js/pull/2634.

buffalojoec commented 6 months ago

@Hrushi20 @nasjuice Thank you both for an awesome effort and hammering out all of these extensions!! I'll be sure to shout you guys out in the release.

If there's anything else you're interested in working on, feel free to tag me and ask any questions. As I continue to build the GraphQL demo application, I'll uncover more issues and things that need to be done in the GraphQL library.

The repository is public, and if you have ideas on stuff you want to add/showcase in the demo app, go ahead and dive in! Maybe we can work in the issues here, and over there as well!

https://github.com/buffalojoec/graphql-wallet

github-actions[bot] commented 6 months ago

Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up.