UNPKG

@solana/kit

Version:
349 lines (341 loc) 12.7 kB
import { fetchJsonParsedAccounts, assertAccountsDecoded, assertAccountsExist } from '@solana/accounts'; export * from '@solana/accounts'; export * from '@solana/addresses'; import { getU32Encoder } from '@solana/codecs'; export * from '@solana/codecs'; import { SolanaError, SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT, SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, isSolanaError } from '@solana/errors'; export * from '@solana/errors'; export * from '@solana/functional'; import { isInstructionForProgram, isInstructionWithData } from '@solana/instructions'; export * from '@solana/instructions'; export * from '@solana/keys'; export * from '@solana/programs'; export * from '@solana/rpc'; export * from '@solana/rpc-parsed-types'; export * from '@solana/rpc-subscriptions'; import { commitmentComparator } from '@solana/rpc-types'; export * from '@solana/rpc-types'; export * from '@solana/signers'; import { decompileTransactionMessage, isDurableNonceTransaction, isTransactionMessageWithBlockhashLifetime, setTransactionMessageLifetimeUsingBlockhash, appendTransactionMessageInstruction } from '@solana/transaction-messages'; export * from '@solana/transaction-messages'; import { compileTransaction, getBase64EncodedWireTransaction } from '@solana/transactions'; export * from '@solana/transactions'; import { createRecentSignatureConfirmationPromiseFactory, createNonceInvalidationPromiseFactory, createBlockHeightExceedencePromiseFactory, waitForRecentTransactionConfirmationUntilTimeout, getTimeoutPromise, waitForDurableNonceTransactionConfirmation, waitForRecentTransactionConfirmation } from '@solana/transaction-confirmation'; export { createRpcMessage } from '@solana/rpc-spec-types'; // src/index.ts // src/airdrop-internal.ts async function requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({ abortSignal, commitment, confirmSignatureOnlyTransaction, lamports, recipientAddress, rpc }) { const airdropTransactionSignature = await rpc.requestAirdrop(recipientAddress, lamports, { commitment }).send({ abortSignal }); await confirmSignatureOnlyTransaction({ abortSignal, commitment, signature: airdropTransactionSignature }); return airdropTransactionSignature; } // src/airdrop.ts function airdropFactory({ rpc, rpcSubscriptions }) { const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions }); async function confirmSignatureOnlyTransaction(config) { await waitForRecentTransactionConfirmationUntilTimeout({ ...config, getRecentSignatureConfirmationPromise, getTimeoutPromise }); } return async function airdrop(config) { return await requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({ ...config, confirmSignatureOnlyTransaction, rpc }); }; } var COMPUTE_BUDGET_PROGRAM_ADDRESS = "ComputeBudget111111111111111111111111111111"; var INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH = { blockhash: "11111111111111111111111111111111", lastValidBlockHeight: 0n // This is not included in compiled transactions; it can be anything. }; var SET_COMPUTE_UNIT_LIMIT_INSTRUCTION_INDEX = 2; function createComputeUnitLimitInstruction(units) { const data = new Uint8Array(5); data[0] = SET_COMPUTE_UNIT_LIMIT_INSTRUCTION_INDEX; getU32Encoder().write( units, data, 1 /* offset */ ); return Object.freeze({ data, programAddress: COMPUTE_BUDGET_PROGRAM_ADDRESS }); } function isSetComputeLimitInstruction(instruction) { return isInstructionForProgram(instruction, COMPUTE_BUDGET_PROGRAM_ADDRESS) && isInstructionWithData(instruction) && instruction.data[0] === SET_COMPUTE_UNIT_LIMIT_INSTRUCTION_INDEX; } async function getComputeUnitEstimateForTransactionMessage_INTERNAL_ONLY_DO_NOT_EXPORT({ abortSignal, rpc, transactionMessage, ...simulateConfig }) { const isDurableNonceTransactionMessage = isDurableNonceTransaction(transactionMessage); let compilableTransactionMessage; if (isDurableNonceTransactionMessage || isTransactionMessageWithBlockhashLifetime(transactionMessage)) { compilableTransactionMessage = transactionMessage; } else { compilableTransactionMessage = setTransactionMessageLifetimeUsingBlockhash( INVALID_BUT_SUFFICIENT_FOR_COMPILATION_BLOCKHASH, transactionMessage ); } const existingSetComputeUnitLimitInstructionIndex = transactionMessage.instructions.findIndex(isSetComputeLimitInstruction); const maxComputeUnitLimitInstruction = createComputeUnitLimitInstruction( 14e5 /* MAX_COMPUTE_UNIT_LIMIT */ ); if (existingSetComputeUnitLimitInstructionIndex === -1) { compilableTransactionMessage = appendTransactionMessageInstruction( maxComputeUnitLimitInstruction, compilableTransactionMessage ); } else { const nextInstructions = [...compilableTransactionMessage.instructions]; nextInstructions.splice(existingSetComputeUnitLimitInstructionIndex, 1, maxComputeUnitLimitInstruction); compilableTransactionMessage = Object.freeze({ ...compilableTransactionMessage, instructions: nextInstructions }); } const compiledTransaction = compileTransaction(compilableTransactionMessage); const wireTransactionBytes = getBase64EncodedWireTransaction(compiledTransaction); try { const { value: { err: transactionError, unitsConsumed } } = await rpc.simulateTransaction(wireTransactionBytes, { ...simulateConfig, encoding: "base64", replaceRecentBlockhash: !isDurableNonceTransactionMessage, sigVerify: false }).send({ abortSignal }); if (unitsConsumed == null) { throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT); } const downcastUnitsConsumed = unitsConsumed > 4294967295n ? 4294967295 : Number(unitsConsumed); if (transactionError) { throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, { cause: transactionError, unitsConsumed: downcastUnitsConsumed }); } return downcastUnitsConsumed; } catch (e) { if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT)) throw e; throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT, { cause: e }); } } // src/compute-limit.ts function getComputeUnitEstimateForTransactionMessageFactory({ rpc }) { return async function getComputeUnitEstimateForTransactionMessage(transactionMessage, config) { return await getComputeUnitEstimateForTransactionMessage_INTERNAL_ONLY_DO_NOT_EXPORT({ ...config, rpc, transactionMessage }); }; } async function fetchAddressesForLookupTables(lookupTableAddresses, rpc, config) { if (lookupTableAddresses.length === 0) { return {}; } const fetchedLookupTables = await fetchJsonParsedAccounts( rpc, lookupTableAddresses, config ); assertAccountsDecoded(fetchedLookupTables); assertAccountsExist(fetchedLookupTables); return fetchedLookupTables.reduce((acc, lookup) => { return { ...acc, [lookup.address]: lookup.data.addresses }; }, {}); } // src/decompile-transaction-message-fetching-lookup-tables.ts async function decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, config) { const lookupTables = "addressTableLookups" in compiledTransactionMessage && compiledTransactionMessage.addressTableLookups !== void 0 && compiledTransactionMessage.addressTableLookups.length > 0 ? compiledTransactionMessage.addressTableLookups : []; const lookupTableAddresses = lookupTables.map((l) => l.lookupTableAddress); const { lastValidBlockHeight, ...fetchAccountsConfig } = config ?? {}; const addressesByLookupTableAddress = lookupTableAddresses.length > 0 ? await fetchAddressesForLookupTables(lookupTableAddresses, rpc, fetchAccountsConfig) : {}; return decompileTransactionMessage(compiledTransactionMessage, { addressesByLookupTableAddress, lastValidBlockHeight }); } function getSendTransactionConfigWithAdjustedPreflightCommitment(commitment, config) { if ( // The developer has supplied no value for `preflightCommitment`. !config?.preflightCommitment && // The value of `commitment` is lower than the server default of `preflightCommitment`. commitmentComparator( commitment, "finalized" /* default value of `preflightCommitment` */ ) < 0 ) { return { ...config, // In the common case, it is unlikely that you want to simulate a transaction at // `finalized` commitment when your standard of commitment for confirming the // transaction is lower. Cap the simulation commitment level to the level of the // confirmation commitment. preflightCommitment: commitment }; } return config; } async function sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ abortSignal, commitment, rpc, transaction, ...sendTransactionConfig }) { const base64EncodedWireTransaction = getBase64EncodedWireTransaction(transaction); return await rpc.sendTransaction(base64EncodedWireTransaction, { ...getSendTransactionConfigWithAdjustedPreflightCommitment(commitment, sendTransactionConfig), encoding: "base64" }).send({ abortSignal }); } async function sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ abortSignal, commitment, confirmDurableNonceTransaction, rpc, transaction, ...sendTransactionConfig }) { const transactionSignature = await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ ...sendTransactionConfig, abortSignal, commitment, rpc, transaction }); await confirmDurableNonceTransaction({ abortSignal, commitment, transaction }); return transactionSignature; } async function sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({ abortSignal, commitment, confirmRecentTransaction, rpc, transaction, ...sendTransactionConfig }) { const transactionSignature = await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ ...sendTransactionConfig, abortSignal, commitment, rpc, transaction }); await confirmRecentTransaction({ abortSignal, commitment, transaction }); return transactionSignature; } // src/send-and-confirm-durable-nonce-transaction.ts function sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions }) { const getNonceInvalidationPromise = createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions }); const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions }); async function confirmDurableNonceTransaction(config) { await waitForDurableNonceTransactionConfirmation({ ...config, getNonceInvalidationPromise, getRecentSignatureConfirmationPromise }); } return async function sendAndConfirmDurableNonceTransaction(transaction, config) { await sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ ...config, confirmDurableNonceTransaction, rpc, transaction }); }; } function sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions }) { const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions }); const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions }); async function confirmRecentTransaction(config) { await waitForRecentTransactionConfirmation({ ...config, getBlockHeightExceedencePromise, getRecentSignatureConfirmationPromise }); } return async function sendAndConfirmTransaction(transaction, config) { await sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({ ...config, confirmRecentTransaction, rpc, transaction }); }; } // src/send-transaction-without-confirming.ts function sendTransactionWithoutConfirmingFactory({ rpc }) { return async function sendTransactionWithoutConfirming(transaction, config) { await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({ ...config, rpc, transaction }); }; } export { airdropFactory, decompileTransactionMessageFetchingLookupTables, fetchAddressesForLookupTables, getComputeUnitEstimateForTransactionMessageFactory, sendAndConfirmDurableNonceTransactionFactory, sendAndConfirmTransactionFactory, sendTransactionWithoutConfirmingFactory }; //# sourceMappingURL=index.browser.mjs.map //# sourceMappingURL=index.browser.mjs.map