@solana/kit
Version:
Solana Javascript API
349 lines (341 loc) • 12.7 kB
JavaScript
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