Skip to content

Commit

Permalink
refactor(experimental): add cluster level subscriptions API for library
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Jan 21, 2024
1 parent 0665804 commit ff8ee18
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 8 deletions.
94 changes: 94 additions & 0 deletions packages/library/src/__typetests__/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
RpcDevnet,
RpcMainnet,
RpcSubscriptions,
RpcSubscriptionsDevnet,
RpcSubscriptionsMainnet,
RpcSubscriptionsTestnet,
RpcTestnet,
} from '@solana/rpc-transport';

Expand Down Expand Up @@ -39,6 +42,8 @@ createSolanaRpc<'mainnet'>({ transport }) satisfies RpcTestnet<Omit<SolanaRpcMet

// Subscription type tests

// Checking stable vs unstable subscriptions

const configSubscriptions = null as unknown as Omit<Parameters<typeof createJsonSubscriptionRpc>[0], 'api'>;

createSolanaRpcSubscriptions(configSubscriptions) satisfies RpcSubscriptions<SolanaRpcSubscriptions>;
Expand All @@ -50,3 +55,92 @@ createSolanaRpcSubscriptions(configSubscriptions) satisfies RpcSubscriptions<
createSolanaRpcSubscriptions_UNSTABLE(configSubscriptions) satisfies RpcSubscriptions<
SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable
>;

// Checking cluster-level subscriptions API

const websocketTransport = null as unknown as Parameters<typeof createJsonSubscriptionRpc>[0]['transport'];

// No cluster specified should be generic `RpcSubscriptions`
createSolanaRpcSubscriptions({ transport: websocketTransport }) satisfies RpcSubscriptions<SolanaRpcSubscriptions>;

// Stable subscriptions

// When devnet is specified, should be `RpcSubscriptionsDevnet`
createSolanaRpcSubscriptions<'devnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'devnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a testnet RPC
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'devnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a mainnet RPC
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions>;

// When testnet is specified, should be `RpcSubscriptionsTestnet`
createSolanaRpcSubscriptions<'testnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'testnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a devnet RPC
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'testnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a mainnet RPC
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions>;

// When mainnet is specified, should be `RpcSubscriptionsMainnet`
createSolanaRpcSubscriptions<'mainnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'mainnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a devnet RPC
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions>;
createSolanaRpcSubscriptions<'mainnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a testnet RPC
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions>;

// Unstable subscriptions

// When devnet is specified, should be `RpcSubscriptionsDevnet`
createSolanaRpcSubscriptions_UNSTABLE<'devnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'devnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a testnet RPC
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'devnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a mainnet RPC
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;

// When testnet is specified, should be `RpcSubscriptionsTestnet`
createSolanaRpcSubscriptions_UNSTABLE<'testnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'testnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a devnet RPC
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'testnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a mainnet RPC
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;

// When mainnet is specified, should be `RpcSubscriptionsMainnet`
createSolanaRpcSubscriptions_UNSTABLE<'mainnet'>({
transport: websocketTransport,
}) satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'mainnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a devnet RPC
}) satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
createSolanaRpcSubscriptions_UNSTABLE<'mainnet'>({
transport: websocketTransport,
// @ts-expect-error Should not be a testnet RPC
}) satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
43 changes: 35 additions & 8 deletions packages/library/src/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import {
RpcDevnet,
RpcMainnet,
RpcSubscriptions,
RpcSubscriptionsDevnet,
RpcSubscriptionsMainnet,
RpcSubscriptionsTestnet,
RpcTestnet,
} from '@solana/rpc-transport';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down Expand Up @@ -53,27 +56,51 @@ export function createSolanaRpc<TCluster extends 'devnet' | 'testnet' | 'mainnet
: Rpc<SolanaRpcMethods>;
}

export function createSolanaRpcSubscriptions(
export function createSolanaRpcSubscriptions<TCluster extends 'devnet' | 'testnet' | 'mainnet' | void = void>(
config: Omit<Parameters<typeof createJsonSubscriptionRpc>[0], 'api'>,
): RpcSubscriptions<SolanaRpcSubscriptions> {
): TCluster extends 'devnet'
? RpcSubscriptionsDevnet<SolanaRpcSubscriptions>
: TCluster extends 'testnet'
? RpcSubscriptionsTestnet<SolanaRpcSubscriptions>
: TCluster extends 'mainnet'
? RpcSubscriptionsMainnet<SolanaRpcSubscriptions>
: RpcSubscriptions<SolanaRpcSubscriptions> {
return pipe(
createJsonSubscriptionRpc({
...config,
api: createSolanaRpcSubscriptionsApi(DEFAULT_RPC_CONFIG),
api: createSolanaRpcSubscriptionsApi<TCluster>(DEFAULT_RPC_CONFIG),
}),
rpcSubscriptions =>
getRpcSubscriptionsWithSubscriptionCoalescing({
getDeduplicationKey: (...args) => fastStableStringify(args),
rpcSubscriptions,
}),
);
) as TCluster extends 'devnet'
? RpcSubscriptionsDevnet<SolanaRpcSubscriptions>
: TCluster extends 'testnet'
? RpcSubscriptionsTestnet<SolanaRpcSubscriptions>
: TCluster extends 'mainnet'
? RpcSubscriptionsMainnet<SolanaRpcSubscriptions>
: RpcSubscriptions<SolanaRpcSubscriptions>;
}

export function createSolanaRpcSubscriptions_UNSTABLE(
export function createSolanaRpcSubscriptions_UNSTABLE<TCluster extends 'devnet' | 'testnet' | 'mainnet' | void = void>(
config: Omit<Parameters<typeof createJsonSubscriptionRpc>[0], 'api'>,
): RpcSubscriptions<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable> {
): TCluster extends 'devnet'
? RpcSubscriptionsDevnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: TCluster extends 'testnet'
? RpcSubscriptionsTestnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: TCluster extends 'mainnet'
? RpcSubscriptionsMainnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: RpcSubscriptions<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable> {
return createJsonSubscriptionRpc({
...config,
api: createSolanaRpcSubscriptionsApi_UNSTABLE(DEFAULT_RPC_CONFIG),
});
api: createSolanaRpcSubscriptionsApi_UNSTABLE<TCluster>(DEFAULT_RPC_CONFIG),
}) as TCluster extends 'devnet'
? RpcSubscriptionsDevnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: TCluster extends 'testnet'
? RpcSubscriptionsTestnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: TCluster extends 'mainnet'
? RpcSubscriptionsMainnet<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>
: RpcSubscriptions<SolanaRpcSubscriptions & SolanaRpcSubscriptionsUnstable>;
}

0 comments on commit ff8ee18

Please sign in to comment.