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

Commit

Permalink
Rename RpcResponse to RpcResponseData (#3145)
Browse files Browse the repository at this point in the history
The purpose of this PR stack is to refactor both the RPC and RPC Subscriptions packages such that they have better interfaces with their respective transports. In this first batch of PRs, we will start by focusing on the RPC packages whilst ensuring minimum changes on the RPC Subscriptions packages.

The end goal of this first part is to have the following interfaces for the RPC packages:

### RPC Shared Layer

```ts
type RpcRequest<TParams = unknown> = {
  readonly methodName: string;
  readonly params: TParams;
}

type RpcResponse<TResponse = unknown> = {
  readonly json: () => Promise<TResponse>;
  readonly text: () => Promise<string>;
}


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

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

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

### RPC Transport Layer

```ts
type RpcTransportRequest = {
  readonly payload: unknown;
  readonly signal?: AbortSignal;
}


type RpcTransport = {
  <TResponse>(
    request: RpcTransportRequest
  ): Promise<RpcResponse<TResponse>>;
}
```

### RPC API Layer

```ts
type RpcApi<TRpcMethods> = { ... }

type RpcApiConfig = {
  readonly requestTransformer?: RpcRequestTransformer;
  readonly responseTransformer?: RpcResponseTransformer;
}

type PendingRpcApiRequest<TResponse> = RpcRequest & {
    responseTransformer?: RpcResponseTransformerFor<TResponse>;
};
```

### RPC Layer

```ts
type PendingRpcRequest<TResponse> = {
  // Nothing changes here but the final send function returns the result of `response.json()`.
  send(options?: RpcSendOptions): Promise<TResponse>;
};
```

---

In the first two PRs of the stack, we start by cleaning up the type namespace to allow these new types to exist. First, we rename `RpcResponse` to `RpcResponseData`, since `RpcResponse` will be used to define a proper response interface that aligns all the RPC layers.
lorisleiva authored Sep 1, 2024

Verified

This commit was signed with the committer’s verified signature. The key has expired.
danielleadams Danielle Adams
1 parent 1193f5f commit 1c25dd4
Showing 6 changed files with 18 additions and 9 deletions.
8 changes: 8 additions & 0 deletions .changeset/gorgeous-foxes-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@solana/rpc-subscriptions-spec': patch
'@solana/rpc-spec-types': patch
'@solana/rpc-spec': patch
'@solana/rpc-api': patch
---

Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ describe('getStakeMinimumDelegation', () => {
});
(['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {
describe(`when called with \`${commitment}\` commitment`, () => {
it('returns the result as a bigint wrapped in an RpcResponse', async () => {
it('returns the result as a bigint wrapped in an RpcResponseData', async () => {
expect.assertions(1);
const result = await rpc.getStakeMinimumDelegation({ commitment }).send();
expect(result.value).toEqual(expect.any(BigInt));
2 changes: 1 addition & 1 deletion packages/rpc-api/src/__tests__/is-blockhash-valid-test.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ describe('isBlockhashValid', () => {
});
(['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {
describe(`when called with \`${commitment}\` commitment`, () => {
it('returns the result as a bool wrapped in an RpcResponse', async () => {
it('returns the result as a bool wrapped in an RpcResponseData', async () => {
expect.assertions(1);
const blockhash = '9PCVWkKP3bq1sT5eLFurUysMvVs4PxJsTfza5QSBB4d1' as Blockhash;
const result = await rpc.isBlockhashValid(blockhash, { commitment }).send();
5 changes: 3 additions & 2 deletions packages/rpc-spec-types/src/rpc-response.ts
Original file line number Diff line number Diff line change
@@ -2,10 +2,11 @@ interface IHasIdentifier {
readonly id: number;
}

type RpcErrorResponse = Readonly<{
type RpcErrorResponsePayload = Readonly<{
code: number;
data?: unknown;
message: string;
}>;

export type RpcResponse<TResponse> = IHasIdentifier & Readonly<{ error: RpcErrorResponse } | { result: TResponse }>;
export type RpcResponseData<TResponse> = IHasIdentifier &
Readonly<{ error: RpcErrorResponsePayload } | { result: TResponse }>;
4 changes: 2 additions & 2 deletions packages/rpc-spec/src/rpc.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import {
createRpcMessage,
Flatten,
OverloadImplementations,
RpcResponse,
RpcResponseData,
UnionToIntersection,
} from '@solana/rpc-spec-types';

@@ -69,7 +69,7 @@ function createPendingRpcRequest<TRpcMethods, TRpcTransport extends RpcTransport
async send(options?: RpcSendOptions): Promise<TResponse> {
const { methodName, params, responseTransformer } = pendingRequest;
const payload = createRpcMessage(methodName, params);
const response = await rpcConfig.transport<RpcResponse<unknown>>({
const response = await rpcConfig.transport<RpcResponseData<unknown>>({
payload,
signal: options?.abortSignal,
});
6 changes: 3 additions & 3 deletions packages/rpc-subscriptions-spec/src/rpc-subscriptions.ts
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {
createRpcMessage,
Flatten,
OverloadImplementations,
RpcResponse,
RpcResponseData,
UnionToIntersection,
} from '@solana/rpc-spec-types';

@@ -155,7 +155,7 @@ function createPendingRpcSubscription<
* STEP 2: Wait for the acknowledgement from the server with the subscription id.
*/
for await (const message of connection as AsyncIterable<
RpcNotification<unknown> | RpcResponse<RpcSubscriptionId>
RpcNotification<unknown> | RpcResponseData<RpcSubscriptionId>
>) {
if ('id' in message && message.id === subscribeMessage.id) {
if ('error' in message) {
@@ -175,7 +175,7 @@ function createPendingRpcSubscription<
return {
async *[Symbol.asyncIterator]() {
for await (const message of connection as AsyncIterable<
RpcNotification<unknown> | RpcResponse<RpcSubscriptionId>
RpcNotification<unknown> | RpcResponseData<RpcSubscriptionId>
>) {
if (!('params' in message) || message.params.subscription !== subscriptionId) {
continue;

0 comments on commit 1c25dd4

Please sign in to comment.