Created
August 14, 2024 19:50
-
-
Save rubpy/964ab7866d767f046b205e0de64b69f7 to your computer and use it in GitHub Desktop.
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
import type { | |
Commitment, | |
TransactionForAccounts, | |
TransactionForFullBase58, | |
TransactionForFullBase64, | |
TransactionForFullJsonParsed, | |
} from '@solana/rpc-types'; | |
import type { TransactionVersion } from '@solana/transaction-messages'; | |
import type { Address } from '@solana/addresses'; | |
import type { Signature } from '@solana/keys'; | |
import { | |
type AllowedNumericKeypaths, | |
type ParamsTransformerConfig, | |
getDefaultParamsTransformerForSolanaRpc, | |
getDefaultResponseTransformerForSolanaRpc, | |
jsonParsedAccountsConfigs, | |
KEYPATH_WILDCARD, | |
} from '@solana/rpc-transformers'; | |
import { | |
AccountNotificationsApi, | |
} from '@solana/rpc-subscriptions-api'; | |
import { | |
type RpcSubscriptionsApiMethods, | |
type RpcSubscriptionsApi, | |
createRpcSubscriptionsApi, | |
} from '@solana/rpc-subscriptions-spec'; | |
// ----------------------------------------------------------------------------- | |
// Subscription notification types | |
export type TransactionNotificationsNotificationBase = Readonly<{ | |
signature: Signature; | |
}>; | |
export type TransactionNotificationsFilter = { | |
vote?: boolean; | |
failed?: boolean; | |
signature?: Signature[]; | |
accountInclude?: Address[]; | |
accountExclude?: Address[]; | |
accountRequired?: Address[]; | |
}; | |
export type TransactionNotificationsCommonOptions = Readonly<{ | |
commitment?: Commitment; | |
showRewards?: boolean; | |
}>; | |
export type TransactionNotificationsEncoding = 'base58' | 'base64' | 'jsonParsed'; | |
export type TransactionNotificationsMaxSupportedTransactionVersion = Exclude<TransactionVersion, 'legacy'>; | |
export type TransactionNotificationsTransactionDetails = 'full' | 'signatures' | 'accounts' | 'none'; | |
export interface TransactionNotificationsApi extends RpcSubscriptionsApiMethods { | |
// transactionDetails=full (default), encoding=jsonParsed, maxSupportedTransactionVersion=0 | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'jsonParsed'; | |
maxSupportedTransactionVersion: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullJsonParsed<TransactionNotificationsMaxSupportedTransactionVersion>; | |
}>; | |
// transactionDetails=full (default), encoding=jsonParsed, maxSupportedTransactionVersion=missing | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'jsonParsed'; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullJsonParsed<void>; | |
}>; | |
// transactionDetails=full (default), encoding=base64, maxSupportedTransactionVersion=0 | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'base64'; | |
maxSupportedTransactionVersion: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullBase64<TransactionNotificationsMaxSupportedTransactionVersion>; | |
}>; | |
// transactionDetails=full (default), encoding=base64, maxSupportedTransactionVersion=missing | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'base64'; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullBase64<void>; | |
}>; | |
// transactionDetails=full (default), encoding=base58, maxSupportedTransactionVersion=0 | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'base58'; | |
maxSupportedTransactionVersion: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullBase58<TransactionNotificationsMaxSupportedTransactionVersion>; | |
}>; | |
// transactionDetails=full (default), encoding=base58, maxSupportedTransactionVersion=missing | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: 'base58'; | |
transactionDetails?: 'full'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForFullBase58<void>; | |
}>; | |
// transactionDetails=signatures, encoding + maxSupportedTransactionVersion irrelevant | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: TransactionNotificationsEncoding; | |
maxSupportedTransactionVersion?: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails: 'signatures'; | |
}>, | |
): TransactionNotificationsNotificationBase; | |
// transactionDetails=none, encoding + maxSupportedTransactionVersion irrelevant | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: TransactionNotificationsEncoding; | |
maxSupportedTransactionVersion?: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails: 'none'; | |
}>, | |
): TransactionNotificationsNotificationBase; | |
// transactionDetails=accounts, maxSupportedTransactionVersion=0, encoding irrelevant | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: TransactionNotificationsEncoding; | |
maxSupportedTransactionVersion: TransactionNotificationsMaxSupportedTransactionVersion; | |
transactionDetails: 'accounts'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForAccounts<TransactionNotificationsMaxSupportedTransactionVersion>; | |
}>; | |
// transactionDetails=accounts, maxSupportedTransactionVersion=missing, encoding irrelevant | |
transactionNotifications( | |
filter: TransactionNotificationsFilter, | |
options: TransactionNotificationsCommonOptions & | |
Readonly<{ | |
encoding?: TransactionNotificationsEncoding; | |
transactionDetails: 'accounts'; | |
}>, | |
): TransactionNotificationsNotificationBase & | |
Readonly<{ | |
transaction: TransactionForAccounts<void>; | |
}>; | |
} | |
// ----------------------------------------------------------------------------- | |
type Config = ParamsTransformerConfig; | |
export type SolanaRpcEnhancedSubscriptionsApi = AccountNotificationsApi & TransactionNotificationsApi; | |
export function createSolanaRpcEnhancedSubscriptionsApi<TApi extends RpcSubscriptionsApiMethods = SolanaRpcEnhancedSubscriptionsApi>( | |
config?: Config, | |
): RpcSubscriptionsApi<TApi> { | |
return createSolanaRpcEnhancedSubscriptionsApi_INTERNAL<TApi>(config); | |
} | |
function createSolanaRpcEnhancedSubscriptionsApi_INTERNAL<TApi extends RpcSubscriptionsApiMethods>( | |
config?: Config, | |
): RpcSubscriptionsApi<TApi> { | |
return createRpcSubscriptionsApi<TApi>({ | |
parametersTransformer: getDefaultParamsTransformerForSolanaRpc(config) as (params: unknown[]) => unknown[], | |
responseTransformer: getDefaultResponseTransformerForSolanaRpc({ | |
allowedNumericKeyPaths: getAllowedNumericKeypaths(), | |
}), | |
subscribeNotificationNameTransformer: (notificationName: string) => | |
notificationName.replace(/Notifications$/, 'Subscribe'), | |
unsubscribeNotificationNameTransformer: (notificationName: string) => | |
notificationName.replace(/Notifications$/, 'Unsubscribe'), | |
}); | |
} | |
let memoizedKeypaths: AllowedNumericKeypaths< | |
RpcSubscriptionsApi<SolanaRpcEnhancedSubscriptionsApi> | |
>; | |
function getAllowedNumericKeypaths(): AllowedNumericKeypaths< | |
RpcSubscriptionsApi<SolanaRpcEnhancedSubscriptionsApi> | |
> { | |
if (!memoizedKeypaths) { | |
memoizedKeypaths = { | |
accountNotifications: jsonParsedAccountsConfigs.map(c => ['value', ...c]), | |
transactionNotifications: [ | |
[ | |
'transaction', | |
'meta', | |
'preTokenBalances', | |
KEYPATH_WILDCARD, | |
'accountIndex', | |
], | |
[ | |
'transaction', | |
'meta', | |
'preTokenBalances', | |
KEYPATH_WILDCARD, | |
'uiTokenAmount', | |
'decimals', | |
], | |
[ | |
'transaction', | |
'meta', | |
'postTokenBalances', | |
KEYPATH_WILDCARD, | |
'accountIndex', | |
], | |
[ | |
'transaction', | |
'meta', | |
'postTokenBalances', | |
KEYPATH_WILDCARD, | |
'uiTokenAmount', | |
'decimals', | |
], | |
[ | |
'transaction', | |
'meta', | |
'rewards', | |
KEYPATH_WILDCARD, | |
'commission', | |
], | |
[ | |
'transaction', | |
'meta', | |
'innerInstructions', | |
KEYPATH_WILDCARD, | |
'index', | |
], | |
[ | |
'transaction', | |
'meta', | |
'innerInstructions', | |
KEYPATH_WILDCARD, | |
'instructions', | |
KEYPATH_WILDCARD, | |
'programIdIndex', | |
], | |
[ | |
'transaction', | |
'meta', | |
'innerInstructions', | |
KEYPATH_WILDCARD, | |
'instructions', | |
KEYPATH_WILDCARD, | |
'accounts', | |
KEYPATH_WILDCARD, | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'addressTableLookups', | |
KEYPATH_WILDCARD, | |
'writableIndexes', | |
KEYPATH_WILDCARD, | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'addressTableLookups', | |
KEYPATH_WILDCARD, | |
'readonlyIndexes', | |
KEYPATH_WILDCARD, | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'instructions', | |
KEYPATH_WILDCARD, | |
'programIdIndex', | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'instructions', | |
KEYPATH_WILDCARD, | |
'accounts', | |
KEYPATH_WILDCARD, | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'header', | |
'numReadonlySignedAccounts', | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'header', | |
'numReadonlyUnsignedAccounts', | |
], | |
[ | |
'transaction', | |
'transaction', | |
'message', | |
'header', | |
'numRequiredSignatures', | |
], | |
], | |
}; | |
} | |
return memoizedKeypaths; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment