diff --git a/packages/rpc-core/src/rpc-subscriptions/__tests__/root-notifications-test.ts b/packages/rpc-core/src/rpc-subscriptions/__tests__/root-notifications-test.ts new file mode 100644 index 00000000000..84a32de2820 --- /dev/null +++ b/packages/rpc-core/src/rpc-subscriptions/__tests__/root-notifications-test.ts @@ -0,0 +1,4 @@ +describe('rootNotifications', () => { + // TODO: A change in root takes too long to occur in order for our tests to pass. + it.todo('produces root notifications'); +}); diff --git a/packages/rpc-core/src/rpc-subscriptions/__typetests__/root-notifications-type-test.ts b/packages/rpc-core/src/rpc-subscriptions/__typetests__/root-notifications-type-test.ts new file mode 100644 index 00000000000..993e4ea16f4 --- /dev/null +++ b/packages/rpc-core/src/rpc-subscriptions/__typetests__/root-notifications-type-test.ts @@ -0,0 +1,19 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import { PendingRpcSubscription, RpcSubscriptions } from '@solana/rpc-transport/dist/types/json-rpc-types'; + +import { Slot } from '../../rpc-methods/common'; +import { RootNotificationsApi } from '../root-notifications'; + +async () => { + const rpcSubscriptions = null as unknown as RpcSubscriptions; + + type TNotification = Slot; + rpcSubscriptions.rootNotifications() satisfies PendingRpcSubscription; + rpcSubscriptions.rootNotifications().subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< + AsyncIterable + >; + + // @ts-expect-error Takes no params. + rpcSubscriptions.rootNotifications({ commitment: 'finalized' }); +}; diff --git a/packages/rpc-core/src/rpc-subscriptions/index.ts b/packages/rpc-core/src/rpc-subscriptions/index.ts index 9b7628200a3..d9ab944cdb9 100644 --- a/packages/rpc-core/src/rpc-subscriptions/index.ts +++ b/packages/rpc-core/src/rpc-subscriptions/index.ts @@ -2,6 +2,7 @@ import { IRpcSubscriptionsApi, RpcSubscription } from '@solana/rpc-transport/dis import { patchParamsForSolanaLabsRpc } from '../params-patcher'; import { patchResponseForSolanaLabsRpcSubscriptions } from '../response-patcher'; +import { RootNotificationsApi } from './root-notifications'; import { SlotNotificationsApi } from './slot-notifications'; import { SlotsUpdatesNotificationsApi } from './slots-updates-notifications'; @@ -9,7 +10,7 @@ type Config = Readonly<{ onIntegerOverflow?: (methodName: string, keyPath: (number | string)[], value: bigint) => void; }>; -export type SolanaRpcSubscriptions = SlotNotificationsApi; +export type SolanaRpcSubscriptions = RootNotificationsApi & SlotNotificationsApi; export type SolanaRpcSubscriptionsUnstable = SlotsUpdatesNotificationsApi; export function createSolanaRpcSubscriptionsApi( diff --git a/packages/rpc-core/src/rpc-subscriptions/root-notifications.ts b/packages/rpc-core/src/rpc-subscriptions/root-notifications.ts new file mode 100644 index 00000000000..bb732bd1349 --- /dev/null +++ b/packages/rpc-core/src/rpc-subscriptions/root-notifications.ts @@ -0,0 +1,13 @@ +import { Slot } from '../rpc-methods/common'; + +type RootNotificationsApiNotification = Slot; + +export interface RootNotificationsApi { + /** + * Subscribe to receive notification anytime a new root is set by the validator + */ + rootNotifications( + // FIXME: https://github.com/solana-labs/solana-web3.js/issues/1389 + NO_CONFIG?: Record + ): RootNotificationsApiNotification; +}