Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
Move RpcRequest and RpcResponse types to rpc-spec-types (#3393)
Browse files Browse the repository at this point in the history
One of the goals of this stack is to eventually make `RpcRequestTransformers` and `RpcResponseTransformers` usable on both RPC and RPC Subscriptions architectures. This was the original intention of the `rpc-transformers` package which already hosts request and response transformers for both but with inconsistent types.

As such, this PR aims to get closer to this goal by moving the `RpcRequest`, `RpcResponse`, `RpcRequestTransformer` and `RpcResponseTransformer` types from the `rpc-spec` package to the `rpc-spec-types` package.

As a reminder the `rpc-spec` and `rpc-subscriptions-spec` packages define the interfaces of the RPC and RPC Subscriptions architectures respectively, whereas, the `rpc-spec-types` package is a utility package that is imported by both of the former packages.

Note that, the `rpc-spec-types` package is now being exported from the main library because re-exporting that package in both `rpc` and `rpc-subscriptions` would be problematic for the main library that re-exports both.

Addresses #2983.
lorisleiva authored Oct 23, 2024

Unverified

This user has not yet uploaded their public signing key.
1 parent 0f739b6 commit 3c02c35
Showing 29 changed files with 86 additions and 51 deletions.
6 changes: 6 additions & 0 deletions .changeset/giant-seals-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@solana/rpc-spec-types': patch
'@solana/rpc-spec': patch
---

Move RpcRequest and RpcResponse types to rpc-spec-types
1 change: 1 addition & 0 deletions packages/library/package.json
Original file line number Diff line number Diff line change
@@ -86,6 +86,7 @@
"@solana/rpc-parsed-types": "workspace:*",
"@solana/rpc-subscriptions": "workspace:*",
"@solana/rpc-types": "workspace:*",
"@solana/rpc-spec-types": "workspace:*",
"@solana/signers": "workspace:*",
"@solana/sysvars": "workspace:*",
"@solana/transaction-confirmation": "workspace:*",
1 change: 1 addition & 0 deletions packages/library/src/index.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ export * from '@solana/rpc';
export * from '@solana/rpc-parsed-types';
export * from '@solana/rpc-subscriptions';
export * from '@solana/rpc-types';
export * from '@solana/rpc-spec-types';
export * from '@solana/signers';
export * from '@solana/transaction-messages';
export * from '@solana/transactions';
23 changes: 22 additions & 1 deletion packages/rpc-spec-types/README.md
Original file line number Diff line number Diff line change
@@ -14,4 +14,25 @@

# @solana/rpc-spec-types

TODO
This package contains core types that can be used on both RPC and RPC Subscriptions specifications. It can be used standalone, but it is also exported as part of the Solana JavaScript SDK [`@solana/web3.js@rc`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/library).

## Types

### `RpcRequest`

An object that describes the elements of an RPC or RPC Subscriptions request. It consists of the following properties:

- `methodName`: The name of the RPC method or subscription requested.
- `params`: The parameters to be passed to the RPC server.

### `RpcRequestTransformer`

A function that accepts an `RpcRequest` and returns another `RpcRequest`. This allows the `RpcApi` to transform the request before it is sent to the RPC server.

### `RpcResponse`

A type that represents the response from an RPC server. This could be any sort of data which is why `RpcResponse` defaults to `unknown`. You may use a type parameter to specify the shape of the response — e.g. `RpcResponse<{ result: number }>`.

### `RpcResponseTransformer`

A function that accepts an `RpcResponse` and returns another `RpcResponse`. This allows the `RpcApi` to transform the response before it is returned to the caller.
1 change: 1 addition & 0 deletions packages/rpc-spec-types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './overloads';
export * from './rpc-message';
export * from './rpc-request';
export * from './rpc-response';
export * from './type-helpers';
Original file line number Diff line number Diff line change
@@ -3,12 +3,6 @@ export type RpcRequest<TParams = unknown> = {
readonly params: TParams;
};

export type RpcResponse<TResponse = unknown> = TResponse;

export type RpcRequestTransformer = {
<TParams>(request: RpcRequest<TParams>): RpcRequest;
};

export type RpcResponseTransformer<TResponse = unknown> = {
(response: RpcResponse, request: RpcRequest): RpcResponse<TResponse>;
};
8 changes: 8 additions & 0 deletions packages/rpc-spec-types/src/rpc-response.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import type { RpcRequest } from './rpc-request';

export type RpcResponse<TResponse = unknown> = TResponse;

export type RpcResponseTransformer<TResponse = unknown> = {
(response: RpcResponse, request: RpcRequest): RpcResponse<TResponse>;
};

interface IHasIdentifier {
readonly id: number;
}
19 changes: 0 additions & 19 deletions packages/rpc-spec/README.md
Original file line number Diff line number Diff line change
@@ -41,25 +41,6 @@ Calling the `send(options)` method on a `PendingRpcRequest` will trigger the req

An object that exposes all of the functions described by `TRpcMethods`, and fulfils them using `TRpcTransport`. Calling each method returns a `PendingRpcRequest<TResponse>` where `TResponse` is that method's response type.

### `RpcRequest`

An object that describes the elements of a JSON RPC request. It consists of the following properties:

- `methodName`: The name of the JSON RPC method to be called.
- `params`: The parameters to be passed to the JSON RPC method.

### `RpcRequestTransformer`

A function that accepts an `RpcRequest` and returns another `RpcRequest`. This allows the `RpcApi` to transform the request before it is sent to the JSON RPC server.

### `RpcResponse`

A type that represents the response from a JSON RPC server. This could be any sort of data which is why `RpcResponse` defaults to `unknown`. You may use a type parameter to specify the shape of the response — e.g. `RpcResponse<{ result: number }>`.

### `RpcResponseTransformer`

A function that accepts an `RpcResponse` and returns another `RpcResponse`. This allows the `RpcApi` to transform the response before it is returned to the caller.

### `RpcApi<TRpcMethods>`

For each of `TRpcMethods` this object exposes a method with the same name that maps between its input arguments and a `RpcApiRequestPlan<TResponse>` that describes how to prepare a JSON RPC request to fetch `TResponse`.
3 changes: 2 additions & 1 deletion packages/rpc-spec/src/__tests__/rpc-api-test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import '@solana/test-matchers/toBeFrozenObject';

import type { RpcRequest, RpcResponse } from '@solana/rpc-spec-types';

import { createJsonRpcApi } from '../rpc-api';
import { RpcRequest, RpcResponse } from '../rpc-shared';

type DummyApi = {
someMethod(...args: unknown[]): unknown;
1 change: 0 additions & 1 deletion packages/rpc-spec/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './rpc';
export * from './rpc-api';
export * from './rpc-shared';
export * from './rpc-transport';
10 changes: 7 additions & 3 deletions packages/rpc-spec/src/rpc-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Callable, createRpcMessage } from '@solana/rpc-spec-types';

import { RpcRequestTransformer, RpcResponse, RpcResponseTransformer } from './rpc-shared';
import {
Callable,
createRpcMessage,
RpcRequestTransformer,
RpcResponse,
RpcResponseTransformer,
} from '@solana/rpc-spec-types';

export type RpcApiConfig = Readonly<{
requestTransformer?: RpcRequestTransformer;
2 changes: 1 addition & 1 deletion packages/rpc-spec/src/rpc-transport.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RpcResponse } from './rpc-shared';
import { RpcResponse } from '@solana/rpc-spec-types';

type RpcTransportRequest = Readonly<{
payload: unknown;
2 changes: 1 addition & 1 deletion packages/rpc-transformers/package.json
Original file line number Diff line number Diff line change
@@ -73,7 +73,7 @@
"dependencies": {
"@solana/errors": "workspace:*",
"@solana/functional": "workspace:*",
"@solana/rpc-spec": "workspace:*",
"@solana/rpc-spec-types": "workspace:*",
"@solana/rpc-subscriptions-spec": "workspace:*",
"@solana/rpc-types": "workspace:*"
},
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RpcRequestTransformer } from '@solana/rpc-spec';
import type { RpcRequestTransformer } from '@solana/rpc-spec-types';
import type { Commitment } from '@solana/rpc-types';

import { getDefaultRequestTransformerForSolanaRpc } from '../request-transformer';
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SOLANA_ERROR__JSON_RPC__PARSE_ERROR, SolanaError } from '@solana/errors';
import { RpcRequest } from '@solana/rpc-spec';
import { RpcRequest } from '@solana/rpc-spec-types';

import { getDefaultResponseTransformerForSolanaRpc } from '../response-transformer';
import { KEYPATH_WILDCARD } from '../tree-traversal';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec';
import type { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec-types';
import type { Commitment } from '@solana/rpc-types';

export function getDefaultCommitmentRequestTransformer({
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RpcRequest } from '@solana/rpc-spec';
import { RpcRequest } from '@solana/rpc-spec-types';

import { getTreeWalkerRequestTransformer, KeyPath, TraversalState } from './tree-traversal';

2 changes: 1 addition & 1 deletion packages/rpc-transformers/src/request-transformer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pipe } from '@solana/functional';
import { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec';
import { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec-types';
import { Commitment } from '@solana/rpc-types';

import { getBigIntDowncastRequestTransformer } from './request-transformer-bigint-downcast';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RpcResponseTransformer } from '@solana/rpc-spec';
import { RpcResponseTransformer } from '@solana/rpc-spec-types';

type JsonRpcResponse = { result: unknown };

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getSolanaErrorFromJsonRpcError } from '@solana/errors';
import { RpcResponseTransformer } from '@solana/rpc-spec';
import { RpcResponseTransformer } from '@solana/rpc-spec-types';

type JsonRpcResponse = { error: Parameters<typeof getSolanaErrorFromJsonRpcError>[0] } | { result: unknown };

2 changes: 1 addition & 1 deletion packages/rpc-transformers/src/response-transformer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { pipe } from '@solana/functional';
import { RpcRequest, RpcResponse, RpcResponseTransformer } from '@solana/rpc-spec';
import { RpcRequest, RpcResponse, RpcResponseTransformer } from '@solana/rpc-spec-types';

import { AllowedNumericKeypaths } from './response-transformer-allowed-numeric-values';
import { getBigIntUpcastResponseTransformer, getBigIntUpcastVisitor } from './response-transformer-bigint-upcast';
2 changes: 1 addition & 1 deletion packages/rpc-transformers/src/tree-traversal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RpcRequest, RpcRequestTransformer, RpcResponseTransformer } from '@solana/rpc-spec';
import { RpcRequest, RpcRequestTransformer, RpcResponseTransformer } from '@solana/rpc-spec-types';

export type KeyPathWildcard = { readonly __brand: unique symbol };
export type KeyPath = ReadonlyArray<KeyPath | KeyPathWildcard | number | string>;
12 changes: 8 additions & 4 deletions packages/rpc-transport-http/README.md
Original file line number Diff line number Diff line change
@@ -127,7 +127,8 @@ Using this core transport, you can implement specialized functionality for lever
Here’s an example of how someone might implement a “round robin” approach to distribute requests to multiple transports:

```ts
import { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import { RpcTransport } from '@solana/rpc-spec';
import { RpcResponse } from '@solana/rpc-spec-types';
import { createHttpTransport } from '@solana/rpc-transport-http';

// Create a transport for each RPC server
@@ -153,7 +154,8 @@ Another example of a possible customization for a transport is to shard requests
Perhaps your application needs to make a large number of requests, or needs to fan request for different methods out to different servers. Here’s an example of an implementation that does the latter:

```ts
import { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import { RpcTransport } from '@solana/rpc-spec';
import { RpcResponse } from '@solana/rpc-spec-types';
import { createHttpTransport } from '@solana/rpc-transport-http';

// Create multiple transports
@@ -190,7 +192,8 @@ async function shardingTransport<TResponse>(...args: Parameters<RpcTransport>):
The transport library can also be used to implement custom retry logic on any request:

```ts
import { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import { RpcTransport } from '@solana/rpc-spec';
import { RpcResponse } from '@solana/rpc-spec-types';
import { createHttpTransport } from '@solana/rpc-transport-http';

// Set the maximum number of attempts to retry a request
@@ -234,7 +237,8 @@ async function retryingTransport<TResponse>(...args: Parameters<RpcTransport>):
Here’s an example of some failover logic integrated into a transport:

```ts
import { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import { RpcTransport } from '@solana/rpc-spec';
import { RpcResponse } from '@solana/rpc-spec-types';
import { createHttpTransport } from '@solana/rpc-transport-http';

// Create a transport for each RPC server
1 change: 1 addition & 0 deletions packages/rpc-transport-http/package.json
Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@
"dependencies": {
"@solana/errors": "workspace:*",
"@solana/rpc-spec": "workspace:*",
"@solana/rpc-spec-types": "workspace:*",
"undici-types": "^6.20.0"
},
"devDependencies": {
3 changes: 2 additions & 1 deletion packages/rpc-transport-http/src/http-transport.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';
import { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import type { RpcTransport } from '@solana/rpc-spec';
import type { RpcResponse } from '@solana/rpc-spec-types';
import type Dispatcher from 'undici-types/dispatcher';

import {
1 change: 1 addition & 0 deletions packages/rpc/package.json
Original file line number Diff line number Diff line change
@@ -76,6 +76,7 @@
"@solana/functional": "workspace:*",
"@solana/rpc-api": "workspace:*",
"@solana/rpc-spec": "workspace:*",
"@solana/rpc-spec-types": "workspace:*",
"@solana/rpc-transformers": "workspace:*",
"@solana/rpc-transport-http": "workspace:*",
"@solana/rpc-types": "workspace:*"
3 changes: 2 additions & 1 deletion packages/rpc/src/__tests__/rpc-request-coalescer-test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import type { RpcTransport } from '@solana/rpc-spec';
import type { RpcResponse } from '@solana/rpc-spec-types';

import { getRpcTransportWithRequestCoalescing } from '../rpc-request-coalescer';

3 changes: 2 additions & 1 deletion packages/rpc/src/rpc-request-coalescer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { RpcResponse, RpcTransport } from '@solana/rpc-spec';
import type { RpcTransport } from '@solana/rpc-spec';
import type { RpcResponse } from '@solana/rpc-spec-types';

type CoalescedRequest = {
readonly abortController: AbortController;
13 changes: 11 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3c02c35

Please sign in to comment.