@solana/transactions 5.1.0-experimental-20251205104522 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/lifetime.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/sendable-transaction.ts","../src/transaction-message-size.ts"],"names":["getBytesEncoder","SolanaError","SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\n/**\n * Returns an encoder that you can use to encode a {@link Transaction} to a byte array in a wire\n * format appropriate for sending to the Solana network for execution.\n */\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\n ]);\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana transaction wire format\n * to a {@link Transaction} object.\n *\n * @example\n * ```ts\n * import { getTransactionDecoder } from '@solana/transactions';\n *\n * const transactionDecoder = getTransactionDecoder();\n * const transaction = transactionDecoder.decode(wireTransactionBytes);\n * for (const [address, signature] in Object.entries(transaction.signatures)) {\n * console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\n\nexport function getTransactionDecoder(): VariableSizeDecoder<Transaction> {\n return transformDecoder(\n getStructDecoder([\n ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getShortU16Decoder() })],\n ['messageBytes', getBytesDecoder()],\n ]),\n decodePartiallyDecodedTransaction,\n );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Transaction}\n *\n * @see {@link getTransactionDecoder}\n * @see {@link getTransactionEncoder}\n */\nexport function getTransactionCodec(): VariableSizeCodec<Transaction> {\n return combineCodec(getTransactionEncoder(), getTransactionDecoder());\n}\n\ntype PartiallyDecodedTransaction = {\n messageBytes: ReadonlyUint8Array;\n signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedTransaction(transaction: PartiallyDecodedTransaction): Transaction {\n const { messageBytes, signatures } = transaction;\n\n /*\n Relevant message structure is at the start:\n - transaction version (0 bytes for legacy transactions, 1 byte for versioned transactions)\n - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n - `numReadOnlySignedAccounts` (1 byte, not used here)\n - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n - static addresses, with signers first. This is an array of addresses, prefixed with a short-u16 length\n */\n\n const signerAddressesDecoder = getTupleDecoder([\n // read transaction version\n getTransactionVersionDecoder(),\n // read first byte of header, `numSignerAccounts`\n // padRight to skip the next 2 bytes, `numReadOnlySignedAccounts` and `numReadOnlyUnsignedAccounts` which we don't need\n padRightDecoder(getU8Decoder(), 2),\n // read static addresses\n getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() }),\n ]);\n const [_txVersion, numRequiredSignatures, staticAddresses] = signerAddressesDecoder.decode(messageBytes);\n\n const signerAddresses = staticAddresses.slice(0, numRequiredSignatures);\n\n // signer addresses and signatures must be the same length\n // we encode an all-zero signature when the signature is missing\n if (signerAddresses.length !== signatures.length) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n numRequiredSignatures,\n signaturesLength: signatures.length,\n signerAddresses,\n });\n }\n\n // combine the signer addresses + signatures into the signatures map\n const signaturesMap: SignaturesMap = {};\n signerAddresses.forEach((address, index) => {\n const signatureForAddress = signatures[index];\n if (signatureForAddress.every(b => b === 0)) {\n signaturesMap[address] = null;\n } else {\n signaturesMap[address] = signatureForAddress as SignatureBytes;\n }\n });\n\n return {\n messageBytes: messageBytes as TransactionMessageBytes,\n signatures: Object.freeze(signaturesMap),\n };\n}\n","import { type Address, isAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n SolanaError,\n} from '@solana/errors';\nimport { type Blockhash, isBlockhash, type Slot } from '@solana/rpc-types';\nimport type {\n CompiledTransactionMessage,\n CompiledTransactionMessageWithLifetime,\n Nonce,\n TransactionMessage,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport type { Transaction } from './transaction';\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network. The transaction will continue to be eligible to land until the network considers the\n * `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type TransactionBlockhashLifetime = {\n /**\n * A recent blockhash observed by the transaction proposer.\n *\n * The transaction will be considered eligible to land until the network determines this\n * blockhash to be too old, or has switched to a fork where it is not present.\n */\n blockhash: Blockhash;\n /**\n * This is the block height beyond which the network will consider the blockhash to be too old\n * to make a transaction eligible to land.\n */\n lastValidBlockHeight: Slot;\n};\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionDurableNonceLifetime = {\n /**\n * A value contained in the account with address `nonceAccountAddress` at the time the\n * transaction was prepared.\n *\n * The transaction will be considered eligible to land until the nonce account ceases to exist\n * or contain this value.\n */\n nonce: Nonce;\n /** The account that contains the `nonce` value */\n nonceAccountAddress: Address;\n};\n\n/**\n * A transaction whose ability to land on the network is determined by some evanescent criteria.\n *\n * This describes a window of time after which a transaction is constructed and before which it will\n * no longer be accepted by the network.\n *\n * No transaction can land on Solana without having a `lifetimeConstraint` set.\n */\nexport type TransactionWithLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime | TransactionDurableNonceLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by the age of a blockhash observed on the network.\n *\n * The transaction will continue to be eligible to land until the network considers the `blockhash`\n * to be expired.\n */\nexport type TransactionWithBlockhashLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by a nonce.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionWithDurableNonceLifetime = {\n readonly lifetimeConstraint: TransactionDurableNonceLifetime;\n};\n\n/**\n * Helper type that sets the lifetime constraint of a transaction to be the same as the\n * lifetime constraint of the provided transaction message.\n *\n * If the transaction message has no explicit lifetime constraint, neither will the transaction.\n */\nexport type SetTransactionLifetimeFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends { lifetimeConstraint: unknown }\n ? TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithBlockhashLifetime['lifetimeConstraint']\n ? TransactionWithBlockhashLifetime & TTransaction\n : TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithDurableNonceLifetime['lifetimeConstraint']\n ? TransactionWithDurableNonceLifetime & TTransaction\n : TransactionWithLifetime & TTransaction\n : TTransaction;\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\n\nfunction compiledInstructionIsAdvanceNonceInstruction(\n instruction: CompiledTransactionMessage['instructions'][number],\n staticAddresses: Address[],\n): instruction is typeof instruction & { accountIndices: [number, number, number] } {\n return (\n staticAddresses[instruction.programAddressIndex] === SYSTEM_PROGRAM_ADDRESS &&\n // Test for `AdvanceNonceAccount` instruction data\n instruction.data != null &&\n isAdvanceNonceAccountInstructionData(instruction.data) &&\n // Test for exactly 3 accounts\n instruction.accountIndices?.length === 3\n );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): boolean {\n // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n\n/**\n * Get the lifetime constraint for a transaction from a compiled transaction message that includes a lifetime token.\n * @param compiledTransactionMessage A compiled transaction message that includes a lifetime token\n * @returns A lifetime constraint for the transaction\n * Note that this is less precise than checking a decompiled instruction, as we can't inspect\n * the address or role of input accounts (which may be in lookup tables). However, this is\n * sufficient for all valid advance durable nonce instructions.\n * Note that the program address must not be in a lookup table, see [this answer on StackExchange](https://solana.stackexchange.com/a/16224/289)\n * @see {@link isAdvanceNonceAccountInstruction}\n * Note that this function is async to allow for future implementations that may fetch `lastValidBlockHeight` using an RPC\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n): Promise<TransactionBlockhashLifetime | TransactionDurableNonceLifetime> {\n const firstInstruction = compiledTransactionMessage.instructions[0];\n const { staticAccounts } = compiledTransactionMessage;\n\n // We need to check if the first instruction is an AdvanceNonceAccount instruction\n if (firstInstruction && compiledInstructionIsAdvanceNonceInstruction(firstInstruction, staticAccounts)) {\n const nonceAccountAddress = staticAccounts[firstInstruction.accountIndices[0]];\n if (!nonceAccountAddress) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n nonce: compiledTransactionMessage.lifetimeToken,\n });\n }\n return {\n nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n nonceAccountAddress,\n };\n } else {\n return {\n blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n // This is not known from the compiled message, so we set it to the maximum possible value\n lastValidBlockHeight: 0xffffffffffffffffn,\n };\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * if (isTransactionWithBlockhashLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a `TransactionWithBlockhashLifetime`.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * setBlockhashIsValid(blockhashIsValid);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithBlockhashLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'blockhash' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.blockhash === 'string' &&\n typeof transaction.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n isBlockhash(transaction.lifetimeConstraint.blockhash)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * blockhash-based lifetime, from for example a wallet. Use this function to\n * assert that such a transaction actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithBlockhashLifetime`.\n * assertIsTransactionWithBlockhashLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithBlockhashLifetime` that can be used\n * // with the RPC.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n * // `transaction` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithBlockhashLifetime {\n if (!isTransactionWithBlockhashLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithDurableNonceLifetime } from '@solana/transactions';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionWithDurableNonceLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a\n * // `TransactionWithDurableNonceLifetime`.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * setNonceIsValid(nonce === actualNonce);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithDurableNonceLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'nonce' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.nonce === 'string' &&\n typeof transaction.lifetimeConstraint.nonceAccountAddress === 'string' &&\n isAddress(transaction.lifetimeConstraint.nonceAccountAddress)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * nonce-based lifetime, from for example a wallet. Use this function to assert\n * that such a transaction actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithDurableNonceLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithDurableNonceLifetime`.\n * assertIsTransactionWithDurableNonceLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithDurableNonceLifetime` that can be used\n * // with the RPC.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n * // `transaction` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithDurableNonceLifetime {\n if (!isTransactionWithDurableNonceLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n }\n}\n","import {\n BaseTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n isTransactionMessageWithDurableNonceLifetime,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type { SignaturesMap, TransactionFromTransactionMessage, TransactionMessageBytes } from './transaction';\n\n/**\n * Returns a {@link Transaction} object for a given {@link TransactionMessage}.\n *\n * This includes the compiled bytes of the transaction message, and a map of signatures. This map\n * will have a key for each address that is required to sign the transaction. The transaction will\n * not yet have signatures for any of these addresses.\n *\n * Whether a transaction message is ready to be compiled or not is enforced for you at the type\n * level. In order to be signable, a transaction message must:\n *\n * - have a version and a list of zero or more instructions (ie. conform to\n * {@link BaseTransactionMessage})\n * - have a fee payer set (ie. conform to {@link TransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction<TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromTransactionMessage<TTransactionMessage>>;\n\n const compiledMessage = compileTransactionMessage(transactionMessage);\n const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage) as TransactionMessageBytes;\n\n const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);\n const signatures: SignaturesMap = {};\n for (const signerAddress of transactionSigners) {\n signatures[signerAddress] = null;\n }\n\n let lifetimeConstraint: TransactionWithLifetime['lifetimeConstraint'] | undefined;\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else if (isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n ...(lifetimeConstraint ? { lifetimeConstraint } : undefined),\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { bytesEqual, Decoder } from '@solana/codecs-core';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { Signature, SignatureBytes, signBytes } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { Transaction } from './transaction';\n\n/**\n * Represents a transaction that is signed by all of its required signers. Being fully signed is a\n * prerequisite of functions designed to land transactions on the network.\n */\nexport type FullySignedTransaction = NominalType<'transactionSignedness', 'fullySigned'>;\n\nlet base58Decoder: Decoder<string> | undefined;\n\n/**\n * Given a transaction signed by its fee payer, this method will return the {@link Signature} that\n * uniquely identifies it. This string can be used to look up transactions at a later date, for\n * example on a Solana block explorer.\n *\n * @example\n * ```ts\n * import { getSignatureFromTransaction } from '@solana/transactions';\n *\n * const signature = getSignatureFromTransaction(tx);\n * console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n * ```\n */\nexport function getSignatureFromTransaction(transaction: Transaction): Signature {\n if (!base58Decoder) base58Decoder = getBase58Decoder();\n\n // We have ordered signatures from the compiled message accounts\n // first signature is the fee payer\n const signatureBytes = Object.values(transaction.signatures)[0];\n if (!signatureBytes) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n }\n const transactionSignature = base58Decoder.decode(signatureBytes);\n return transactionSignature as Signature;\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link Transaction}.\n *\n * Though the resulting transaction might have every signature it needs to land on the network, this\n * function will not assert that it does. A partially signed transaction cannot be landed on the\n * network, but can be serialized and deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignTransaction } from '@solana/transactions';\n *\n * const partiallySignedTransaction = await partiallySignTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link signTransaction} if you want to assert that the transaction has all of its required\n * signatures after signing.\n */\nexport async function partiallySignTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<TTransaction> {\n let newSignatures: Record<Address, SignatureBytes> | undefined;\n let unexpectedSigners: Set<Address> | undefined;\n\n await Promise.all(\n keyPairs.map(async keyPair => {\n const address = await getAddressFromPublicKey(keyPair.publicKey);\n const existingSignature = transaction.signatures[address];\n\n // Check if the address is expected to sign the transaction\n if (existingSignature === undefined) {\n // address is not an expected signer for this transaction\n unexpectedSigners ||= new Set();\n unexpectedSigners.add(address);\n return;\n }\n\n // Return if there are any unexpected signers already since we won't be using signatures\n if (unexpectedSigners) {\n return;\n }\n\n const newSignature = await signBytes(keyPair.privateKey, transaction.messageBytes);\n\n if (existingSignature !== null && bytesEqual(newSignature, existingSignature)) {\n // already have the same signature set\n return;\n }\n\n newSignatures ||= {};\n newSignatures[address] = newSignature;\n }),\n );\n\n if (unexpectedSigners && unexpectedSigners.size > 0) {\n const expectedSigners = Object.keys(transaction.signatures);\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n expectedAddresses: expectedSigners,\n unexpectedAddresses: [...unexpectedSigners],\n });\n }\n\n if (!newSignatures) {\n return transaction;\n }\n\n return Object.freeze({\n ...transaction,\n signatures: Object.freeze({\n ...transaction.signatures,\n ...newSignatures,\n }),\n });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link FullySignedTransaction}.\n *\n * This function will throw unless the resulting transaction is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signTransaction } from '@solana/transactions';\n *\n * const signedTransaction = await signTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link partiallySignTransaction} if you want to sign the transaction without asserting that\n * the resulting transaction is fully signed.\n */\nexport async function signTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<FullySignedTransaction & TTransaction> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertIsFullySignedTransaction(out);\n Object.freeze(out);\n return out;\n}\n\n/**\n * Checks whether a given {@link Transaction} is fully signed.\n *\n * @example\n * ```ts\n * import { isFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isFullySignedTransaction(transaction)) {\n * // At this point we know that the transaction is signed and can be sent to the network.\n * }\n * ```\n */\nexport function isFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is FullySignedTransaction & TTransaction {\n return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link Transaction}, that you expect to be fully signed,\n * from an untrusted network API or user input. Use this function to assert that such a transaction\n * is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `FullySignedTransaction`.\n * assertIsFullySignedTransaction(transaction);\n * // At this point we know that the transaction is signed and can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is FullySignedTransaction & TTransaction {\n const missingSigs: Address[] = [];\n Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {\n if (!signatureBytes) {\n missingSigs.push(address as Address);\n }\n });\n\n if (missingSigs.length > 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n addresses: missingSigs,\n });\n }\n}\n","import { getBase64Decoder } from '@solana/codecs-strings';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/** Represents the wire format of a transaction as a base64-encoded string. */\nexport type Base64EncodedWireTransaction = Brand<EncodedString<string, 'base64'>, 'Base64EncodedWireTransaction'>;\n\n/**\n * Given a signed transaction, this method returns the transaction as a string that conforms to the\n * {@link Base64EncodedWireTransaction} type.\n *\n * @example\n * ```ts\n * import { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n *\n * const serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n * const signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n * ```\n */\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { NominalType } from '@solana/nominal-types';\nimport type { BaseTransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/**\n * The maximum size of a transaction in bytes.\n */\nexport const TRANSACTION_SIZE_LIMIT = 4096;\n\n/**\n * Gets the size of a given transaction in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionSize(transaction);\n * ```\n */\nexport function getTransactionSize(transaction: Transaction): number {\n return getTransactionEncoder().getSizeFromValue(transaction);\n}\n\n/**\n * A type guard that checks if a transaction is within the size limit.\n */\nexport type TransactionWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that adds the `TransactionWithinSizeLimit` flag to\n * a transaction if and only if the provided transaction message\n * is also within the size limit.\n */\nexport type SetTransactionWithinSizeLimitFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends BaseTransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithinSizeLimit\n ? TransactionWithinSizeLimit & TTransaction\n : TTransaction;\n\n/**\n * Checks if a transaction is within the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * if (isTransactionWithinSizeLimit(transaction)) {\n * transaction satisfies TransactionWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is TransactionWithinSizeLimit & TTransaction {\n return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction is within the size limit.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction exceeds the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * assertIsTransactionWithinSizeLimit(transaction);\n * transaction satisfies TransactionWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is TransactionWithinSizeLimit & TTransaction {\n const transactionSize = getTransactionSize(transaction);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n","import { assertIsFullySignedTransaction, FullySignedTransaction, isFullySignedTransaction } from './signatures';\nimport { Transaction } from './transaction';\nimport {\n assertIsTransactionWithinSizeLimit,\n isTransactionWithinSizeLimit,\n TransactionWithinSizeLimit,\n} from './transaction-size';\n\n/**\n * Helper type that includes all transaction types required\n * for the transaction to be sent to the network.\n *\n * @see {@link isSendableTransaction}\n * @see {@link assertIsSendableTransaction}\n */\nexport type SendableTransaction = FullySignedTransaction & TransactionWithinSizeLimit;\n\n/**\n * Checks if a transaction has all the required\n * conditions to be sent to the network.\n *\n * @example\n * ```ts\n * import { isSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isSendableTransaction(transaction)) {\n * // At this point we know that the transaction can be sent to the network.\n * }\n * ```\n *\n * @see {@link assertIsSendableTransaction}\n */\nexport function isSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is SendableTransaction & TTransaction {\n return isFullySignedTransaction(transaction) && isTransactionWithinSizeLimit(transaction);\n}\n\n/**\n * Asserts that a given transaction has all the\n * required conditions to be sent to the network.\n *\n * From time to time you might acquire a {@link Transaction}\n * from an untrusted network API or user input and you are not sure\n * that it has all the required conditions to be sent to the network\n * — such as being fully signed and within the size limit.\n * This function can be used to assert that such a transaction\n * is in fact sendable.\n *\n * @example\n * ```ts\n * import { assertIsSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `SendableTransaction`.\n * assertIsSendableTransaction(transaction);\n * // At this point we know that the transaction can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n * setError(`Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is SendableTransaction & TTransaction {\n assertIsFullySignedTransaction(transaction);\n assertIsTransactionWithinSizeLimit(transaction);\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type {\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from './compile-transaction';\nimport { getTransactionSize, TRANSACTION_SIZE_LIMIT } from './transaction-size';\n\n/**\n * Gets the compiled transaction size of a given transaction message in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionMessageSize(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSize(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): number {\n return getTransactionSize(compileTransaction(transactionMessage));\n}\n\n/**\n * Checks if a transaction message is within the size limit\n * when compiled into a transaction.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction message is within the size limit\n * when compiled into a transaction.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction message exceeds the size limit.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): asserts transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n const transactionSize = getTransactionMessageSize(transactionMessage);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/lifetime.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/sendable-transaction.ts","../src/transaction-message-size.ts"],"names":["getBytesEncoder","SolanaError","SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\n/**\n * Returns an encoder that you can use to encode a {@link Transaction} to a byte array in a wire\n * format appropriate for sending to the Solana network for execution.\n */\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\n ]);\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana transaction wire format\n * to a {@link Transaction} object.\n *\n * @example\n * ```ts\n * import { getTransactionDecoder } from '@solana/transactions';\n *\n * const transactionDecoder = getTransactionDecoder();\n * const transaction = transactionDecoder.decode(wireTransactionBytes);\n * for (const [address, signature] in Object.entries(transaction.signatures)) {\n * console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\n\nexport function getTransactionDecoder(): VariableSizeDecoder<Transaction> {\n return transformDecoder(\n getStructDecoder([\n ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getShortU16Decoder() })],\n ['messageBytes', getBytesDecoder()],\n ]),\n decodePartiallyDecodedTransaction,\n );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Transaction}\n *\n * @see {@link getTransactionDecoder}\n * @see {@link getTransactionEncoder}\n */\nexport function getTransactionCodec(): VariableSizeCodec<Transaction> {\n return combineCodec(getTransactionEncoder(), getTransactionDecoder());\n}\n\ntype PartiallyDecodedTransaction = {\n messageBytes: ReadonlyUint8Array;\n signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedTransaction(transaction: PartiallyDecodedTransaction): Transaction {\n const { messageBytes, signatures } = transaction;\n\n /*\n Relevant message structure is at the start:\n - transaction version (0 bytes for legacy transactions, 1 byte for versioned transactions)\n - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n - `numReadOnlySignedAccounts` (1 byte, not used here)\n - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n - static addresses, with signers first. This is an array of addresses, prefixed with a short-u16 length\n */\n\n const signerAddressesDecoder = getTupleDecoder([\n // read transaction version\n getTransactionVersionDecoder(),\n // read first byte of header, `numSignerAccounts`\n // padRight to skip the next 2 bytes, `numReadOnlySignedAccounts` and `numReadOnlyUnsignedAccounts` which we don't need\n padRightDecoder(getU8Decoder(), 2),\n // read static addresses\n getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() }),\n ]);\n const [_txVersion, numRequiredSignatures, staticAddresses] = signerAddressesDecoder.decode(messageBytes);\n\n const signerAddresses = staticAddresses.slice(0, numRequiredSignatures);\n\n // signer addresses and signatures must be the same length\n // we encode an all-zero signature when the signature is missing\n if (signerAddresses.length !== signatures.length) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n numRequiredSignatures,\n signaturesLength: signatures.length,\n signerAddresses,\n });\n }\n\n // combine the signer addresses + signatures into the signatures map\n const signaturesMap: SignaturesMap = {};\n signerAddresses.forEach((address, index) => {\n const signatureForAddress = signatures[index];\n if (signatureForAddress.every(b => b === 0)) {\n signaturesMap[address] = null;\n } else {\n signaturesMap[address] = signatureForAddress as SignatureBytes;\n }\n });\n\n return {\n messageBytes: messageBytes as TransactionMessageBytes,\n signatures: Object.freeze(signaturesMap),\n };\n}\n","import { type Address, isAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n SolanaError,\n} from '@solana/errors';\nimport { type Blockhash, isBlockhash, type Slot } from '@solana/rpc-types';\nimport type {\n CompiledTransactionMessage,\n CompiledTransactionMessageWithLifetime,\n Nonce,\n TransactionMessage,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport type { Transaction } from './transaction';\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network. The transaction will continue to be eligible to land until the network considers the\n * `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type TransactionBlockhashLifetime = {\n /**\n * A recent blockhash observed by the transaction proposer.\n *\n * The transaction will be considered eligible to land until the network determines this\n * blockhash to be too old, or has switched to a fork where it is not present.\n */\n blockhash: Blockhash;\n /**\n * This is the block height beyond which the network will consider the blockhash to be too old\n * to make a transaction eligible to land.\n */\n lastValidBlockHeight: Slot;\n};\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionDurableNonceLifetime = {\n /**\n * A value contained in the account with address `nonceAccountAddress` at the time the\n * transaction was prepared.\n *\n * The transaction will be considered eligible to land until the nonce account ceases to exist\n * or contain this value.\n */\n nonce: Nonce;\n /** The account that contains the `nonce` value */\n nonceAccountAddress: Address;\n};\n\n/**\n * A transaction whose ability to land on the network is determined by some evanescent criteria.\n *\n * This describes a window of time after which a transaction is constructed and before which it will\n * no longer be accepted by the network.\n *\n * No transaction can land on Solana without having a `lifetimeConstraint` set.\n */\nexport type TransactionWithLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime | TransactionDurableNonceLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by the age of a blockhash observed on the network.\n *\n * The transaction will continue to be eligible to land until the network considers the `blockhash`\n * to be expired.\n */\nexport type TransactionWithBlockhashLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by a nonce.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionWithDurableNonceLifetime = {\n readonly lifetimeConstraint: TransactionDurableNonceLifetime;\n};\n\n/**\n * Helper type that sets the lifetime constraint of a transaction to be the same as the\n * lifetime constraint of the provided transaction message.\n *\n * If the transaction message has no explicit lifetime constraint, neither will the transaction.\n */\nexport type SetTransactionLifetimeFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends { lifetimeConstraint: unknown }\n ? TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithBlockhashLifetime['lifetimeConstraint']\n ? TransactionWithBlockhashLifetime & TTransaction\n : TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithDurableNonceLifetime['lifetimeConstraint']\n ? TransactionWithDurableNonceLifetime & TTransaction\n : TransactionWithLifetime & TTransaction\n : TTransaction;\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\n\nfunction compiledInstructionIsAdvanceNonceInstruction(\n instruction: CompiledTransactionMessage['instructions'][number],\n staticAddresses: Address[],\n): instruction is typeof instruction & { accountIndices: [number, number, number] } {\n return (\n staticAddresses[instruction.programAddressIndex] === SYSTEM_PROGRAM_ADDRESS &&\n // Test for `AdvanceNonceAccount` instruction data\n instruction.data != null &&\n isAdvanceNonceAccountInstructionData(instruction.data) &&\n // Test for exactly 3 accounts\n instruction.accountIndices?.length === 3\n );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): boolean {\n // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n\n/**\n * Get the lifetime constraint for a transaction from a compiled transaction message that includes a lifetime token.\n * @param compiledTransactionMessage A compiled transaction message that includes a lifetime token\n * @returns A lifetime constraint for the transaction\n * Note that this is less precise than checking a decompiled instruction, as we can't inspect\n * the address or role of input accounts (which may be in lookup tables). However, this is\n * sufficient for all valid advance durable nonce instructions.\n * Note that the program address must not be in a lookup table, see [this answer on StackExchange](https://solana.stackexchange.com/a/16224/289)\n * @see {@link isAdvanceNonceAccountInstruction}\n * Note that this function is async to allow for future implementations that may fetch `lastValidBlockHeight` using an RPC\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n): Promise<TransactionBlockhashLifetime | TransactionDurableNonceLifetime> {\n const firstInstruction = compiledTransactionMessage.instructions[0];\n const { staticAccounts } = compiledTransactionMessage;\n\n // We need to check if the first instruction is an AdvanceNonceAccount instruction\n if (firstInstruction && compiledInstructionIsAdvanceNonceInstruction(firstInstruction, staticAccounts)) {\n const nonceAccountAddress = staticAccounts[firstInstruction.accountIndices[0]];\n if (!nonceAccountAddress) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n nonce: compiledTransactionMessage.lifetimeToken,\n });\n }\n return {\n nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n nonceAccountAddress,\n };\n } else {\n return {\n blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n // This is not known from the compiled message, so we set it to the maximum possible value\n lastValidBlockHeight: 0xffffffffffffffffn,\n };\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * if (isTransactionWithBlockhashLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a `TransactionWithBlockhashLifetime`.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * setBlockhashIsValid(blockhashIsValid);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithBlockhashLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'blockhash' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.blockhash === 'string' &&\n typeof transaction.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n isBlockhash(transaction.lifetimeConstraint.blockhash)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * blockhash-based lifetime, from for example a wallet. Use this function to\n * assert that such a transaction actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithBlockhashLifetime`.\n * assertIsTransactionWithBlockhashLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithBlockhashLifetime` that can be used\n * // with the RPC.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n * // `transaction` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithBlockhashLifetime {\n if (!isTransactionWithBlockhashLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithDurableNonceLifetime } from '@solana/transactions';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionWithDurableNonceLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a\n * // `TransactionWithDurableNonceLifetime`.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * setNonceIsValid(nonce === actualNonce);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithDurableNonceLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'nonce' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.nonce === 'string' &&\n typeof transaction.lifetimeConstraint.nonceAccountAddress === 'string' &&\n isAddress(transaction.lifetimeConstraint.nonceAccountAddress)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * nonce-based lifetime, from for example a wallet. Use this function to assert\n * that such a transaction actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithDurableNonceLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithDurableNonceLifetime`.\n * assertIsTransactionWithDurableNonceLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithDurableNonceLifetime` that can be used\n * // with the RPC.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n * // `transaction` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithDurableNonceLifetime {\n if (!isTransactionWithDurableNonceLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n }\n}\n","import {\n BaseTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n isTransactionMessageWithDurableNonceLifetime,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type { SignaturesMap, TransactionFromTransactionMessage, TransactionMessageBytes } from './transaction';\n\n/**\n * Returns a {@link Transaction} object for a given {@link TransactionMessage}.\n *\n * This includes the compiled bytes of the transaction message, and a map of signatures. This map\n * will have a key for each address that is required to sign the transaction. The transaction will\n * not yet have signatures for any of these addresses.\n *\n * Whether a transaction message is ready to be compiled or not is enforced for you at the type\n * level. In order to be signable, a transaction message must:\n *\n * - have a version and a list of zero or more instructions (ie. conform to\n * {@link BaseTransactionMessage})\n * - have a fee payer set (ie. conform to {@link TransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction<TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromTransactionMessage<TTransactionMessage>>;\n\n const compiledMessage = compileTransactionMessage(transactionMessage);\n const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage) as TransactionMessageBytes;\n\n const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);\n const signatures: SignaturesMap = {};\n for (const signerAddress of transactionSigners) {\n signatures[signerAddress] = null;\n }\n\n let lifetimeConstraint: TransactionWithLifetime['lifetimeConstraint'] | undefined;\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else if (isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n ...(lifetimeConstraint ? { lifetimeConstraint } : undefined),\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { bytesEqual, Decoder } from '@solana/codecs-core';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { Signature, SignatureBytes, signBytes } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { Transaction } from './transaction';\n\n/**\n * Represents a transaction that is signed by all of its required signers. Being fully signed is a\n * prerequisite of functions designed to land transactions on the network.\n */\nexport type FullySignedTransaction = NominalType<'transactionSignedness', 'fullySigned'>;\n\nlet base58Decoder: Decoder<string> | undefined;\n\n/**\n * Given a transaction signed by its fee payer, this method will return the {@link Signature} that\n * uniquely identifies it. This string can be used to look up transactions at a later date, for\n * example on a Solana block explorer.\n *\n * @example\n * ```ts\n * import { getSignatureFromTransaction } from '@solana/transactions';\n *\n * const signature = getSignatureFromTransaction(tx);\n * console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n * ```\n */\nexport function getSignatureFromTransaction(transaction: Transaction): Signature {\n if (!base58Decoder) base58Decoder = getBase58Decoder();\n\n // We have ordered signatures from the compiled message accounts\n // first signature is the fee payer\n const signatureBytes = Object.values(transaction.signatures)[0];\n if (!signatureBytes) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n }\n const transactionSignature = base58Decoder.decode(signatureBytes);\n return transactionSignature as Signature;\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link Transaction}.\n *\n * Though the resulting transaction might have every signature it needs to land on the network, this\n * function will not assert that it does. A partially signed transaction cannot be landed on the\n * network, but can be serialized and deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignTransaction } from '@solana/transactions';\n *\n * const partiallySignedTransaction = await partiallySignTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link signTransaction} if you want to assert that the transaction has all of its required\n * signatures after signing.\n */\nexport async function partiallySignTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<TTransaction> {\n let newSignatures: Record<Address, SignatureBytes> | undefined;\n let unexpectedSigners: Set<Address> | undefined;\n\n await Promise.all(\n keyPairs.map(async keyPair => {\n const address = await getAddressFromPublicKey(keyPair.publicKey);\n const existingSignature = transaction.signatures[address];\n\n // Check if the address is expected to sign the transaction\n if (existingSignature === undefined) {\n // address is not an expected signer for this transaction\n unexpectedSigners ||= new Set();\n unexpectedSigners.add(address);\n return;\n }\n\n // Return if there are any unexpected signers already since we won't be using signatures\n if (unexpectedSigners) {\n return;\n }\n\n const newSignature = await signBytes(keyPair.privateKey, transaction.messageBytes);\n\n if (existingSignature !== null && bytesEqual(newSignature, existingSignature)) {\n // already have the same signature set\n return;\n }\n\n newSignatures ||= {};\n newSignatures[address] = newSignature;\n }),\n );\n\n if (unexpectedSigners && unexpectedSigners.size > 0) {\n const expectedSigners = Object.keys(transaction.signatures);\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n expectedAddresses: expectedSigners,\n unexpectedAddresses: [...unexpectedSigners],\n });\n }\n\n if (!newSignatures) {\n return transaction;\n }\n\n return Object.freeze({\n ...transaction,\n signatures: Object.freeze({\n ...transaction.signatures,\n ...newSignatures,\n }),\n });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link FullySignedTransaction}.\n *\n * This function will throw unless the resulting transaction is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signTransaction } from '@solana/transactions';\n *\n * const signedTransaction = await signTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link partiallySignTransaction} if you want to sign the transaction without asserting that\n * the resulting transaction is fully signed.\n */\nexport async function signTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<FullySignedTransaction & TTransaction> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertIsFullySignedTransaction(out);\n Object.freeze(out);\n return out;\n}\n\n/**\n * Checks whether a given {@link Transaction} is fully signed.\n *\n * @example\n * ```ts\n * import { isFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isFullySignedTransaction(transaction)) {\n * // At this point we know that the transaction is signed and can be sent to the network.\n * }\n * ```\n */\nexport function isFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is FullySignedTransaction & TTransaction {\n return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link Transaction}, that you expect to be fully signed,\n * from an untrusted network API or user input. Use this function to assert that such a transaction\n * is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `FullySignedTransaction`.\n * assertIsFullySignedTransaction(transaction);\n * // At this point we know that the transaction is signed and can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is FullySignedTransaction & TTransaction {\n const missingSigs: Address[] = [];\n Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {\n if (!signatureBytes) {\n missingSigs.push(address as Address);\n }\n });\n\n if (missingSigs.length > 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n addresses: missingSigs,\n });\n }\n}\n","import { getBase64Decoder } from '@solana/codecs-strings';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/** Represents the wire format of a transaction as a base64-encoded string. */\nexport type Base64EncodedWireTransaction = Brand<EncodedString<string, 'base64'>, 'Base64EncodedWireTransaction'>;\n\n/**\n * Given a signed transaction, this method returns the transaction as a string that conforms to the\n * {@link Base64EncodedWireTransaction} type.\n *\n * @example\n * ```ts\n * import { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n *\n * const serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n * const signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n * ```\n */\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { NominalType } from '@solana/nominal-types';\nimport type { BaseTransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/**\n * The maximum size of a transaction packet in bytes.\n */\nexport const TRANSACTION_PACKET_SIZE = 1280;\n\n/**\n * The size of the transaction packet header in bytes.\n * This includes the IPv6 header and the fragment header.\n */\nexport const TRANSACTION_PACKET_HEADER =\n 40 /* 40 bytes is the size of the IPv6 header. */ + 8; /* 8 bytes is the size of the fragment header. */\n\n/**\n * The maximum size of a transaction in bytes.\n *\n * Note that this excludes the transaction packet header.\n * In other words, this is how much content we can fit in a transaction packet.\n */\nexport const TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;\n\n/**\n * Gets the size of a given transaction in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionSize(transaction);\n * ```\n */\nexport function getTransactionSize(transaction: Transaction): number {\n return getTransactionEncoder().getSizeFromValue(transaction);\n}\n\n/**\n * A type guard that checks if a transaction is within the size limit.\n */\nexport type TransactionWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that adds the `TransactionWithinSizeLimit` flag to\n * a transaction if and only if the provided transaction message\n * is also within the size limit.\n */\nexport type SetTransactionWithinSizeLimitFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends BaseTransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithinSizeLimit\n ? TransactionWithinSizeLimit & TTransaction\n : TTransaction;\n\n/**\n * Checks if a transaction is within the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * if (isTransactionWithinSizeLimit(transaction)) {\n * transaction satisfies TransactionWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is TransactionWithinSizeLimit & TTransaction {\n return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction is within the size limit.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction exceeds the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * assertIsTransactionWithinSizeLimit(transaction);\n * transaction satisfies TransactionWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is TransactionWithinSizeLimit & TTransaction {\n const transactionSize = getTransactionSize(transaction);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n","import { assertIsFullySignedTransaction, FullySignedTransaction, isFullySignedTransaction } from './signatures';\nimport { Transaction } from './transaction';\nimport {\n assertIsTransactionWithinSizeLimit,\n isTransactionWithinSizeLimit,\n TransactionWithinSizeLimit,\n} from './transaction-size';\n\n/**\n * Helper type that includes all transaction types required\n * for the transaction to be sent to the network.\n *\n * @see {@link isSendableTransaction}\n * @see {@link assertIsSendableTransaction}\n */\nexport type SendableTransaction = FullySignedTransaction & TransactionWithinSizeLimit;\n\n/**\n * Checks if a transaction has all the required\n * conditions to be sent to the network.\n *\n * @example\n * ```ts\n * import { isSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isSendableTransaction(transaction)) {\n * // At this point we know that the transaction can be sent to the network.\n * }\n * ```\n *\n * @see {@link assertIsSendableTransaction}\n */\nexport function isSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is SendableTransaction & TTransaction {\n return isFullySignedTransaction(transaction) && isTransactionWithinSizeLimit(transaction);\n}\n\n/**\n * Asserts that a given transaction has all the\n * required conditions to be sent to the network.\n *\n * From time to time you might acquire a {@link Transaction}\n * from an untrusted network API or user input and you are not sure\n * that it has all the required conditions to be sent to the network\n * — such as being fully signed and within the size limit.\n * This function can be used to assert that such a transaction\n * is in fact sendable.\n *\n * @example\n * ```ts\n * import { assertIsSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `SendableTransaction`.\n * assertIsSendableTransaction(transaction);\n * // At this point we know that the transaction can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n * setError(`Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is SendableTransaction & TTransaction {\n assertIsFullySignedTransaction(transaction);\n assertIsTransactionWithinSizeLimit(transaction);\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type {\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from './compile-transaction';\nimport { getTransactionSize, TRANSACTION_SIZE_LIMIT } from './transaction-size';\n\n/**\n * Gets the compiled transaction size of a given transaction message in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionMessageSize(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSize(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): number {\n return getTransactionSize(compileTransaction(transactionMessage));\n}\n\n/**\n * Checks if a transaction message is within the size limit\n * when compiled into a transaction.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction message is within the size limit\n * when compiled into a transaction.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction message exceeds the size limit.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): asserts transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n const transactionSize = getTransactionMessageSize(transactionMessage);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n"]}
@@ -233,7 +233,9 @@ function getBase64EncodedWireTransaction(transaction) {
233
233
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
234
234
  return codecsStrings.getBase64Decoder().decode(wireTransactionBytes);
235
235
  }
236
- var TRANSACTION_SIZE_LIMIT = 4096;
236
+ var TRANSACTION_PACKET_SIZE = 1280;
237
+ var TRANSACTION_PACKET_HEADER = 40 + 8;
238
+ var TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;
237
239
  function getTransactionSize(transaction) {
238
240
  return getTransactionEncoder().getSizeFromValue(transaction);
239
241
  }
@@ -274,6 +276,8 @@ function assertIsTransactionMessageWithinSizeLimit(transactionMessage) {
274
276
  }
275
277
  }
276
278
 
279
+ exports.TRANSACTION_PACKET_HEADER = TRANSACTION_PACKET_HEADER;
280
+ exports.TRANSACTION_PACKET_SIZE = TRANSACTION_PACKET_SIZE;
277
281
  exports.TRANSACTION_SIZE_LIMIT = TRANSACTION_SIZE_LIMIT;
278
282
  exports.assertIsFullySignedTransaction = assertIsFullySignedTransaction;
279
283
  exports.assertIsSendableTransaction = assertIsSendableTransaction;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/lifetime.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/sendable-transaction.ts","../src/transaction-message-size.ts"],"names":["SolanaError","SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES","transformEncoder","getArrayEncoder","fixEncoderSize","getBytesEncoder","getShortU16Encoder","getStructEncoder","transformDecoder","getStructDecoder","getArrayDecoder","fixDecoderSize","getBytesDecoder","getShortU16Decoder","combineCodec","getTupleDecoder","getTransactionVersionDecoder","padRightDecoder","getU8Decoder","getAddressDecoder","SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH","SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE","isBlockhash","SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME","isAddress","SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME","compileTransactionMessage","getCompiledTransactionMessageEncoder","isTransactionMessageWithBlockhashLifetime","isTransactionMessageWithDurableNonceLifetime","getBase58Decoder","SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING","getAddressFromPublicKey","signBytes","bytesEqual","SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION","SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING","getBase64Decoder","SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT"],"mappings":";;;;;;;;;;;;;AAQA,SAAS,sBAAsB,aAAA,EAAgD;AAC3E,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,CAAO,aAAa,CAAA;AAC9C,EAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AACzB,IAAA,MAAM,IAAIA,mBAAYC,qEAA8D,CAAA;AAAA,EACxF;AAEA,EAAA,OAAO,UAAA,CAAW,IAAI,CAAA,SAAA,KAAa;AAC/B,IAAA,IAAI,CAAC,SAAA,EAAW;AACZ,MAAA,OAAO,IAAI,UAAA,CAAW,EAAE,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,SAAA;AAAA,EACX,CAAC,CAAA;AACL;AAEO,SAAS,oBAAA,GAA2D;AACvE,EAAA,OAAOC,2BAAA;AAAA,IACHC,oCAAA,CAAgBC,yBAAA,CAAeC,oCAAA,EAAgB,EAAG,EAAE,GAAG,EAAE,IAAA,EAAMC,gCAAA,EAAmB,EAAG,CAAA;AAAA,IACrF;AAAA,GACJ;AACJ;;;ACIO,SAAS,qBAAA,GAA0D;AACtE,EAAA,OAAOC,qCAAA,CAAiB;AAAA,IACpB,CAAC,YAAA,EAAc,oBAAA,EAAsB,CAAA;AAAA,IACrC,CAAC,cAAA,EAAgBF,oCAAAA,EAAiB;AAAA,GACrC,CAAA;AACL;AAkBO,SAAS,qBAAA,GAA0D;AACtE,EAAA,OAAOG,2BAAA;AAAA,IACHC,qCAAA,CAAiB;AAAA,MACb,CAAC,YAAA,EAAcC,oCAAA,CAAgBC,yBAAA,CAAeC,oCAAA,EAAgB,EAAG,EAAE,CAAA,EAAG,EAAE,IAAA,EAAMC,gCAAA,EAAmB,EAAG,CAAC,CAAA;AAAA,MACrG,CAAC,cAAA,EAAgBD,oCAAA,EAAiB;AAAA,KACrC,CAAA;AAAA,IACD;AAAA,GACJ;AACJ;AAQO,SAAS,mBAAA,GAAsD;AAClE,EAAA,OAAOE,uBAAA,CAAa,qBAAA,EAAsB,EAAG,qBAAA,EAAuB,CAAA;AACxE;AAOA,SAAS,kCAAkC,WAAA,EAAuD;AAC9F,EAAA,MAAM,EAAE,YAAA,EAAc,UAAA,EAAW,GAAI,WAAA;AAWrC,EAAA,MAAM,yBAAyBC,oCAAA,CAAgB;AAAA;AAAA,IAE3CC,gDAAA,EAA6B;AAAA;AAAA;AAAA,IAG7BC,0BAAA,CAAgBC,0BAAA,EAAa,EAAG,CAAC,CAAA;AAAA;AAAA,IAEjCR,qCAAgBS,2BAAA,EAAkB,EAAG,EAAE,IAAA,EAAMN,gCAAA,IAAsB;AAAA,GACtE,CAAA;AACD,EAAA,MAAM,CAAC,UAAA,EAAY,qBAAA,EAAuB,eAAe,CAAA,GAAI,sBAAA,CAAuB,OAAO,YAAY,CAAA;AAEvG,EAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,KAAA,CAAM,CAAA,EAAG,qBAAqB,CAAA;AAItE,EAAA,IAAI,eAAA,CAAgB,MAAA,KAAW,UAAA,CAAW,MAAA,EAAQ;AAC9C,IAAA,MAAM,IAAIb,mBAAYoB,6DAAA,EAAwD;AAAA,MAC1E,qBAAA;AAAA,MACA,kBAAkB,UAAA,CAAW,MAAA;AAAA,MAC7B;AAAA,KACH,CAAA;AAAA,EACL;AAGA,EAAA,MAAM,gBAA+B,EAAC;AACtC,EAAA,eAAA,CAAgB,OAAA,CAAQ,CAAC,OAAA,EAAS,KAAA,KAAU;AACxC,IAAA,MAAM,mBAAA,GAAsB,WAAW,KAAK,CAAA;AAC5C,IAAA,IAAI,mBAAA,CAAoB,KAAA,CAAM,CAAA,CAAA,KAAK,CAAA,KAAM,CAAC,CAAA,EAAG;AACzC,MAAA,aAAA,CAAc,OAAO,CAAA,GAAI,IAAA;AAAA,IAC7B,CAAA,MAAO;AACH,MAAA,aAAA,CAAc,OAAO,CAAA,GAAI,mBAAA;AAAA,IAC7B;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACH,YAAA;AAAA,IACA,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,aAAa;AAAA,GAC3C;AACJ;ACfA,IAAM,sBAAA,GAAyB,kCAAA;AAE/B,SAAS,4CAAA,CACL,aACA,eAAA,EACgF;AAChF,EAAA,OACI,eAAA,CAAgB,WAAA,CAAY,mBAAmB,CAAA,KAAM,sBAAA;AAAA,EAErD,WAAA,CAAY,IAAA,IAAQ,IAAA,IACpB,oCAAA,CAAqC,YAAY,IAAI,CAAA;AAAA,EAErD,WAAA,CAAY,gBAAgB,MAAA,KAAW,CAAA;AAE/C;AAEA,SAAS,qCAAqC,IAAA,EAAmC;AAE7E,EAAA,OAAO,KAAK,UAAA,KAAe,CAAA,IAAK,IAAA,CAAK,CAAC,MAAM,CAAA,IAAK,IAAA,CAAK,CAAC,CAAA,KAAM,KAAK,IAAA,CAAK,CAAC,MAAM,CAAA,IAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA;AACnG;AAcA,eAAsB,+DAClB,0BAAA,EACuE;AACvE,EAAA,MAAM,gBAAA,GAAmB,0BAAA,CAA2B,YAAA,CAAa,CAAC,CAAA;AAClE,EAAA,MAAM,EAAE,gBAAe,GAAI,0BAAA;AAG3B,EAAA,IAAI,gBAAA,IAAoB,4CAAA,CAA6C,gBAAA,EAAkB,cAAc,CAAA,EAAG;AACpG,IAAA,MAAM,mBAAA,GAAsB,cAAA,CAAe,gBAAA,CAAiB,cAAA,CAAe,CAAC,CAAC,CAAA;AAC7E,IAAA,IAAI,CAAC,mBAAA,EAAqB;AACtB,MAAA,MAAM,IAAIpB,mBAAYqB,yEAAA,EAAoE;AAAA,QACtF,OAAO,0BAAA,CAA2B;AAAA,OACrC,CAAA;AAAA,IACL;AACA,IAAA,OAAO;AAAA,MACH,OAAO,0BAAA,CAA2B,aAAA;AAAA,MAClC;AAAA,KACJ;AAAA,EACJ,CAAA,MAAO;AACH,IAAA,OAAO;AAAA,MACH,WAAW,0BAAA,CAA2B,aAAA;AAAA;AAAA,MAEtC,oBAAA,EAAsB;AAAA,KAC1B;AAAA,EACJ;AACJ;AAuBO,SAAS,mCACZ,WAAA,EAC6D;AAC7D,EAAA,OACI,wBAAwB,WAAA,IACxB,WAAA,IAAe,YAAY,kBAAA,IAC3B,OAAO,YAAY,kBAAA,CAAmB,SAAA,KAAc,QAAA,IACpD,OAAO,YAAY,kBAAA,CAAmB,oBAAA,KAAyB,YAC/DC,oBAAA,CAAY,WAAA,CAAY,mBAAmB,SAAS,CAAA;AAE5D;AAwBO,SAAS,yCACZ,WAAA,EACqE;AACrE,EAAA,IAAI,CAAC,kCAAA,CAAmC,WAAW,CAAA,EAAG;AAClD,IAAA,MAAM,IAAItB,mBAAYuB,6DAAsD,CAAA;AAAA,EAChF;AACJ;AAyBO,SAAS,sCACZ,WAAA,EACgE;AAChE,EAAA,OACI,wBAAwB,WAAA,IACxB,OAAA,IAAW,YAAY,kBAAA,IACvB,OAAO,YAAY,kBAAA,CAAmB,KAAA,KAAU,QAAA,IAChD,OAAO,YAAY,kBAAA,CAAmB,mBAAA,KAAwB,YAC9DC,mBAAA,CAAU,WAAA,CAAY,mBAAmB,mBAAmB,CAAA;AAEpE;AAwBO,SAAS,4CACZ,WAAA,EACwE;AACxE,EAAA,IAAI,CAAC,qCAAA,CAAsC,WAAW,CAAA,EAAG;AACrD,IAAA,MAAM,IAAIxB,mBAAYyB,yDAAkD,CAAA;AAAA,EAC5E;AACJ;AChRO,SAAS,mBACZ,kBAAA,EACgE;AAGhE,EAAA,MAAM,eAAA,GAAkBC,8CAA0B,kBAAkB,CAAA;AACpE,EAAA,MAAM,YAAA,GAAeC,wDAAA,EAAqC,CAAE,MAAA,CAAO,eAAe,CAAA;AAElF,EAAA,MAAM,qBAAqB,eAAA,CAAgB,cAAA,CAAe,MAAM,CAAA,EAAG,eAAA,CAAgB,OAAO,iBAAiB,CAAA;AAC3G,EAAA,MAAM,aAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,iBAAiB,kBAAA,EAAoB;AAC5C,IAAA,UAAA,CAAW,aAAa,CAAA,GAAI,IAAA;AAAA,EAChC;AAEA,EAAA,IAAI,kBAAA;AACJ,EAAA,IAAIC,6DAAA,CAA0C,kBAAkB,CAAA,EAAG;AAC/D,IAAA,kBAAA,GAAqB;AAAA,MACjB,SAAA,EAAW,mBAAmB,kBAAA,CAAmB,SAAA;AAAA,MACjD,oBAAA,EAAsB,mBAAmB,kBAAA,CAAmB;AAAA,KAChE;AAAA,EACJ,CAAA,MAAA,IAAWC,gEAAA,CAA6C,kBAAkB,CAAA,EAAG;AACzE,IAAA,kBAAA,GAAqB;AAAA,MACjB,KAAA,EAAO,mBAAmB,kBAAA,CAAmB,KAAA;AAAA,MAC7C,qBAAqB,kBAAA,CAAmB,YAAA,CAAa,CAAC,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,CAAE;AAAA,KACxE;AAAA,EACJ;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAI,kBAAA,GAAqB,EAAE,kBAAA,EAAmB,GAAI,MAAA;AAAA,IAClD,YAAA;AAAA,IACA,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,UAAU;AAAA,GACvC,CAAA;AACL;ACxCA,IAAI,aAAA;AAeG,SAAS,4BAA4B,WAAA,EAAqC;AAC7E,EAAA,IAAI,CAAC,aAAA,EAAe,aAAA,GAAgBC,8BAAA,EAAiB;AAIrD,EAAA,MAAM,iBAAiB,MAAA,CAAO,MAAA,CAAO,WAAA,CAAY,UAAU,EAAE,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAC,cAAA,EAAgB;AACjB,IAAA,MAAM,IAAI9B,mBAAY+B,6DAAsD,CAAA;AAAA,EAChF;AACA,EAAA,MAAM,oBAAA,GAAuB,aAAA,CAAc,MAAA,CAAO,cAAc,CAAA;AAChE,EAAA,OAAO,oBAAA;AACX;AAsBA,eAAsB,wBAAA,CAClB,UACA,WAAA,EACqB;AACrB,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI,iBAAA;AAEJ,EAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,IACV,QAAA,CAAS,GAAA,CAAI,OAAM,OAAA,KAAW;AAC1B,MAAA,MAAM,OAAA,GAAU,MAAMC,iCAAA,CAAwB,OAAA,CAAQ,SAAS,CAAA;AAC/D,MAAA,MAAM,iBAAA,GAAoB,WAAA,CAAY,UAAA,CAAW,OAAO,CAAA;AAGxD,MAAA,IAAI,sBAAsB,MAAA,EAAW;AAEjC,QAAA,iBAAA,yBAA0B,GAAA,EAAI;AAC9B,QAAA,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAC7B,QAAA;AAAA,MACJ;AAGA,MAAA,IAAI,iBAAA,EAAmB;AACnB,QAAA;AAAA,MACJ;AAEA,MAAA,MAAM,eAAe,MAAMC,cAAA,CAAU,OAAA,CAAQ,UAAA,EAAY,YAAY,YAAY,CAAA;AAEjF,MAAA,IAAI,iBAAA,KAAsB,IAAA,IAAQC,qBAAA,CAAW,YAAA,EAAc,iBAAiB,CAAA,EAAG;AAE3E,QAAA;AAAA,MACJ;AAEA,MAAA,aAAA,KAAkB,EAAC;AACnB,MAAA,aAAA,CAAc,OAAO,CAAA,GAAI,YAAA;AAAA,IAC7B,CAAC;AAAA,GACL;AAEA,EAAA,IAAI,iBAAA,IAAqB,iBAAA,CAAkB,IAAA,GAAO,CAAA,EAAG;AACjD,IAAA,MAAM,eAAA,GAAkB,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,UAAU,CAAA;AAC1D,IAAA,MAAM,IAAIlC,mBAAYmC,mEAAA,EAA8D;AAAA,MAChF,iBAAA,EAAmB,eAAA;AAAA,MACnB,mBAAA,EAAqB,CAAC,GAAG,iBAAiB;AAAA,KAC7C,CAAA;AAAA,EACL;AAEA,EAAA,IAAI,CAAC,aAAA,EAAe;AAChB,IAAA,OAAO,WAAA;AAAA,EACX;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACjB,GAAG,WAAA;AAAA,IACH,UAAA,EAAY,OAAO,MAAA,CAAO;AAAA,MACtB,GAAG,WAAA,CAAY,UAAA;AAAA,MACf,GAAG;AAAA,KACN;AAAA,GACJ,CAAA;AACL;AAoBA,eAAsB,eAAA,CAClB,UACA,WAAA,EAC8C;AAC9C,EAAA,MAAM,GAAA,GAAM,MAAM,wBAAA,CAAyB,QAAA,EAAU,WAAW,CAAA;AAChE,EAAA,8BAAA,CAA+B,GAAG,CAAA;AAClC,EAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AACjB,EAAA,OAAO,GAAA;AACX;AAeO,SAAS,yBACZ,WAAA,EACoD;AACpD,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,WAAA,CAAY,UAAU,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,cAAc,CAAA,KAAM,CAAC,CAAC,cAAc,CAAA;AACjG;AA0BO,SAAS,+BACZ,WAAA,EAC4D;AAC5D,EAAA,MAAM,cAAyB,EAAC;AAChC,EAAA,MAAA,CAAO,OAAA,CAAQ,YAAY,UAAU,CAAA,CAAE,QAAQ,CAAC,CAAC,OAAA,EAAS,cAAc,CAAA,KAAM;AAC1E,IAAA,IAAI,CAAC,cAAA,EAAgB;AACjB,MAAA,WAAA,CAAY,KAAK,OAAkB,CAAA;AAAA,IACvC;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AACxB,IAAA,MAAM,IAAInC,mBAAYoC,oDAAA,EAA+C;AAAA,MACjE,SAAA,EAAW;AAAA,KACd,CAAA;AAAA,EACL;AACJ;AC/LO,SAAS,gCAAgC,WAAA,EAAwD;AACpG,EAAA,MAAM,oBAAA,GAAuB,qBAAA,EAAsB,CAAE,MAAA,CAAO,WAAW,CAAA;AACvE,EAAA,OAAOC,8BAAA,EAAiB,CAAE,MAAA,CAAO,oBAAoB,CAAA;AACzD;ACdO,IAAM,sBAAA,GAAyB;AAU/B,SAAS,mBAAmB,WAAA,EAAkC;AACjE,EAAA,OAAO,qBAAA,EAAsB,CAAE,gBAAA,CAAiB,WAAW,CAAA;AAC/D;AA+BO,SAAS,6BACZ,WAAA,EACwD;AACxD,EAAA,OAAO,kBAAA,CAAmB,WAAW,CAAA,IAAK,sBAAA;AAC9C;AAgBO,SAAS,mCACZ,WAAA,EACgE;AAChE,EAAA,MAAM,eAAA,GAAkB,mBAAmB,WAAW,CAAA;AACtD,EAAA,IAAI,kBAAkB,sBAAA,EAAwB;AAC1C,IAAA,MAAM,IAAIrC,mBAAYsC,oDAAA,EAA+C;AAAA,MACjE,eAAA;AAAA,MACA,oBAAA,EAAsB;AAAA,KACzB,CAAA;AAAA,EACL;AACJ;;;AClDO,SAAS,sBACZ,WAAA,EACiD;AACjD,EAAA,OAAO,wBAAA,CAAyB,WAAW,CAAA,IAAK,4BAAA,CAA6B,WAAW,CAAA;AAC5F;AAkCO,SAAS,4BACZ,WAAA,EACyD;AACzD,EAAA,8BAAA,CAA+B,WAAW,CAAA;AAC1C,EAAA,kCAAA,CAAmC,WAAW,CAAA;AAClD;AC1DO,SAAS,0BACZ,kBAAA,EACM;AACN,EAAA,OAAO,kBAAA,CAAmB,kBAAA,CAAmB,kBAAkB,CAAC,CAAA;AACpE;AAeO,SAAS,oCAGZ,kBAAA,EAC6E;AAC7E,EAAA,OAAO,yBAAA,CAA0B,kBAAkB,CAAA,IAAK,sBAAA;AAC5D;AAiBO,SAAS,0CAGZ,kBAAA,EACqF;AACrF,EAAA,MAAM,eAAA,GAAkB,0BAA0B,kBAAkB,CAAA;AACpE,EAAA,IAAI,kBAAkB,sBAAA,EAAwB;AAC1C,IAAA,MAAM,IAAItC,mBAAYsC,oDAAAA,EAA+C;AAAA,MACjE,eAAA;AAAA,MACA,oBAAA,EAAsB;AAAA,KACzB,CAAA;AAAA,EACL;AACJ","file":"index.node.cjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\n/**\n * Returns an encoder that you can use to encode a {@link Transaction} to a byte array in a wire\n * format appropriate for sending to the Solana network for execution.\n */\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\n ]);\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana transaction wire format\n * to a {@link Transaction} object.\n *\n * @example\n * ```ts\n * import { getTransactionDecoder } from '@solana/transactions';\n *\n * const transactionDecoder = getTransactionDecoder();\n * const transaction = transactionDecoder.decode(wireTransactionBytes);\n * for (const [address, signature] in Object.entries(transaction.signatures)) {\n * console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\n\nexport function getTransactionDecoder(): VariableSizeDecoder<Transaction> {\n return transformDecoder(\n getStructDecoder([\n ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getShortU16Decoder() })],\n ['messageBytes', getBytesDecoder()],\n ]),\n decodePartiallyDecodedTransaction,\n );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Transaction}\n *\n * @see {@link getTransactionDecoder}\n * @see {@link getTransactionEncoder}\n */\nexport function getTransactionCodec(): VariableSizeCodec<Transaction> {\n return combineCodec(getTransactionEncoder(), getTransactionDecoder());\n}\n\ntype PartiallyDecodedTransaction = {\n messageBytes: ReadonlyUint8Array;\n signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedTransaction(transaction: PartiallyDecodedTransaction): Transaction {\n const { messageBytes, signatures } = transaction;\n\n /*\n Relevant message structure is at the start:\n - transaction version (0 bytes for legacy transactions, 1 byte for versioned transactions)\n - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n - `numReadOnlySignedAccounts` (1 byte, not used here)\n - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n - static addresses, with signers first. This is an array of addresses, prefixed with a short-u16 length\n */\n\n const signerAddressesDecoder = getTupleDecoder([\n // read transaction version\n getTransactionVersionDecoder(),\n // read first byte of header, `numSignerAccounts`\n // padRight to skip the next 2 bytes, `numReadOnlySignedAccounts` and `numReadOnlyUnsignedAccounts` which we don't need\n padRightDecoder(getU8Decoder(), 2),\n // read static addresses\n getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() }),\n ]);\n const [_txVersion, numRequiredSignatures, staticAddresses] = signerAddressesDecoder.decode(messageBytes);\n\n const signerAddresses = staticAddresses.slice(0, numRequiredSignatures);\n\n // signer addresses and signatures must be the same length\n // we encode an all-zero signature when the signature is missing\n if (signerAddresses.length !== signatures.length) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n numRequiredSignatures,\n signaturesLength: signatures.length,\n signerAddresses,\n });\n }\n\n // combine the signer addresses + signatures into the signatures map\n const signaturesMap: SignaturesMap = {};\n signerAddresses.forEach((address, index) => {\n const signatureForAddress = signatures[index];\n if (signatureForAddress.every(b => b === 0)) {\n signaturesMap[address] = null;\n } else {\n signaturesMap[address] = signatureForAddress as SignatureBytes;\n }\n });\n\n return {\n messageBytes: messageBytes as TransactionMessageBytes,\n signatures: Object.freeze(signaturesMap),\n };\n}\n","import { type Address, isAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n SolanaError,\n} from '@solana/errors';\nimport { type Blockhash, isBlockhash, type Slot } from '@solana/rpc-types';\nimport type {\n CompiledTransactionMessage,\n CompiledTransactionMessageWithLifetime,\n Nonce,\n TransactionMessage,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport type { Transaction } from './transaction';\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network. The transaction will continue to be eligible to land until the network considers the\n * `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type TransactionBlockhashLifetime = {\n /**\n * A recent blockhash observed by the transaction proposer.\n *\n * The transaction will be considered eligible to land until the network determines this\n * blockhash to be too old, or has switched to a fork where it is not present.\n */\n blockhash: Blockhash;\n /**\n * This is the block height beyond which the network will consider the blockhash to be too old\n * to make a transaction eligible to land.\n */\n lastValidBlockHeight: Slot;\n};\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionDurableNonceLifetime = {\n /**\n * A value contained in the account with address `nonceAccountAddress` at the time the\n * transaction was prepared.\n *\n * The transaction will be considered eligible to land until the nonce account ceases to exist\n * or contain this value.\n */\n nonce: Nonce;\n /** The account that contains the `nonce` value */\n nonceAccountAddress: Address;\n};\n\n/**\n * A transaction whose ability to land on the network is determined by some evanescent criteria.\n *\n * This describes a window of time after which a transaction is constructed and before which it will\n * no longer be accepted by the network.\n *\n * No transaction can land on Solana without having a `lifetimeConstraint` set.\n */\nexport type TransactionWithLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime | TransactionDurableNonceLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by the age of a blockhash observed on the network.\n *\n * The transaction will continue to be eligible to land until the network considers the `blockhash`\n * to be expired.\n */\nexport type TransactionWithBlockhashLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by a nonce.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionWithDurableNonceLifetime = {\n readonly lifetimeConstraint: TransactionDurableNonceLifetime;\n};\n\n/**\n * Helper type that sets the lifetime constraint of a transaction to be the same as the\n * lifetime constraint of the provided transaction message.\n *\n * If the transaction message has no explicit lifetime constraint, neither will the transaction.\n */\nexport type SetTransactionLifetimeFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends { lifetimeConstraint: unknown }\n ? TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithBlockhashLifetime['lifetimeConstraint']\n ? TransactionWithBlockhashLifetime & TTransaction\n : TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithDurableNonceLifetime['lifetimeConstraint']\n ? TransactionWithDurableNonceLifetime & TTransaction\n : TransactionWithLifetime & TTransaction\n : TTransaction;\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\n\nfunction compiledInstructionIsAdvanceNonceInstruction(\n instruction: CompiledTransactionMessage['instructions'][number],\n staticAddresses: Address[],\n): instruction is typeof instruction & { accountIndices: [number, number, number] } {\n return (\n staticAddresses[instruction.programAddressIndex] === SYSTEM_PROGRAM_ADDRESS &&\n // Test for `AdvanceNonceAccount` instruction data\n instruction.data != null &&\n isAdvanceNonceAccountInstructionData(instruction.data) &&\n // Test for exactly 3 accounts\n instruction.accountIndices?.length === 3\n );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): boolean {\n // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n\n/**\n * Get the lifetime constraint for a transaction from a compiled transaction message that includes a lifetime token.\n * @param compiledTransactionMessage A compiled transaction message that includes a lifetime token\n * @returns A lifetime constraint for the transaction\n * Note that this is less precise than checking a decompiled instruction, as we can't inspect\n * the address or role of input accounts (which may be in lookup tables). However, this is\n * sufficient for all valid advance durable nonce instructions.\n * Note that the program address must not be in a lookup table, see [this answer on StackExchange](https://solana.stackexchange.com/a/16224/289)\n * @see {@link isAdvanceNonceAccountInstruction}\n * Note that this function is async to allow for future implementations that may fetch `lastValidBlockHeight` using an RPC\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n): Promise<TransactionBlockhashLifetime | TransactionDurableNonceLifetime> {\n const firstInstruction = compiledTransactionMessage.instructions[0];\n const { staticAccounts } = compiledTransactionMessage;\n\n // We need to check if the first instruction is an AdvanceNonceAccount instruction\n if (firstInstruction && compiledInstructionIsAdvanceNonceInstruction(firstInstruction, staticAccounts)) {\n const nonceAccountAddress = staticAccounts[firstInstruction.accountIndices[0]];\n if (!nonceAccountAddress) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n nonce: compiledTransactionMessage.lifetimeToken,\n });\n }\n return {\n nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n nonceAccountAddress,\n };\n } else {\n return {\n blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n // This is not known from the compiled message, so we set it to the maximum possible value\n lastValidBlockHeight: 0xffffffffffffffffn,\n };\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * if (isTransactionWithBlockhashLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a `TransactionWithBlockhashLifetime`.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * setBlockhashIsValid(blockhashIsValid);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithBlockhashLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'blockhash' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.blockhash === 'string' &&\n typeof transaction.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n isBlockhash(transaction.lifetimeConstraint.blockhash)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * blockhash-based lifetime, from for example a wallet. Use this function to\n * assert that such a transaction actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithBlockhashLifetime`.\n * assertIsTransactionWithBlockhashLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithBlockhashLifetime` that can be used\n * // with the RPC.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n * // `transaction` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithBlockhashLifetime {\n if (!isTransactionWithBlockhashLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithDurableNonceLifetime } from '@solana/transactions';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionWithDurableNonceLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a\n * // `TransactionWithDurableNonceLifetime`.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * setNonceIsValid(nonce === actualNonce);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithDurableNonceLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'nonce' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.nonce === 'string' &&\n typeof transaction.lifetimeConstraint.nonceAccountAddress === 'string' &&\n isAddress(transaction.lifetimeConstraint.nonceAccountAddress)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * nonce-based lifetime, from for example a wallet. Use this function to assert\n * that such a transaction actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithDurableNonceLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithDurableNonceLifetime`.\n * assertIsTransactionWithDurableNonceLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithDurableNonceLifetime` that can be used\n * // with the RPC.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n * // `transaction` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithDurableNonceLifetime {\n if (!isTransactionWithDurableNonceLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n }\n}\n","import {\n BaseTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n isTransactionMessageWithDurableNonceLifetime,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type { SignaturesMap, TransactionFromTransactionMessage, TransactionMessageBytes } from './transaction';\n\n/**\n * Returns a {@link Transaction} object for a given {@link TransactionMessage}.\n *\n * This includes the compiled bytes of the transaction message, and a map of signatures. This map\n * will have a key for each address that is required to sign the transaction. The transaction will\n * not yet have signatures for any of these addresses.\n *\n * Whether a transaction message is ready to be compiled or not is enforced for you at the type\n * level. In order to be signable, a transaction message must:\n *\n * - have a version and a list of zero or more instructions (ie. conform to\n * {@link BaseTransactionMessage})\n * - have a fee payer set (ie. conform to {@link TransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction<TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromTransactionMessage<TTransactionMessage>>;\n\n const compiledMessage = compileTransactionMessage(transactionMessage);\n const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage) as TransactionMessageBytes;\n\n const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);\n const signatures: SignaturesMap = {};\n for (const signerAddress of transactionSigners) {\n signatures[signerAddress] = null;\n }\n\n let lifetimeConstraint: TransactionWithLifetime['lifetimeConstraint'] | undefined;\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else if (isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n ...(lifetimeConstraint ? { lifetimeConstraint } : undefined),\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { bytesEqual, Decoder } from '@solana/codecs-core';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { Signature, SignatureBytes, signBytes } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { Transaction } from './transaction';\n\n/**\n * Represents a transaction that is signed by all of its required signers. Being fully signed is a\n * prerequisite of functions designed to land transactions on the network.\n */\nexport type FullySignedTransaction = NominalType<'transactionSignedness', 'fullySigned'>;\n\nlet base58Decoder: Decoder<string> | undefined;\n\n/**\n * Given a transaction signed by its fee payer, this method will return the {@link Signature} that\n * uniquely identifies it. This string can be used to look up transactions at a later date, for\n * example on a Solana block explorer.\n *\n * @example\n * ```ts\n * import { getSignatureFromTransaction } from '@solana/transactions';\n *\n * const signature = getSignatureFromTransaction(tx);\n * console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n * ```\n */\nexport function getSignatureFromTransaction(transaction: Transaction): Signature {\n if (!base58Decoder) base58Decoder = getBase58Decoder();\n\n // We have ordered signatures from the compiled message accounts\n // first signature is the fee payer\n const signatureBytes = Object.values(transaction.signatures)[0];\n if (!signatureBytes) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n }\n const transactionSignature = base58Decoder.decode(signatureBytes);\n return transactionSignature as Signature;\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link Transaction}.\n *\n * Though the resulting transaction might have every signature it needs to land on the network, this\n * function will not assert that it does. A partially signed transaction cannot be landed on the\n * network, but can be serialized and deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignTransaction } from '@solana/transactions';\n *\n * const partiallySignedTransaction = await partiallySignTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link signTransaction} if you want to assert that the transaction has all of its required\n * signatures after signing.\n */\nexport async function partiallySignTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<TTransaction> {\n let newSignatures: Record<Address, SignatureBytes> | undefined;\n let unexpectedSigners: Set<Address> | undefined;\n\n await Promise.all(\n keyPairs.map(async keyPair => {\n const address = await getAddressFromPublicKey(keyPair.publicKey);\n const existingSignature = transaction.signatures[address];\n\n // Check if the address is expected to sign the transaction\n if (existingSignature === undefined) {\n // address is not an expected signer for this transaction\n unexpectedSigners ||= new Set();\n unexpectedSigners.add(address);\n return;\n }\n\n // Return if there are any unexpected signers already since we won't be using signatures\n if (unexpectedSigners) {\n return;\n }\n\n const newSignature = await signBytes(keyPair.privateKey, transaction.messageBytes);\n\n if (existingSignature !== null && bytesEqual(newSignature, existingSignature)) {\n // already have the same signature set\n return;\n }\n\n newSignatures ||= {};\n newSignatures[address] = newSignature;\n }),\n );\n\n if (unexpectedSigners && unexpectedSigners.size > 0) {\n const expectedSigners = Object.keys(transaction.signatures);\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n expectedAddresses: expectedSigners,\n unexpectedAddresses: [...unexpectedSigners],\n });\n }\n\n if (!newSignatures) {\n return transaction;\n }\n\n return Object.freeze({\n ...transaction,\n signatures: Object.freeze({\n ...transaction.signatures,\n ...newSignatures,\n }),\n });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link FullySignedTransaction}.\n *\n * This function will throw unless the resulting transaction is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signTransaction } from '@solana/transactions';\n *\n * const signedTransaction = await signTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link partiallySignTransaction} if you want to sign the transaction without asserting that\n * the resulting transaction is fully signed.\n */\nexport async function signTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<FullySignedTransaction & TTransaction> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertIsFullySignedTransaction(out);\n Object.freeze(out);\n return out;\n}\n\n/**\n * Checks whether a given {@link Transaction} is fully signed.\n *\n * @example\n * ```ts\n * import { isFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isFullySignedTransaction(transaction)) {\n * // At this point we know that the transaction is signed and can be sent to the network.\n * }\n * ```\n */\nexport function isFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is FullySignedTransaction & TTransaction {\n return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link Transaction}, that you expect to be fully signed,\n * from an untrusted network API or user input. Use this function to assert that such a transaction\n * is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `FullySignedTransaction`.\n * assertIsFullySignedTransaction(transaction);\n * // At this point we know that the transaction is signed and can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is FullySignedTransaction & TTransaction {\n const missingSigs: Address[] = [];\n Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {\n if (!signatureBytes) {\n missingSigs.push(address as Address);\n }\n });\n\n if (missingSigs.length > 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n addresses: missingSigs,\n });\n }\n}\n","import { getBase64Decoder } from '@solana/codecs-strings';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/** Represents the wire format of a transaction as a base64-encoded string. */\nexport type Base64EncodedWireTransaction = Brand<EncodedString<string, 'base64'>, 'Base64EncodedWireTransaction'>;\n\n/**\n * Given a signed transaction, this method returns the transaction as a string that conforms to the\n * {@link Base64EncodedWireTransaction} type.\n *\n * @example\n * ```ts\n * import { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n *\n * const serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n * const signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n * ```\n */\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { NominalType } from '@solana/nominal-types';\nimport type { BaseTransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/**\n * The maximum size of a transaction in bytes.\n */\nexport const TRANSACTION_SIZE_LIMIT = 4096;\n\n/**\n * Gets the size of a given transaction in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionSize(transaction);\n * ```\n */\nexport function getTransactionSize(transaction: Transaction): number {\n return getTransactionEncoder().getSizeFromValue(transaction);\n}\n\n/**\n * A type guard that checks if a transaction is within the size limit.\n */\nexport type TransactionWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that adds the `TransactionWithinSizeLimit` flag to\n * a transaction if and only if the provided transaction message\n * is also within the size limit.\n */\nexport type SetTransactionWithinSizeLimitFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends BaseTransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithinSizeLimit\n ? TransactionWithinSizeLimit & TTransaction\n : TTransaction;\n\n/**\n * Checks if a transaction is within the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * if (isTransactionWithinSizeLimit(transaction)) {\n * transaction satisfies TransactionWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is TransactionWithinSizeLimit & TTransaction {\n return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction is within the size limit.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction exceeds the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * assertIsTransactionWithinSizeLimit(transaction);\n * transaction satisfies TransactionWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is TransactionWithinSizeLimit & TTransaction {\n const transactionSize = getTransactionSize(transaction);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n","import { assertIsFullySignedTransaction, FullySignedTransaction, isFullySignedTransaction } from './signatures';\nimport { Transaction } from './transaction';\nimport {\n assertIsTransactionWithinSizeLimit,\n isTransactionWithinSizeLimit,\n TransactionWithinSizeLimit,\n} from './transaction-size';\n\n/**\n * Helper type that includes all transaction types required\n * for the transaction to be sent to the network.\n *\n * @see {@link isSendableTransaction}\n * @see {@link assertIsSendableTransaction}\n */\nexport type SendableTransaction = FullySignedTransaction & TransactionWithinSizeLimit;\n\n/**\n * Checks if a transaction has all the required\n * conditions to be sent to the network.\n *\n * @example\n * ```ts\n * import { isSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isSendableTransaction(transaction)) {\n * // At this point we know that the transaction can be sent to the network.\n * }\n * ```\n *\n * @see {@link assertIsSendableTransaction}\n */\nexport function isSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is SendableTransaction & TTransaction {\n return isFullySignedTransaction(transaction) && isTransactionWithinSizeLimit(transaction);\n}\n\n/**\n * Asserts that a given transaction has all the\n * required conditions to be sent to the network.\n *\n * From time to time you might acquire a {@link Transaction}\n * from an untrusted network API or user input and you are not sure\n * that it has all the required conditions to be sent to the network\n * — such as being fully signed and within the size limit.\n * This function can be used to assert that such a transaction\n * is in fact sendable.\n *\n * @example\n * ```ts\n * import { assertIsSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `SendableTransaction`.\n * assertIsSendableTransaction(transaction);\n * // At this point we know that the transaction can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n * setError(`Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is SendableTransaction & TTransaction {\n assertIsFullySignedTransaction(transaction);\n assertIsTransactionWithinSizeLimit(transaction);\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type {\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from './compile-transaction';\nimport { getTransactionSize, TRANSACTION_SIZE_LIMIT } from './transaction-size';\n\n/**\n * Gets the compiled transaction size of a given transaction message in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionMessageSize(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSize(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): number {\n return getTransactionSize(compileTransaction(transactionMessage));\n}\n\n/**\n * Checks if a transaction message is within the size limit\n * when compiled into a transaction.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction message is within the size limit\n * when compiled into a transaction.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction message exceeds the size limit.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): asserts transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n const transactionSize = getTransactionMessageSize(transactionMessage);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/lifetime.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/sendable-transaction.ts","../src/transaction-message-size.ts"],"names":["SolanaError","SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES","transformEncoder","getArrayEncoder","fixEncoderSize","getBytesEncoder","getShortU16Encoder","getStructEncoder","transformDecoder","getStructDecoder","getArrayDecoder","fixDecoderSize","getBytesDecoder","getShortU16Decoder","combineCodec","getTupleDecoder","getTransactionVersionDecoder","padRightDecoder","getU8Decoder","getAddressDecoder","SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH","SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE","isBlockhash","SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME","isAddress","SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME","compileTransactionMessage","getCompiledTransactionMessageEncoder","isTransactionMessageWithBlockhashLifetime","isTransactionMessageWithDurableNonceLifetime","getBase58Decoder","SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING","getAddressFromPublicKey","signBytes","bytesEqual","SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION","SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING","getBase64Decoder","SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\n/**\n * Returns an encoder that you can use to encode a {@link Transaction} to a byte array in a wire\n * format appropriate for sending to the Solana network for execution.\n */\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\n ]);\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana transaction wire format\n * to a {@link Transaction} object.\n *\n * @example\n * ```ts\n * import { getTransactionDecoder } from '@solana/transactions';\n *\n * const transactionDecoder = getTransactionDecoder();\n * const transaction = transactionDecoder.decode(wireTransactionBytes);\n * for (const [address, signature] in Object.entries(transaction.signatures)) {\n * console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\n\nexport function getTransactionDecoder(): VariableSizeDecoder<Transaction> {\n return transformDecoder(\n getStructDecoder([\n ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getShortU16Decoder() })],\n ['messageBytes', getBytesDecoder()],\n ]),\n decodePartiallyDecodedTransaction,\n );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Transaction}\n *\n * @see {@link getTransactionDecoder}\n * @see {@link getTransactionEncoder}\n */\nexport function getTransactionCodec(): VariableSizeCodec<Transaction> {\n return combineCodec(getTransactionEncoder(), getTransactionDecoder());\n}\n\ntype PartiallyDecodedTransaction = {\n messageBytes: ReadonlyUint8Array;\n signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedTransaction(transaction: PartiallyDecodedTransaction): Transaction {\n const { messageBytes, signatures } = transaction;\n\n /*\n Relevant message structure is at the start:\n - transaction version (0 bytes for legacy transactions, 1 byte for versioned transactions)\n - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n - `numReadOnlySignedAccounts` (1 byte, not used here)\n - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n - static addresses, with signers first. This is an array of addresses, prefixed with a short-u16 length\n */\n\n const signerAddressesDecoder = getTupleDecoder([\n // read transaction version\n getTransactionVersionDecoder(),\n // read first byte of header, `numSignerAccounts`\n // padRight to skip the next 2 bytes, `numReadOnlySignedAccounts` and `numReadOnlyUnsignedAccounts` which we don't need\n padRightDecoder(getU8Decoder(), 2),\n // read static addresses\n getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() }),\n ]);\n const [_txVersion, numRequiredSignatures, staticAddresses] = signerAddressesDecoder.decode(messageBytes);\n\n const signerAddresses = staticAddresses.slice(0, numRequiredSignatures);\n\n // signer addresses and signatures must be the same length\n // we encode an all-zero signature when the signature is missing\n if (signerAddresses.length !== signatures.length) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n numRequiredSignatures,\n signaturesLength: signatures.length,\n signerAddresses,\n });\n }\n\n // combine the signer addresses + signatures into the signatures map\n const signaturesMap: SignaturesMap = {};\n signerAddresses.forEach((address, index) => {\n const signatureForAddress = signatures[index];\n if (signatureForAddress.every(b => b === 0)) {\n signaturesMap[address] = null;\n } else {\n signaturesMap[address] = signatureForAddress as SignatureBytes;\n }\n });\n\n return {\n messageBytes: messageBytes as TransactionMessageBytes,\n signatures: Object.freeze(signaturesMap),\n };\n}\n","import { type Address, isAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n SolanaError,\n} from '@solana/errors';\nimport { type Blockhash, isBlockhash, type Slot } from '@solana/rpc-types';\nimport type {\n CompiledTransactionMessage,\n CompiledTransactionMessageWithLifetime,\n Nonce,\n TransactionMessage,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport type { Transaction } from './transaction';\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network. The transaction will continue to be eligible to land until the network considers the\n * `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type TransactionBlockhashLifetime = {\n /**\n * A recent blockhash observed by the transaction proposer.\n *\n * The transaction will be considered eligible to land until the network determines this\n * blockhash to be too old, or has switched to a fork where it is not present.\n */\n blockhash: Blockhash;\n /**\n * This is the block height beyond which the network will consider the blockhash to be too old\n * to make a transaction eligible to land.\n */\n lastValidBlockHeight: Slot;\n};\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionDurableNonceLifetime = {\n /**\n * A value contained in the account with address `nonceAccountAddress` at the time the\n * transaction was prepared.\n *\n * The transaction will be considered eligible to land until the nonce account ceases to exist\n * or contain this value.\n */\n nonce: Nonce;\n /** The account that contains the `nonce` value */\n nonceAccountAddress: Address;\n};\n\n/**\n * A transaction whose ability to land on the network is determined by some evanescent criteria.\n *\n * This describes a window of time after which a transaction is constructed and before which it will\n * no longer be accepted by the network.\n *\n * No transaction can land on Solana without having a `lifetimeConstraint` set.\n */\nexport type TransactionWithLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime | TransactionDurableNonceLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by the age of a blockhash observed on the network.\n *\n * The transaction will continue to be eligible to land until the network considers the `blockhash`\n * to be expired.\n */\nexport type TransactionWithBlockhashLifetime = {\n readonly lifetimeConstraint: TransactionBlockhashLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by a nonce.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionWithDurableNonceLifetime = {\n readonly lifetimeConstraint: TransactionDurableNonceLifetime;\n};\n\n/**\n * Helper type that sets the lifetime constraint of a transaction to be the same as the\n * lifetime constraint of the provided transaction message.\n *\n * If the transaction message has no explicit lifetime constraint, neither will the transaction.\n */\nexport type SetTransactionLifetimeFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends { lifetimeConstraint: unknown }\n ? TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithBlockhashLifetime['lifetimeConstraint']\n ? TransactionWithBlockhashLifetime & TTransaction\n : TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithDurableNonceLifetime['lifetimeConstraint']\n ? TransactionWithDurableNonceLifetime & TTransaction\n : TransactionWithLifetime & TTransaction\n : TTransaction;\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\n\nfunction compiledInstructionIsAdvanceNonceInstruction(\n instruction: CompiledTransactionMessage['instructions'][number],\n staticAddresses: Address[],\n): instruction is typeof instruction & { accountIndices: [number, number, number] } {\n return (\n staticAddresses[instruction.programAddressIndex] === SYSTEM_PROGRAM_ADDRESS &&\n // Test for `AdvanceNonceAccount` instruction data\n instruction.data != null &&\n isAdvanceNonceAccountInstructionData(instruction.data) &&\n // Test for exactly 3 accounts\n instruction.accountIndices?.length === 3\n );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): boolean {\n // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n\n/**\n * Get the lifetime constraint for a transaction from a compiled transaction message that includes a lifetime token.\n * @param compiledTransactionMessage A compiled transaction message that includes a lifetime token\n * @returns A lifetime constraint for the transaction\n * Note that this is less precise than checking a decompiled instruction, as we can't inspect\n * the address or role of input accounts (which may be in lookup tables). However, this is\n * sufficient for all valid advance durable nonce instructions.\n * Note that the program address must not be in a lookup table, see [this answer on StackExchange](https://solana.stackexchange.com/a/16224/289)\n * @see {@link isAdvanceNonceAccountInstruction}\n * Note that this function is async to allow for future implementations that may fetch `lastValidBlockHeight` using an RPC\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n): Promise<TransactionBlockhashLifetime | TransactionDurableNonceLifetime> {\n const firstInstruction = compiledTransactionMessage.instructions[0];\n const { staticAccounts } = compiledTransactionMessage;\n\n // We need to check if the first instruction is an AdvanceNonceAccount instruction\n if (firstInstruction && compiledInstructionIsAdvanceNonceInstruction(firstInstruction, staticAccounts)) {\n const nonceAccountAddress = staticAccounts[firstInstruction.accountIndices[0]];\n if (!nonceAccountAddress) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n nonce: compiledTransactionMessage.lifetimeToken,\n });\n }\n return {\n nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n nonceAccountAddress,\n };\n } else {\n return {\n blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n // This is not known from the compiled message, so we set it to the maximum possible value\n lastValidBlockHeight: 0xffffffffffffffffn,\n };\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * if (isTransactionWithBlockhashLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a `TransactionWithBlockhashLifetime`.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * setBlockhashIsValid(blockhashIsValid);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithBlockhashLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'blockhash' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.blockhash === 'string' &&\n typeof transaction.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n isBlockhash(transaction.lifetimeConstraint.blockhash)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * blockhash-based lifetime, from for example a wallet. Use this function to\n * assert that such a transaction actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithBlockhashLifetime`.\n * assertIsTransactionWithBlockhashLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithBlockhashLifetime` that can be used\n * // with the RPC.\n * const { blockhash } = transaction.lifetimeConstraint;\n * const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n * // `transaction` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithBlockhashLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithBlockhashLifetime {\n if (!isTransactionWithBlockhashLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithDurableNonceLifetime } from '@solana/transactions';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionWithDurableNonceLifetime(transaction)) {\n * // At this point, `transaction` has been refined to a\n * // `TransactionWithDurableNonceLifetime`.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * setNonceIsValid(nonce === actualNonce);\n * } else {\n * setError(\n * `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n * );\n * }\n * ```\n */\nexport function isTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithDurableNonceLifetime {\n return (\n 'lifetimeConstraint' in transaction &&\n 'nonce' in transaction.lifetimeConstraint &&\n typeof transaction.lifetimeConstraint.nonce === 'string' &&\n typeof transaction.lifetimeConstraint.nonceAccountAddress === 'string' &&\n isAddress(transaction.lifetimeConstraint.nonceAccountAddress)\n );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * nonce-based lifetime, from for example a wallet. Use this function to assert\n * that such a transaction actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithDurableNonceLifetime } from '@solana/transactions';\n *\n * try {\n * // If this type assertion function doesn't throw, then\n * // Typescript will upcast `transaction` to `TransactionWithDurableNonceLifetime`.\n * assertIsTransactionWithDurableNonceLifetime(transaction);\n * // At this point, `transaction` is a `TransactionWithDurableNonceLifetime` that can be used\n * // with the RPC.\n * const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n * const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n * // `transaction` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithDurableNonceLifetime(\n transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithDurableNonceLifetime {\n if (!isTransactionWithDurableNonceLifetime(transaction)) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n }\n}\n","import {\n BaseTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n isTransactionMessageWithDurableNonceLifetime,\n TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type { SignaturesMap, TransactionFromTransactionMessage, TransactionMessageBytes } from './transaction';\n\n/**\n * Returns a {@link Transaction} object for a given {@link TransactionMessage}.\n *\n * This includes the compiled bytes of the transaction message, and a map of signatures. This map\n * will have a key for each address that is required to sign the transaction. The transaction will\n * not yet have signatures for any of these addresses.\n *\n * Whether a transaction message is ready to be compiled or not is enforced for you at the type\n * level. In order to be signable, a transaction message must:\n *\n * - have a version and a list of zero or more instructions (ie. conform to\n * {@link BaseTransactionMessage})\n * - have a fee payer set (ie. conform to {@link TransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction<TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromTransactionMessage<TTransactionMessage>>;\n\n const compiledMessage = compileTransactionMessage(transactionMessage);\n const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage) as TransactionMessageBytes;\n\n const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);\n const signatures: SignaturesMap = {};\n for (const signerAddress of transactionSigners) {\n signatures[signerAddress] = null;\n }\n\n let lifetimeConstraint: TransactionWithLifetime['lifetimeConstraint'] | undefined;\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else if (isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n ...(lifetimeConstraint ? { lifetimeConstraint } : undefined),\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { bytesEqual, Decoder } from '@solana/codecs-core';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n SolanaError,\n} from '@solana/errors';\nimport { Signature, SignatureBytes, signBytes } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { Transaction } from './transaction';\n\n/**\n * Represents a transaction that is signed by all of its required signers. Being fully signed is a\n * prerequisite of functions designed to land transactions on the network.\n */\nexport type FullySignedTransaction = NominalType<'transactionSignedness', 'fullySigned'>;\n\nlet base58Decoder: Decoder<string> | undefined;\n\n/**\n * Given a transaction signed by its fee payer, this method will return the {@link Signature} that\n * uniquely identifies it. This string can be used to look up transactions at a later date, for\n * example on a Solana block explorer.\n *\n * @example\n * ```ts\n * import { getSignatureFromTransaction } from '@solana/transactions';\n *\n * const signature = getSignatureFromTransaction(tx);\n * console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n * ```\n */\nexport function getSignatureFromTransaction(transaction: Transaction): Signature {\n if (!base58Decoder) base58Decoder = getBase58Decoder();\n\n // We have ordered signatures from the compiled message accounts\n // first signature is the fee payer\n const signatureBytes = Object.values(transaction.signatures)[0];\n if (!signatureBytes) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n }\n const transactionSignature = base58Decoder.decode(signatureBytes);\n return transactionSignature as Signature;\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link Transaction}.\n *\n * Though the resulting transaction might have every signature it needs to land on the network, this\n * function will not assert that it does. A partially signed transaction cannot be landed on the\n * network, but can be serialized and deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignTransaction } from '@solana/transactions';\n *\n * const partiallySignedTransaction = await partiallySignTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link signTransaction} if you want to assert that the transaction has all of its required\n * signatures after signing.\n */\nexport async function partiallySignTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<TTransaction> {\n let newSignatures: Record<Address, SignatureBytes> | undefined;\n let unexpectedSigners: Set<Address> | undefined;\n\n await Promise.all(\n keyPairs.map(async keyPair => {\n const address = await getAddressFromPublicKey(keyPair.publicKey);\n const existingSignature = transaction.signatures[address];\n\n // Check if the address is expected to sign the transaction\n if (existingSignature === undefined) {\n // address is not an expected signer for this transaction\n unexpectedSigners ||= new Set();\n unexpectedSigners.add(address);\n return;\n }\n\n // Return if there are any unexpected signers already since we won't be using signatures\n if (unexpectedSigners) {\n return;\n }\n\n const newSignature = await signBytes(keyPair.privateKey, transaction.messageBytes);\n\n if (existingSignature !== null && bytesEqual(newSignature, existingSignature)) {\n // already have the same signature set\n return;\n }\n\n newSignatures ||= {};\n newSignatures[address] = newSignature;\n }),\n );\n\n if (unexpectedSigners && unexpectedSigners.size > 0) {\n const expectedSigners = Object.keys(transaction.signatures);\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n expectedAddresses: expectedSigners,\n unexpectedAddresses: [...unexpectedSigners],\n });\n }\n\n if (!newSignatures) {\n return transaction;\n }\n\n return Object.freeze({\n ...transaction,\n signatures: Object.freeze({\n ...transaction.signatures,\n ...newSignatures,\n }),\n });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link FullySignedTransaction}.\n *\n * This function will throw unless the resulting transaction is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signTransaction } from '@solana/transactions';\n *\n * const signedTransaction = await signTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link partiallySignTransaction} if you want to sign the transaction without asserting that\n * the resulting transaction is fully signed.\n */\nexport async function signTransaction<TTransaction extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: TTransaction,\n): Promise<FullySignedTransaction & TTransaction> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertIsFullySignedTransaction(out);\n Object.freeze(out);\n return out;\n}\n\n/**\n * Checks whether a given {@link Transaction} is fully signed.\n *\n * @example\n * ```ts\n * import { isFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isFullySignedTransaction(transaction)) {\n * // At this point we know that the transaction is signed and can be sent to the network.\n * }\n * ```\n */\nexport function isFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is FullySignedTransaction & TTransaction {\n return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link Transaction}, that you expect to be fully signed,\n * from an untrusted network API or user input. Use this function to assert that such a transaction\n * is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `FullySignedTransaction`.\n * assertIsFullySignedTransaction(transaction);\n * // At this point we know that the transaction is signed and can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsFullySignedTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is FullySignedTransaction & TTransaction {\n const missingSigs: Address[] = [];\n Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {\n if (!signatureBytes) {\n missingSigs.push(address as Address);\n }\n });\n\n if (missingSigs.length > 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n addresses: missingSigs,\n });\n }\n}\n","import { getBase64Decoder } from '@solana/codecs-strings';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/** Represents the wire format of a transaction as a base64-encoded string. */\nexport type Base64EncodedWireTransaction = Brand<EncodedString<string, 'base64'>, 'Base64EncodedWireTransaction'>;\n\n/**\n * Given a signed transaction, this method returns the transaction as a string that conforms to the\n * {@link Base64EncodedWireTransaction} type.\n *\n * @example\n * ```ts\n * import { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n *\n * const serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n * const signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n * ```\n */\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { NominalType } from '@solana/nominal-types';\nimport type { BaseTransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/**\n * The maximum size of a transaction packet in bytes.\n */\nexport const TRANSACTION_PACKET_SIZE = 1280;\n\n/**\n * The size of the transaction packet header in bytes.\n * This includes the IPv6 header and the fragment header.\n */\nexport const TRANSACTION_PACKET_HEADER =\n 40 /* 40 bytes is the size of the IPv6 header. */ + 8; /* 8 bytes is the size of the fragment header. */\n\n/**\n * The maximum size of a transaction in bytes.\n *\n * Note that this excludes the transaction packet header.\n * In other words, this is how much content we can fit in a transaction packet.\n */\nexport const TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;\n\n/**\n * Gets the size of a given transaction in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionSize(transaction);\n * ```\n */\nexport function getTransactionSize(transaction: Transaction): number {\n return getTransactionEncoder().getSizeFromValue(transaction);\n}\n\n/**\n * A type guard that checks if a transaction is within the size limit.\n */\nexport type TransactionWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that adds the `TransactionWithinSizeLimit` flag to\n * a transaction if and only if the provided transaction message\n * is also within the size limit.\n */\nexport type SetTransactionWithinSizeLimitFromTransactionMessage<\n TTransaction extends Transaction,\n TTransactionMessage extends BaseTransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithinSizeLimit\n ? TransactionWithinSizeLimit & TTransaction\n : TTransaction;\n\n/**\n * Checks if a transaction is within the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * if (isTransactionWithinSizeLimit(transaction)) {\n * transaction satisfies TransactionWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is TransactionWithinSizeLimit & TTransaction {\n return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction is within the size limit.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction exceeds the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * assertIsTransactionWithinSizeLimit(transaction);\n * transaction satisfies TransactionWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionWithinSizeLimit<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is TransactionWithinSizeLimit & TTransaction {\n const transactionSize = getTransactionSize(transaction);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n","import { assertIsFullySignedTransaction, FullySignedTransaction, isFullySignedTransaction } from './signatures';\nimport { Transaction } from './transaction';\nimport {\n assertIsTransactionWithinSizeLimit,\n isTransactionWithinSizeLimit,\n TransactionWithinSizeLimit,\n} from './transaction-size';\n\n/**\n * Helper type that includes all transaction types required\n * for the transaction to be sent to the network.\n *\n * @see {@link isSendableTransaction}\n * @see {@link assertIsSendableTransaction}\n */\nexport type SendableTransaction = FullySignedTransaction & TransactionWithinSizeLimit;\n\n/**\n * Checks if a transaction has all the required\n * conditions to be sent to the network.\n *\n * @example\n * ```ts\n * import { isSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isSendableTransaction(transaction)) {\n * // At this point we know that the transaction can be sent to the network.\n * }\n * ```\n *\n * @see {@link assertIsSendableTransaction}\n */\nexport function isSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): transaction is SendableTransaction & TTransaction {\n return isFullySignedTransaction(transaction) && isTransactionWithinSizeLimit(transaction);\n}\n\n/**\n * Asserts that a given transaction has all the\n * required conditions to be sent to the network.\n *\n * From time to time you might acquire a {@link Transaction}\n * from an untrusted network API or user input and you are not sure\n * that it has all the required conditions to be sent to the network\n * — such as being fully signed and within the size limit.\n * This function can be used to assert that such a transaction\n * is in fact sendable.\n *\n * @example\n * ```ts\n * import { assertIsSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n * // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n * // to `SendableTransaction`.\n * assertIsSendableTransaction(transaction);\n * // At this point we know that the transaction can be sent to the network.\n * await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n * if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n * setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n * } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n * setError(`Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes`);\n * }\n * throw;\n * }\n * ```\n */\nexport function assertIsSendableTransaction<TTransaction extends Transaction>(\n transaction: TTransaction,\n): asserts transaction is SendableTransaction & TTransaction {\n assertIsFullySignedTransaction(transaction);\n assertIsTransactionWithinSizeLimit(transaction);\n}\n","import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type {\n BaseTransactionMessage,\n TransactionMessageWithFeePayer,\n TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from './compile-transaction';\nimport { getTransactionSize, TRANSACTION_SIZE_LIMIT } from './transaction-size';\n\n/**\n * Gets the compiled transaction size of a given transaction message in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionMessageSize(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSize(\n transactionMessage: BaseTransactionMessage & TransactionMessageWithFeePayer,\n): number {\n return getTransactionSize(compileTransaction(transactionMessage));\n}\n\n/**\n * Checks if a transaction message is within the size limit\n * when compiled into a transaction.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Asserts that a given transaction message is within the size limit\n * when compiled into a transaction.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction message exceeds the size limit.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionMessageWithinSizeLimit<\n TTransactionMessage extends BaseTransactionMessage & TransactionMessageWithFeePayer,\n>(\n transactionMessage: TTransactionMessage,\n): asserts transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n const transactionSize = getTransactionMessageSize(transactionMessage);\n if (transactionSize > TRANSACTION_SIZE_LIMIT) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n transactionSize,\n transactionSizeLimit: TRANSACTION_SIZE_LIMIT,\n });\n }\n}\n"]}
@@ -231,7 +231,9 @@ function getBase64EncodedWireTransaction(transaction) {
231
231
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
232
232
  return getBase64Decoder().decode(wireTransactionBytes);
233
233
  }
234
- var TRANSACTION_SIZE_LIMIT = 4096;
234
+ var TRANSACTION_PACKET_SIZE = 1280;
235
+ var TRANSACTION_PACKET_HEADER = 40 + 8;
236
+ var TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;
235
237
  function getTransactionSize(transaction) {
236
238
  return getTransactionEncoder().getSizeFromValue(transaction);
237
239
  }
@@ -272,6 +274,6 @@ function assertIsTransactionMessageWithinSizeLimit(transactionMessage) {
272
274
  }
273
275
  }
274
276
 
275
- export { TRANSACTION_SIZE_LIMIT, assertIsFullySignedTransaction, assertIsSendableTransaction, assertIsTransactionMessageWithinSizeLimit, assertIsTransactionWithBlockhashLifetime, assertIsTransactionWithDurableNonceLifetime, assertIsTransactionWithinSizeLimit, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getTransactionLifetimeConstraintFromCompiledTransactionMessage, getTransactionMessageSize, getTransactionSize, isFullySignedTransaction, isSendableTransaction, isTransactionMessageWithinSizeLimit, isTransactionWithBlockhashLifetime, isTransactionWithDurableNonceLifetime, isTransactionWithinSizeLimit, partiallySignTransaction, signTransaction };
277
+ export { TRANSACTION_PACKET_HEADER, TRANSACTION_PACKET_SIZE, TRANSACTION_SIZE_LIMIT, assertIsFullySignedTransaction, assertIsSendableTransaction, assertIsTransactionMessageWithinSizeLimit, assertIsTransactionWithBlockhashLifetime, assertIsTransactionWithDurableNonceLifetime, assertIsTransactionWithinSizeLimit, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getTransactionLifetimeConstraintFromCompiledTransactionMessage, getTransactionMessageSize, getTransactionSize, isFullySignedTransaction, isSendableTransaction, isTransactionMessageWithinSizeLimit, isTransactionWithBlockhashLifetime, isTransactionWithDurableNonceLifetime, isTransactionWithinSizeLimit, partiallySignTransaction, signTransaction };
276
278
  //# sourceMappingURL=index.node.mjs.map
277
279
  //# sourceMappingURL=index.node.mjs.map