107 lines
3.1 KiB
Plaintext
107 lines
3.1 KiB
Plaintext
import {Connection, SignatureResult} from '../connection';
|
|
import {Transaction} from '../transaction';
|
|
import type {ConfirmOptions} from '../connection';
|
|
import type {Signer} from '../keypair';
|
|
import type {TransactionSignature} from '../transaction';
|
|
import {SendTransactionError} from '../errors';
|
|
|
|
/**
|
|
* Sign, send and confirm a transaction.
|
|
*
|
|
* If `commitment` option is not specified, defaults to 'max' commitment.
|
|
*
|
|
* @param {Connection} connection
|
|
* @param {Transaction} transaction
|
|
* @param {Array<Signer>} signers
|
|
* @param {ConfirmOptions} [options]
|
|
* @returns {Promise<TransactionSignature>}
|
|
*/
|
|
export async function sendAndConfirmTransaction(
|
|
connection: Connection,
|
|
transaction: Transaction,
|
|
signers: Array<Signer>,
|
|
options?: ConfirmOptions &
|
|
Readonly<{
|
|
// A signal that, when aborted, cancels any outstanding transaction confirmation operations
|
|
abortSignal?: AbortSignal;
|
|
}>,
|
|
): Promise<TransactionSignature> {
|
|
const sendOptions = options && {
|
|
skipPreflight: options.skipPreflight,
|
|
preflightCommitment: options.preflightCommitment || options.commitment,
|
|
maxRetries: options.maxRetries,
|
|
minContextSlot: options.minContextSlot,
|
|
};
|
|
|
|
const signature = await connection.sendTransaction(
|
|
transaction,
|
|
signers,
|
|
sendOptions,
|
|
);
|
|
|
|
let status: SignatureResult;
|
|
if (
|
|
transaction.recentBlockhash != null &&
|
|
transaction.lastValidBlockHeight != null
|
|
) {
|
|
status = (
|
|
await connection.confirmTransaction(
|
|
{
|
|
abortSignal: options?.abortSignal,
|
|
signature: signature,
|
|
blockhash: transaction.recentBlockhash,
|
|
lastValidBlockHeight: transaction.lastValidBlockHeight,
|
|
},
|
|
options && options.commitment,
|
|
)
|
|
).value;
|
|
} else if (
|
|
transaction.minNonceContextSlot != null &&
|
|
transaction.nonceInfo != null
|
|
) {
|
|
const {nonceInstruction} = transaction.nonceInfo;
|
|
const nonceAccountPubkey = nonceInstruction.keys[0].pubkey;
|
|
status = (
|
|
await connection.confirmTransaction(
|
|
{
|
|
abortSignal: options?.abortSignal,
|
|
minContextSlot: transaction.minNonceContextSlot,
|
|
nonceAccountPubkey,
|
|
nonceValue: transaction.nonceInfo.nonce,
|
|
signature,
|
|
},
|
|
options && options.commitment,
|
|
)
|
|
).value;
|
|
} else {
|
|
if (options?.abortSignal != null) {
|
|
console.warn(
|
|
'sendAndConfirmTransaction(): A transaction with a deprecated confirmation strategy was ' +
|
|
'supplied along with an `abortSignal`. Only transactions having `lastValidBlockHeight` ' +
|
|
'or a combination of `nonceInfo` and `minNonceContextSlot` are abortable.',
|
|
);
|
|
}
|
|
status = (
|
|
await connection.confirmTransaction(
|
|
signature,
|
|
options && options.commitment,
|
|
)
|
|
).value;
|
|
}
|
|
|
|
if (status.err) {
|
|
if (signature != null) {
|
|
throw new SendTransactionError({
|
|
action: 'send',
|
|
signature: signature,
|
|
transactionMessage: `Status: (${JSON.stringify(status)})`,
|
|
});
|
|
}
|
|
throw new Error(
|
|
`Transaction ${signature} failed (${JSON.stringify(status)})`,
|
|
);
|
|
}
|
|
|
|
return signature;
|
|
}
|