solana-web3.js icon indicating copy to clipboard operation
solana-web3.js copied to clipboard

[experimental] RPC method typespec contribution guide

Open steveluscher opened this issue 2 years ago • 0 comments
trafficstars

The new experimental @solana/web3.js implements every RPC method as a type specification. These typespecs power autocomplete in your editor, and help you verify your program's type safety using Typescript – both in terms of the values you send to the Solana JSON-RPC, and in terms of the responses that you get from it.

You're here because you're interested in contributing a type specification to the project. This is a great way to learn more about how the Solana RPC works, and the best way to add support for the methods you need in the new @solana/web3.js.

How?

In general, the way you add support for an RPC method is by writing a Typescript interface that describes its inputs and outputs. This interface must match the inputs/outputs of the JSON-RPC exactly. Same positional order for the input arguments, same shape for the output return type.

type GetTokenAccountBalanceApiConfig = Readonly<{
  committment?: Commitment,
}>;

type GetTokenAccountBalanceApiResponse = Readonly<{
  // the raw balance without decimals, a string representation of u64
  amount: string,
  // number of base 10 digits to the right of the decimal place
  decimals: number,
  /** @deprecated Use `uiAmountString` instead */
  // the balance, using mint-prescribed decimals
  uiAmount: number | null,
  // the balance as a string, using mint-prescribed decimals
  uiAmountString: string,
}>

export interface GetTokenAccountBalanceApi {
  getTokenAccountBalance(
    // Pubkey of Token account to query, as base-58 encoded string
    address: Base58EncodedAddress,
    config?: GetTokenAccountBalanceApiConfig,
  ): Promise<GetTokenAccountBalanceApiResponse>
}

A perfectly-crafted interface is only the beginning; to get a PR accepted, make sure to go through the checklist below to finish it up.

Have an example?

Study this PR; it's a good example of how to go about adding a method to the RPC. It is also a good example of some of the challenges you might bump up against.

Checklist

Before you send your own PR, copy and paste this checklist into your PR description.

- [ ] I read the [JSON-RPC docs](https://docs.solana.com/api/http) for my method and implemented it faithfully as a Typescript interface in [`packages/rpc-core/src/rpc-methods`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/rpc-core/src/rpc-methods)
- [ ] I have commented the inputs and outputs of my Typescript interface using text from the JSON-RPC docs
- [ ] I have read through the Rust source code of my RPC method to make sure that it accepts the inputs that I expect, returns the outputs that I expect, and applies the defaults I expect when an input is not supplied
- [ ] Wherever my method's return value changes based on its inputs, I've implemented that as a [Typescript function overload](https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads) ([example](https://github.com/solana-labs/solana-web3.js/blob/b69daf278045bc96740450e123a322e0dd95f60e/packages/rpc-core/src/rpc-methods/getAccountInfo.ts#L80-L114))
- [ ] I have written a test in [`packages/rpc-core/src/rpc-methods/__tests__`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/rpc-core/src/rpc-methods/__tests__) that exercises as much of my RPC method's functionality as is practical
- [ ] Wherever my test relies on reading account data I have created an account fixture in [`scripts/fixtures`](https://github.com/solana-labs/solana-web3.js/tree/master/scripts/fixtures) that gets loaded into the test validator ([example](https://github.com/solana-labs/solana-web3.js/blob/master/scripts/fixtures/4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc.json))
- [ ] If my RPC method returns a numeric value _other_ than a `u64` or `usize` (eg. a `u8`) I have encoded an exception for that return value so that it does _not_ get upcast to a `bigint` in the RPC ([example](https://github.com/solana-labs/solana-web3.js/blob/b69daf278045bc96740450e123a322e0dd95f60e/packages/rpc-core/src/response-patcher-allowed-numeric-values.ts#L12))

steveluscher avatar Apr 24 '23 19:04 steveluscher