-
Notifications
You must be signed in to change notification settings - Fork 878
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(experimental): add
accountNotifications
websocket method (#1650)
- Loading branch information
1 parent
e0b865d
commit d9dcd1c
Showing
5 changed files
with
315 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
packages/rpc-core/src/rpc-subscriptions/__tests__/account-notifications-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Commitment } from '../../rpc-methods'; | ||
|
||
describe('accountNotifications', () => { | ||
([undefined, 'confirmed', 'finalized', 'processed'] as (Commitment | undefined)[]).forEach(commitment => { | ||
describe(`when called with \`${commitment}\` commitment`, () => { | ||
it.todo('produces account notifications'); | ||
}); | ||
}); | ||
|
||
describe('when called with base58 encoding', () => { | ||
it.todo('produces account notifications with annotated base58 encoding'); | ||
}); | ||
|
||
describe('when called with base64 encoding', () => { | ||
it.todo('produces account notifications with annotated base64 encoding'); | ||
}); | ||
|
||
describe('when called with base64+zstd encoding', () => { | ||
it.todo('produces account notifications with annotated base64+zstd encoding'); | ||
}); | ||
|
||
describe('when called with jsonParsed encoding', () => { | ||
describe('for an account without parse-able JSON data', () => { | ||
it.todo('produces account notifications as base64'); | ||
}); | ||
|
||
describe('for an account with parse-able JSON data', () => { | ||
it.todo('produces account notifications with parsed JSON data for AddressLookupTable account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for BpfLoaderUpgradeable account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Config validator account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Config stake account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Nonce account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for SPL Token mint account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for SPL Token token account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for SPL token multisig account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for SPL Token 22 mint account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Stake account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Sysvar rent account'); | ||
|
||
it.todo('produces account notifications with parsed JSON data for Vote account'); | ||
}); | ||
}); | ||
|
||
describe('when called with no encoding', () => { | ||
it.todo('produces account notifications with base58 data without an annotation'); | ||
}); | ||
}); |
158 changes: 158 additions & 0 deletions
158
packages/rpc-core/src/rpc-subscriptions/__typetests__/account-notifications-type-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* eslint-disable @typescript-eslint/ban-ts-comment */ | ||
|
||
import { Base58EncodedAddress } from '@solana/addresses'; | ||
import { PendingRpcSubscription, RpcSubscriptions } from '@solana/rpc-transport/dist/types/json-rpc-types'; | ||
|
||
import { LamportsUnsafeBeyond2Pow53Minus1 } from '../../lamports'; | ||
import { | ||
Base58EncodedBytes, | ||
Base58EncodedDataResponse, | ||
Base64EncodedDataResponse, | ||
Base64EncodedZStdCompressedDataResponse, | ||
RpcResponse, | ||
U64UnsafeBeyond2Pow53Minus1, | ||
} from '../../rpc-methods/common'; | ||
import { AccountNotificationsApi } from '../account-notifications'; | ||
|
||
async () => { | ||
const rpcSubscriptions = null as unknown as RpcSubscriptions<AccountNotificationsApi>; | ||
// See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json | ||
// data is 'test data' | ||
// Note: In type tests, it doesn't matter if the account is actually JSON-parseable | ||
const pubkey = | ||
'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Base58EncodedAddress<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>; | ||
|
||
type TNotificationBase = Readonly<{ | ||
executable: boolean; | ||
lamports: LamportsUnsafeBeyond2Pow53Minus1; | ||
owner: Base58EncodedAddress; | ||
rentEpoch: U64UnsafeBeyond2Pow53Minus1; | ||
}>; | ||
|
||
// No optional configs | ||
rpcSubscriptions.accountNotifications(pubkey) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedBytes; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedBytes; | ||
} | ||
> | ||
> | ||
>; | ||
// With optional configs | ||
rpcSubscriptions.accountNotifications(pubkey, { commitment: 'confirmed' }) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedBytes; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey, { commitment: 'confirmed' }) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedBytes; | ||
} | ||
> | ||
> | ||
>; | ||
// Base58 encoded data | ||
rpcSubscriptions.accountNotifications(pubkey, { encoding: 'base58' }) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedDataResponse; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey, { encoding: 'base58' }) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base58EncodedDataResponse; | ||
} | ||
> | ||
> | ||
>; | ||
// Base64 encoded data | ||
rpcSubscriptions.accountNotifications(pubkey, { encoding: 'base64' }) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base64EncodedDataResponse; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey, { encoding: 'base64' }) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base64EncodedDataResponse; | ||
} | ||
> | ||
> | ||
>; | ||
// Base64 + ZSTD encoded data | ||
rpcSubscriptions.accountNotifications(pubkey, { encoding: 'base64+zstd' }) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base64EncodedZStdCompressedDataResponse; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey, { encoding: 'base64+zstd' }) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: Base64EncodedZStdCompressedDataResponse; | ||
} | ||
> | ||
> | ||
>; | ||
// JSON parsed data | ||
rpcSubscriptions.accountNotifications(pubkey, { encoding: 'jsonParsed' }) satisfies PendingRpcSubscription< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: | ||
| Readonly<{ | ||
program: string; | ||
parsed: unknown; | ||
space: U64UnsafeBeyond2Pow53Minus1; | ||
}> | ||
| Base64EncodedDataResponse; | ||
} | ||
> | ||
>; | ||
rpcSubscriptions | ||
.accountNotifications(pubkey, { encoding: 'jsonParsed' }) | ||
.subscribe({ abortSignal: new AbortController().signal }) satisfies Promise< | ||
AsyncIterable< | ||
RpcResponse< | ||
TNotificationBase & { | ||
data: | ||
| Readonly<{ | ||
program: string; | ||
parsed: unknown; | ||
space: U64UnsafeBeyond2Pow53Minus1; | ||
}> | ||
| Base64EncodedDataResponse; | ||
} | ||
> | ||
> | ||
>; | ||
}; |
58 changes: 58 additions & 0 deletions
58
packages/rpc-core/src/rpc-subscriptions/account-notifications.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Base58EncodedAddress } from '@solana/addresses'; | ||
|
||
import { | ||
AccountInfoBase, | ||
AccountInfoWithBase58Bytes, | ||
AccountInfoWithBase58EncodedData, | ||
AccountInfoWithBase64EncodedData, | ||
AccountInfoWithBase64EncodedZStdCompressedData, | ||
AccountInfoWithJsonData, | ||
Commitment, | ||
RpcResponse, | ||
} from '../rpc-methods/common'; | ||
|
||
type AccountNotificationsApiCommonConfig = Readonly<{ | ||
commitment?: Commitment; | ||
}>; | ||
|
||
export interface AccountNotificationsApi { | ||
/** | ||
* Subscribe to an account to receive notifications when the lamports or data for | ||
* a given account public key changes. | ||
* | ||
* The notification format is the same as seen in the `getAccountInfo` RPC HTTP method. | ||
* @see https://docs.solana.com/api/websocket#getAccountInfo | ||
*/ | ||
accountNotifications( | ||
address: Base58EncodedAddress, | ||
config: AccountNotificationsApiCommonConfig & | ||
Readonly<{ | ||
encoding: 'base64'; | ||
}> | ||
): RpcResponse<AccountInfoBase & AccountInfoWithBase64EncodedData>; | ||
accountNotifications( | ||
address: Base58EncodedAddress, | ||
config: AccountNotificationsApiCommonConfig & | ||
Readonly<{ | ||
encoding: 'base64+zstd'; | ||
}> | ||
): RpcResponse<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>; | ||
accountNotifications( | ||
address: Base58EncodedAddress, | ||
config: AccountNotificationsApiCommonConfig & | ||
Readonly<{ | ||
encoding: 'jsonParsed'; | ||
}> | ||
): RpcResponse<AccountInfoBase & AccountInfoWithJsonData>; | ||
accountNotifications( | ||
address: Base58EncodedAddress, | ||
config: AccountNotificationsApiCommonConfig & | ||
Readonly<{ | ||
encoding: 'base58'; | ||
}> | ||
): RpcResponse<AccountInfoBase & AccountInfoWithBase58EncodedData>; | ||
accountNotifications( | ||
address: Base58EncodedAddress, | ||
config?: AccountNotificationsApiCommonConfig | ||
): RpcResponse<AccountInfoBase & AccountInfoWithBase58Bytes>; | ||
} |
Oops, something went wrong.