Skip to content

Commit 544cc84

Browse files
authored
refactor(experimental): the default transaction confirmation strategy (#1687)
# Summary This PR installs the conventional web3.js transaction confirmation strategy implementations. People who don't wish to customize them can create a confirmer according to the defaults, and can use it to confirm transactions. # Test Plan ``` cd packages/library pnpm test:unit:browser pnpm test:unit:node ``` Also, this integration test! ([link](https://gist.github.com/steveluscher/9244301b2f7fa3a1bd04308bfb0f0855)) ```js const { createSolanaRpc, createSolanaRpcSubscriptions, createDefaultRpcTransport, createDefaultRpcSubscriptionsTransport, createDefaultTransactionConfirmer, generateKeyPair, getAddressFromPublicKey, } = require('@solana/web3.js'); const { lamports } = require('@solana/rpc-core'); function synthesizeTransactionFromAirdrop(publicKey, signature) { return { feePayer: publicKey, lifetimeConstraint: { lastValidBlockHeight: 18446744073709551615n, }, signatures: { [publicKey]: signature, }, } } const COMMITMENT_LEVEL = 'finalized'; const LAMPORTS_TO_REQUEST = lamports(10000000n) // Configure your RPC. const rpc = createSolanaRpc({ transport: createDefaultRpcTransport({ url: 'http://127.0.0.1:8899' }) }); const rpcSubscriptions = createSolanaRpcSubscriptions({ transport: createDefaultRpcSubscriptionsTransport({ url: 'ws://127.0.0.1:8900' }), }); // Create a reusable transaction confirmer. const confirmTransaction = createDefaultTransactionConfirmer({ rpc, rpcSubscriptions }); // Create an account. console.log('Creating an account'); const keypair = await generateKeyPair(); const address = await getAddressFromPublicKey(keypair.publicKey); console.log('Created an account with address', address) // Request an airdrop. console.log('Requesting an airdrop of', LAMPORTS_TO_REQUEST, 'lamports') const signature = await rpc.requestAirdrop(address, LAMPORTS_TO_REQUEST).send(); console.log('Airdrop has signature', signature) // Confirm transaction. console.log('Confirming transaction with signature', signature, 'at', COMMITMENT_LEVEL, 'commitment'); await confirmTransaction({ abortSignal: new AbortController().signal, commitment: COMMITMENT_LEVEL, transaction: synthesizeTransactionFromAirdrop(address, signature), }); console.log('Confirmed!'); // Double check balance. console.log('Getting balance of', address) const {value} = await rpc.getBalance(address, {commitment: COMMITMENT_LEVEL}).send() console.log('Balance is now', value); ```
1 parent 6467eba commit 544cc84

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

packages/library/src/transaction-confirmation.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import type { Commitment } from '@solana/rpc-core';
2+
import type { GetAccountInfoApi } from '@solana/rpc-core/dist/types/rpc-methods/getAccountInfo';
3+
import type { GetSignatureStatusesApi } from '@solana/rpc-core/dist/types/rpc-methods/getSignatureStatuses';
4+
import type { AccountNotificationsApi } from '@solana/rpc-core/dist/types/rpc-subscriptions/account-notifications';
5+
import type { SignatureNotificationsApi } from '@solana/rpc-core/dist/types/rpc-subscriptions/signature-notifications';
6+
import type { SlotNotificationsApi } from '@solana/rpc-core/dist/types/rpc-subscriptions/slot-notifications';
7+
import type { Rpc, RpcSubscriptions } from '@solana/rpc-transport/dist/types/json-rpc-types';
28
import {
39
getSignatureFromTransaction,
410
IDurableNonceTransaction,
@@ -18,6 +24,16 @@ interface BaseConfig {
1824
transaction: ITransactionWithFeePayer & ITransactionWithSignatures;
1925
}
2026

27+
interface DefaultDurableNonceTransactionConfirmerConfig {
28+
rpc: Rpc<GetSignatureStatusesApi & GetAccountInfoApi>;
29+
rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi & SignatureNotificationsApi>;
30+
}
31+
32+
interface DefaultTransactionConfirmerConfig {
33+
rpc: Rpc<GetSignatureStatusesApi>;
34+
rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi & SlotNotificationsApi>;
35+
}
36+
2137
interface WaitForTransactionWithBlockhashLifetimeConfirmationConfig extends BaseConfig {
2238
getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;
2339
transaction: ITransactionWithFeePayer & ITransactionWithSignatures & ITransactionWithBlockhashLifetime;
@@ -58,6 +74,43 @@ async function raceStrategies<TConfig extends BaseConfig>(
5874
}
5975
}
6076

77+
export function createDefaultDurableNonceTransactionConfirmer({
78+
rpc,
79+
rpcSubscriptions,
80+
}: DefaultDurableNonceTransactionConfirmerConfig) {
81+
const getNonceInvalidationPromise = createNonceInvalidationPromiseFactory(rpc, rpcSubscriptions);
82+
const getSignatureConfirmationPromise = createSignatureConfirmationPromiseFactory(rpc, rpcSubscriptions);
83+
return async function confirmTransaction(
84+
config: Omit<
85+
Parameters<typeof waitForDurableNonceTransactionConfirmation>[0],
86+
'getNonceInvalidationPromise' | 'getSignatureConfirmationPromise'
87+
>
88+
) {
89+
await waitForDurableNonceTransactionConfirmation({
90+
...config,
91+
getNonceInvalidationPromise,
92+
getSignatureConfirmationPromise,
93+
});
94+
};
95+
}
96+
97+
export function createDefaultTransactionConfirmer({ rpc, rpcSubscriptions }: DefaultTransactionConfirmerConfig) {
98+
const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory(rpcSubscriptions);
99+
const getSignatureConfirmationPromise = createSignatureConfirmationPromiseFactory(rpc, rpcSubscriptions);
100+
return async function confirmTransaction(
101+
config: Omit<
102+
Parameters<typeof waitForTransactionConfirmation>[0],
103+
'getBlockHeightExceedencePromise' | 'getSignatureConfirmationPromise'
104+
>
105+
) {
106+
await waitForTransactionConfirmation({
107+
...config,
108+
getBlockHeightExceedencePromise,
109+
getSignatureConfirmationPromise,
110+
});
111+
};
112+
}
113+
61114
export async function waitForDurableNonceTransactionConfirmation(
62115
config: WaitForDurableNonceTransactionConfirmationConfig
63116
): Promise<void> {

0 commit comments

Comments
 (0)