@solana/transactions 2.2.1 → 2.3.0-canary-20250708190258

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.
package/README.md CHANGED
@@ -26,7 +26,7 @@ Given a `TransactionMessage`, this function returns a `Transaction` object. This
26
26
  Whether a transaction message is ready to be compiled or not is enforced for you at the type level. In order to be signable, a transaction message must:
27
27
 
28
28
  - have a version and a list of zero or more instructions (ie. conform to `BaseTransactionMessage`)
29
- - have a fee payer set (ie. conform to `ITransactionMessageWithFeePayer`)
29
+ - have a fee payer set (ie. conform to `TransactionMessageWithFeePayer`)
30
30
  - have a lifetime specified (ie. conform to `TransactionMessageWithBlockhashLifetime | TransactionMessageWithDurableNonceLifetime`)
31
31
 
32
32
  ## Signing transactions
@@ -102,12 +102,11 @@ function compileTransaction(transactionMessage) {
102
102
  nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address
103
103
  };
104
104
  }
105
- const transaction = {
105
+ return Object.freeze({
106
106
  lifetimeConstraint,
107
107
  messageBytes,
108
108
  signatures: Object.freeze(signatures)
109
- };
110
- return Object.freeze(transaction);
109
+ });
111
110
  }
112
111
  var base58Decoder;
113
112
  function getSignatureFromTransaction(transaction) {
@@ -165,11 +164,14 @@ async function partiallySignTransaction(keyPairs, transaction) {
165
164
  }
166
165
  async function signTransaction(keyPairs, transaction) {
167
166
  const out = await partiallySignTransaction(keyPairs, transaction);
168
- assertTransactionIsFullySigned(out);
167
+ assertIsFullySignedTransaction(out);
169
168
  Object.freeze(out);
170
169
  return out;
171
170
  }
172
- function assertTransactionIsFullySigned(transaction) {
171
+ function isFullySignedTransaction(transaction) {
172
+ return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);
173
+ }
174
+ function assertIsFullySignedTransaction(transaction) {
173
175
  const missingSigs = [];
174
176
  Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {
175
177
  if (!signatureBytes) {
@@ -186,7 +188,51 @@ function getBase64EncodedWireTransaction(transaction) {
186
188
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
187
189
  return codecsStrings.getBase64Decoder().decode(wireTransactionBytes);
188
190
  }
191
+ var TRANSACTION_PACKET_SIZE = 1280;
192
+ var TRANSACTION_PACKET_HEADER = 40 + 8;
193
+ var TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;
194
+ function getTransactionSize(transaction) {
195
+ return getTransactionEncoder().getSizeFromValue(transaction);
196
+ }
197
+ function isTransactionWithinSizeLimit(transaction) {
198
+ return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;
199
+ }
200
+ function assertIsTransactionWithinSizeLimit(transaction) {
201
+ const transactionSize = getTransactionSize(transaction);
202
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
203
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
204
+ transactionSize,
205
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
206
+ });
207
+ }
208
+ }
209
+
210
+ // src/transaction-message-size.ts
211
+ function getTransactionMessageSize(transactionMessage) {
212
+ return getTransactionSize(compileTransaction(transactionMessage));
213
+ }
214
+ function isTransactionMessageWithinSizeLimit(transactionMessage) {
215
+ return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;
216
+ }
217
+ function assertIsTransactionMessageWithinSizeLimit(transactionMessage) {
218
+ const transactionSize = getTransactionMessageSize(transactionMessage);
219
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
220
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
221
+ transactionSize,
222
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
223
+ });
224
+ }
225
+ }
226
+
227
+ // src/deprecated.ts
228
+ var assertTransactionIsFullySigned = assertIsFullySignedTransaction;
189
229
 
230
+ exports.TRANSACTION_PACKET_HEADER = TRANSACTION_PACKET_HEADER;
231
+ exports.TRANSACTION_PACKET_SIZE = TRANSACTION_PACKET_SIZE;
232
+ exports.TRANSACTION_SIZE_LIMIT = TRANSACTION_SIZE_LIMIT;
233
+ exports.assertIsFullySignedTransaction = assertIsFullySignedTransaction;
234
+ exports.assertIsTransactionMessageWithinSizeLimit = assertIsTransactionMessageWithinSizeLimit;
235
+ exports.assertIsTransactionWithinSizeLimit = assertIsTransactionWithinSizeLimit;
190
236
  exports.assertTransactionIsFullySigned = assertTransactionIsFullySigned;
191
237
  exports.compileTransaction = compileTransaction;
192
238
  exports.getBase64EncodedWireTransaction = getBase64EncodedWireTransaction;
@@ -194,6 +240,11 @@ exports.getSignatureFromTransaction = getSignatureFromTransaction;
194
240
  exports.getTransactionCodec = getTransactionCodec;
195
241
  exports.getTransactionDecoder = getTransactionDecoder;
196
242
  exports.getTransactionEncoder = getTransactionEncoder;
243
+ exports.getTransactionMessageSize = getTransactionMessageSize;
244
+ exports.getTransactionSize = getTransactionSize;
245
+ exports.isFullySignedTransaction = isFullySignedTransaction;
246
+ exports.isTransactionMessageWithinSizeLimit = isTransactionMessageWithinSizeLimit;
247
+ exports.isTransactionWithinSizeLimit = isTransactionWithinSizeLimit;
197
248
  exports.partiallySignTransaction = partiallySignTransaction;
198
249
  exports.signTransaction = signTransaction;
199
250
  //# sourceMappingURL=index.browser.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.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","compileTransactionMessage","getCompiledTransactionMessageEncoder","isTransactionMessageWithBlockhashLifetime","getBase58Decoder","SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING","getAddressFromPublicKey","signBytes","SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION","SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING","getBase64Decoder"],"mappings":"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","file":"index.browser.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 {\n CompilableTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n TransactionWithLifetime,\n} from './lifetime';\nimport { SignaturesMap, Transaction, 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 ITransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage & TransactionMessageWithBlockhashLifetime,\n): Readonly<Transaction & TransactionWithBlockhashLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage & TransactionMessageWithDurableNonceLifetime,\n): Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage,\n): Readonly<Transaction & TransactionWithLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage,\n): Readonly<Transaction & TransactionWithLifetime> {\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'];\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n const transaction: Transaction & TransactionWithLifetime = {\n lifetimeConstraint,\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n };\n\n return Object.freeze(transaction);\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { 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'> & Transaction;\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\nfunction uint8ArraysEqual(arr1: Uint8Array, arr2: Uint8Array) {\n return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);\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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<T> {\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 && uint8ArraysEqual(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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<FullySignedTransaction & T> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertTransactionIsFullySigned(out);\n Object.freeze(out);\n return out;\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 { assertTransactionIsFullySigned } 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 * assertTransactionIsFullySigned(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 */\nexport function assertTransactionIsFullySigned(\n transaction: Transaction,\n): asserts transaction is FullySignedTransaction {\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"]}
1
+ {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/transaction-message-size.ts","../src/deprecated.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","compileTransactionMessage","getCompiledTransactionMessageEncoder","isTransactionMessageWithBlockhashLifetime","getBase58Decoder","SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING","getAddressFromPublicKey","signBytes","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.browser.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 {\n CompilableTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type {\n SignaturesMap,\n TransactionFromCompilableTransactionMessage,\n TransactionMessageBytes,\n} 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 CompilableTransactionMessage>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromCompilableTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromCompilableTransactionMessage<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'];\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n lifetimeConstraint,\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { 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'> & Transaction;\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\nfunction uint8ArraysEqual(arr1: Uint8Array, arr2: Uint8Array) {\n return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);\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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<T> {\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 && uint8ArraysEqual(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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<FullySignedTransaction & T> {\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 { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { CompilableTransactionMessage, TransactionMessageWithinSizeLimit } 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(transactionMessage: CompilableTransactionMessage): 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<TTransactionMessage extends CompilableTransactionMessage>(\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<TTransactionMessage extends CompilableTransactionMessage>(\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","import { assertIsFullySignedTransaction } from './signatures';\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 * @deprecated Use {@link assertIsFullySignedTransaction} instead. It was only renamed.\n *\n * @example\n * ```ts\n * import { assertTransactionIsFullySigned } 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 * assertTransactionIsFullySigned(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 const assertTransactionIsFullySigned = assertIsFullySignedTransaction;\n"]}
@@ -2,7 +2,7 @@ import { getAddressDecoder, getAddressFromPublicKey } from '@solana/addresses';
2
2
  import { transformDecoder, fixDecoderSize, combineCodec, padRightDecoder, transformEncoder, fixEncoderSize } from '@solana/codecs-core';
3
3
  import { getStructEncoder, getBytesEncoder, getStructDecoder, getArrayDecoder, getBytesDecoder, getTupleDecoder, getArrayEncoder } from '@solana/codecs-data-structures';
4
4
  import { getShortU16Decoder, getU8Decoder, getShortU16Encoder } from '@solana/codecs-numbers';
5
- import { SolanaError, SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES } from '@solana/errors';
5
+ import { SolanaError, SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES } from '@solana/errors';
6
6
  import { getTransactionVersionDecoder, compileTransactionMessage, getCompiledTransactionMessageEncoder, isTransactionMessageWithBlockhashLifetime } from '@solana/transaction-messages';
7
7
  import { getBase58Decoder, getBase64Decoder } from '@solana/codecs-strings';
8
8
  import { signBytes } from '@solana/keys';
@@ -100,12 +100,11 @@ function compileTransaction(transactionMessage) {
100
100
  nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address
101
101
  };
102
102
  }
103
- const transaction = {
103
+ return Object.freeze({
104
104
  lifetimeConstraint,
105
105
  messageBytes,
106
106
  signatures: Object.freeze(signatures)
107
- };
108
- return Object.freeze(transaction);
107
+ });
109
108
  }
110
109
  var base58Decoder;
111
110
  function getSignatureFromTransaction(transaction) {
@@ -163,11 +162,14 @@ async function partiallySignTransaction(keyPairs, transaction) {
163
162
  }
164
163
  async function signTransaction(keyPairs, transaction) {
165
164
  const out = await partiallySignTransaction(keyPairs, transaction);
166
- assertTransactionIsFullySigned(out);
165
+ assertIsFullySignedTransaction(out);
167
166
  Object.freeze(out);
168
167
  return out;
169
168
  }
170
- function assertTransactionIsFullySigned(transaction) {
169
+ function isFullySignedTransaction(transaction) {
170
+ return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);
171
+ }
172
+ function assertIsFullySignedTransaction(transaction) {
171
173
  const missingSigs = [];
172
174
  Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {
173
175
  if (!signatureBytes) {
@@ -184,7 +186,45 @@ function getBase64EncodedWireTransaction(transaction) {
184
186
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
185
187
  return getBase64Decoder().decode(wireTransactionBytes);
186
188
  }
189
+ var TRANSACTION_PACKET_SIZE = 1280;
190
+ var TRANSACTION_PACKET_HEADER = 40 + 8;
191
+ var TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;
192
+ function getTransactionSize(transaction) {
193
+ return getTransactionEncoder().getSizeFromValue(transaction);
194
+ }
195
+ function isTransactionWithinSizeLimit(transaction) {
196
+ return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;
197
+ }
198
+ function assertIsTransactionWithinSizeLimit(transaction) {
199
+ const transactionSize = getTransactionSize(transaction);
200
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
201
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
202
+ transactionSize,
203
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
204
+ });
205
+ }
206
+ }
207
+
208
+ // src/transaction-message-size.ts
209
+ function getTransactionMessageSize(transactionMessage) {
210
+ return getTransactionSize(compileTransaction(transactionMessage));
211
+ }
212
+ function isTransactionMessageWithinSizeLimit(transactionMessage) {
213
+ return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;
214
+ }
215
+ function assertIsTransactionMessageWithinSizeLimit(transactionMessage) {
216
+ const transactionSize = getTransactionMessageSize(transactionMessage);
217
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
218
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
219
+ transactionSize,
220
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
221
+ });
222
+ }
223
+ }
224
+
225
+ // src/deprecated.ts
226
+ var assertTransactionIsFullySigned = assertIsFullySignedTransaction;
187
227
 
188
- export { assertTransactionIsFullySigned, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, partiallySignTransaction, signTransaction };
228
+ export { TRANSACTION_PACKET_HEADER, TRANSACTION_PACKET_SIZE, TRANSACTION_SIZE_LIMIT, assertIsFullySignedTransaction, assertIsTransactionMessageWithinSizeLimit, assertIsTransactionWithinSizeLimit, assertTransactionIsFullySigned, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getTransactionMessageSize, getTransactionSize, isFullySignedTransaction, isTransactionMessageWithinSizeLimit, isTransactionWithinSizeLimit, partiallySignTransaction, signTransaction };
189
229
  //# sourceMappingURL=index.browser.mjs.map
190
230
  //# sourceMappingURL=index.browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts"],"names":["getBytesEncoder","SolanaError"],"mappings":"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","file":"index.browser.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 {\n CompilableTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n TransactionMessageWithBlockhashLifetime,\n TransactionMessageWithDurableNonceLifetime,\n} from '@solana/transaction-messages';\n\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n TransactionWithLifetime,\n} from './lifetime';\nimport { SignaturesMap, Transaction, 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 ITransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n * {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage & TransactionMessageWithBlockhashLifetime,\n): Readonly<Transaction & TransactionWithBlockhashLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage & TransactionMessageWithDurableNonceLifetime,\n): Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage,\n): Readonly<Transaction & TransactionWithLifetime>;\n\nexport function compileTransaction(\n transactionMessage: CompilableTransactionMessage,\n): Readonly<Transaction & TransactionWithLifetime> {\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'];\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n const transaction: Transaction & TransactionWithLifetime = {\n lifetimeConstraint,\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n };\n\n return Object.freeze(transaction);\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { 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'> & Transaction;\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\nfunction uint8ArraysEqual(arr1: Uint8Array, arr2: Uint8Array) {\n return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);\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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<T> {\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 && uint8ArraysEqual(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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<FullySignedTransaction & T> {\n const out = await partiallySignTransaction(keyPairs, transaction);\n assertTransactionIsFullySigned(out);\n Object.freeze(out);\n return out;\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 { assertTransactionIsFullySigned } 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 * assertTransactionIsFullySigned(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 */\nexport function assertTransactionIsFullySigned(\n transaction: Transaction,\n): asserts transaction is FullySignedTransaction {\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"]}
1
+ {"version":3,"sources":["../src/codecs/signatures-encoder.ts","../src/codecs/transaction-codec.ts","../src/compile-transaction.ts","../src/signatures.ts","../src/wire-transaction.ts","../src/transaction-size.ts","../src/transaction-message-size.ts","../src/deprecated.ts"],"names":["getBytesEncoder","SolanaError","SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT"],"mappings":";;;;;;;;;;AAQA,SAAS,sBAAsB,aAAgD,EAAA;AAC3E,EAAM,MAAA,UAAA,GAAa,MAAO,CAAA,MAAA,CAAO,aAAa,CAAA;AAC9C,EAAI,IAAA,UAAA,CAAW,WAAW,CAAG,EAAA;AACzB,IAAM,MAAA,IAAI,YAAY,8DAA8D,CAAA;AAAA;AAGxF,EAAO,OAAA,UAAA,CAAW,IAAI,CAAa,SAAA,KAAA;AAC/B,IAAA,IAAI,CAAC,SAAW,EAAA;AACZ,MAAA,OAAO,IAAI,UAAA,CAAW,EAAE,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA;AAEpC,IAAO,OAAA,SAAA;AAAA,GACV,CAAA;AACL;AAEO,SAAS,oBAA2D,GAAA;AACvE,EAAO,OAAA,gBAAA;AAAA,IACH,eAAA,CAAgB,cAAe,CAAA,eAAA,EAAmB,EAAA,EAAE,GAAG,EAAE,IAAA,EAAM,kBAAmB,EAAA,EAAG,CAAA;AAAA,IACrF;AAAA,GACJ;AACJ;;;ACIO,SAAS,qBAA0D,GAAA;AACtE,EAAA,OAAO,gBAAiB,CAAA;AAAA,IACpB,CAAC,YAAc,EAAA,oBAAA,EAAsB,CAAA;AAAA,IACrC,CAAC,cAAgBA,EAAAA,eAAAA,EAAiB;AAAA,GACrC,CAAA;AACL;AAkBO,SAAS,qBAA0D,GAAA;AACtE,EAAO,OAAA,gBAAA;AAAA,IACH,gBAAiB,CAAA;AAAA,MACb,CAAC,YAAA,EAAc,eAAgB,CAAA,cAAA,CAAe,eAAgB,EAAA,EAAG,EAAE,CAAA,EAAG,EAAE,IAAA,EAAM,kBAAmB,EAAA,EAAG,CAAC,CAAA;AAAA,MACrG,CAAC,cAAgB,EAAA,eAAA,EAAiB;AAAA,KACrC,CAAA;AAAA,IACD;AAAA,GACJ;AACJ;AAQO,SAAS,mBAAsD,GAAA;AAClE,EAAA,OAAO,YAAa,CAAA,qBAAA,EAAyB,EAAA,qBAAA,EAAuB,CAAA;AACxE;AAOA,SAAS,kCAAkC,WAAuD,EAAA;AAC9F,EAAM,MAAA,EAAE,YAAc,EAAA,UAAA,EAAe,GAAA,WAAA;AAWrC,EAAA,MAAM,yBAAyB,eAAgB,CAAA;AAAA;AAAA,IAE3C,4BAA6B,EAAA;AAAA;AAAA;AAAA,IAG7B,eAAA,CAAgB,YAAa,EAAA,EAAG,CAAC,CAAA;AAAA;AAAA,IAEjC,gBAAgB,iBAAkB,EAAA,EAAG,EAAE,IAAM,EAAA,kBAAA,IAAsB;AAAA,GACtE,CAAA;AACD,EAAA,MAAM,CAAC,UAAY,EAAA,qBAAA,EAAuB,eAAe,CAAI,GAAA,sBAAA,CAAuB,OAAO,YAAY,CAAA;AAEvG,EAAA,MAAM,eAAkB,GAAA,eAAA,CAAgB,KAAM,CAAA,CAAA,EAAG,qBAAqB,CAAA;AAItE,EAAI,IAAA,eAAA,CAAgB,MAAW,KAAA,UAAA,CAAW,MAAQ,EAAA;AAC9C,IAAM,MAAA,IAAIC,YAAY,sDAAwD,EAAA;AAAA,MAC1E,qBAAA;AAAA,MACA,kBAAkB,UAAW,CAAA,MAAA;AAAA,MAC7B;AAAA,KACH,CAAA;AAAA;AAIL,EAAA,MAAM,gBAA+B,EAAC;AACtC,EAAgB,eAAA,CAAA,OAAA,CAAQ,CAAC,OAAA,EAAS,KAAU,KAAA;AACxC,IAAM,MAAA,mBAAA,GAAsB,WAAW,KAAK,CAAA;AAC5C,IAAA,IAAI,mBAAoB,CAAA,KAAA,CAAM,CAAK,CAAA,KAAA,CAAA,KAAM,CAAC,CAAG,EAAA;AACzC,MAAA,aAAA,CAAc,OAAO,CAAI,GAAA,IAAA;AAAA,KACtB,MAAA;AACH,MAAA,aAAA,CAAc,OAAO,CAAI,GAAA,mBAAA;AAAA;AAC7B,GACH,CAAA;AAED,EAAO,OAAA;AAAA,IACH,YAAA;AAAA,IACA,UAAA,EAAY,MAAO,CAAA,MAAA,CAAO,aAAa;AAAA,GAC3C;AACJ;ACnGO,SAAS,mBACZ,kBAC0E,EAAA;AAG1E,EAAM,MAAA,eAAA,GAAkB,0BAA0B,kBAAkB,CAAA;AACpE,EAAA,MAAM,YAAe,GAAA,oCAAA,EAAuC,CAAA,MAAA,CAAO,eAAe,CAAA;AAElF,EAAA,MAAM,qBAAqB,eAAgB,CAAA,cAAA,CAAe,MAAM,CAAG,EAAA,eAAA,CAAgB,OAAO,iBAAiB,CAAA;AAC3G,EAAA,MAAM,aAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,iBAAiB,kBAAoB,EAAA;AAC5C,IAAA,UAAA,CAAW,aAAa,CAAI,GAAA,IAAA;AAAA;AAGhC,EAAI,IAAA,kBAAA;AACJ,EAAI,IAAA,yCAAA,CAA0C,kBAAkB,CAAG,EAAA;AAC/D,IAAqB,kBAAA,GAAA;AAAA,MACjB,SAAA,EAAW,mBAAmB,kBAAmB,CAAA,SAAA;AAAA,MACjD,oBAAA,EAAsB,mBAAmB,kBAAmB,CAAA;AAAA,KAChE;AAAA,GACG,MAAA;AACH,IAAqB,kBAAA,GAAA;AAAA,MACjB,KAAA,EAAO,mBAAmB,kBAAmB,CAAA,KAAA;AAAA,MAC7C,qBAAqB,kBAAmB,CAAA,YAAA,CAAa,CAAC,CAAE,CAAA,QAAA,CAAS,CAAC,CAAE,CAAA;AAAA,KACxE;AAAA;AAGJ,EAAA,OAAO,OAAO,MAAO,CAAA;AAAA,IACjB,kBAAA;AAAA,IACA,YAAA;AAAA,IACA,UAAA,EAAY,MAAO,CAAA,MAAA,CAAO,UAAU;AAAA,GACvC,CAAA;AACL;AC1CA,IAAI,aAAA;AAeG,SAAS,4BAA4B,WAAqC,EAAA;AAC7E,EAAI,IAAA,CAAC,aAAe,EAAA,aAAA,GAAgB,gBAAiB,EAAA;AAIrD,EAAA,MAAM,iBAAiB,MAAO,CAAA,MAAA,CAAO,WAAY,CAAA,UAAU,EAAE,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAC,cAAgB,EAAA;AACjB,IAAM,MAAA,IAAIA,YAAY,sDAAsD,CAAA;AAAA;AAEhF,EAAM,MAAA,oBAAA,GAAuB,aAAc,CAAA,MAAA,CAAO,cAAc,CAAA;AAChE,EAAO,OAAA,oBAAA;AACX;AAEA,SAAS,gBAAA,CAAiB,MAAkB,IAAkB,EAAA;AAC1D,EAAA,OAAO,IAAK,CAAA,MAAA,KAAW,IAAK,CAAA,MAAA,IAAU,IAAK,CAAA,KAAA,CAAM,CAAC,KAAA,EAAO,KAAU,KAAA,KAAA,KAAU,IAAK,CAAA,KAAK,CAAC,CAAA;AAC5F;AAsBA,eAAsB,wBAAA,CAClB,UACA,WACU,EAAA;AACV,EAAI,IAAA,aAAA;AACJ,EAAI,IAAA,iBAAA;AAEJ,EAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,IACV,QAAA,CAAS,GAAI,CAAA,OAAM,OAAW,KAAA;AAC1B,MAAA,MAAM,OAAU,GAAA,MAAM,uBAAwB,CAAA,OAAA,CAAQ,SAAS,CAAA;AAC/D,MAAM,MAAA,iBAAA,GAAoB,WAAY,CAAA,UAAA,CAAW,OAAO,CAAA;AAGxD,MAAA,IAAI,sBAAsB,MAAW,EAAA;AAEjC,QAAA,iBAAA,yBAA0B,GAAI,EAAA;AAC9B,QAAA,iBAAA,CAAkB,IAAI,OAAO,CAAA;AAC7B,QAAA;AAAA;AAIJ,MAAA,IAAI,iBAAmB,EAAA;AACnB,QAAA;AAAA;AAGJ,MAAA,MAAM,eAAe,MAAM,SAAA,CAAU,OAAQ,CAAA,UAAA,EAAY,YAAY,YAAY,CAAA;AAEjF,MAAA,IAAI,iBAAsB,KAAA,IAAA,IAAQ,gBAAiB,CAAA,YAAA,EAAc,iBAAiB,CAAG,EAAA;AAEjF,QAAA;AAAA;AAGJ,MAAA,aAAA,KAAkB,EAAC;AACnB,MAAA,aAAA,CAAc,OAAO,CAAI,GAAA,YAAA;AAAA,KAC5B;AAAA,GACL;AAEA,EAAI,IAAA,iBAAA,IAAqB,iBAAkB,CAAA,IAAA,GAAO,CAAG,EAAA;AACjD,IAAA,MAAM,eAAkB,GAAA,MAAA,CAAO,IAAK,CAAA,WAAA,CAAY,UAAU,CAAA;AAC1D,IAAM,MAAA,IAAIA,YAAY,4DAA8D,EAAA;AAAA,MAChF,iBAAmB,EAAA,eAAA;AAAA,MACnB,mBAAA,EAAqB,CAAC,GAAG,iBAAiB;AAAA,KAC7C,CAAA;AAAA;AAGL,EAAA,IAAI,CAAC,aAAe,EAAA;AAChB,IAAO,OAAA,WAAA;AAAA;AAGX,EAAA,OAAO,OAAO,MAAO,CAAA;AAAA,IACjB,GAAG,WAAA;AAAA,IACH,UAAA,EAAY,OAAO,MAAO,CAAA;AAAA,MACtB,GAAG,WAAY,CAAA,UAAA;AAAA,MACf,GAAG;AAAA,KACN;AAAA,GACJ,CAAA;AACL;AAoBA,eAAsB,eAAA,CAClB,UACA,WACmC,EAAA;AACnC,EAAA,MAAM,GAAM,GAAA,MAAM,wBAAyB,CAAA,QAAA,EAAU,WAAW,CAAA;AAChE,EAAA,8BAAA,CAA+B,GAAG,CAAA;AAClC,EAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AACjB,EAAO,OAAA,GAAA;AACX;AAeO,SAAS,yBACZ,WACoD,EAAA;AACpD,EAAA,OAAO,MAAO,CAAA,OAAA,CAAQ,WAAY,CAAA,UAAU,CAAE,CAAA,KAAA,CAAM,CAAC,CAAC,CAAG,EAAA,cAAc,CAAM,KAAA,CAAC,CAAC,cAAc,CAAA;AACjG;AA0BO,SAAS,+BACZ,WAC4D,EAAA;AAC5D,EAAA,MAAM,cAAyB,EAAC;AAChC,EAAO,MAAA,CAAA,OAAA,CAAQ,YAAY,UAAU,CAAA,CAAE,QAAQ,CAAC,CAAC,OAAS,EAAA,cAAc,CAAM,KAAA;AAC1E,IAAA,IAAI,CAAC,cAAgB,EAAA;AACjB,MAAA,WAAA,CAAY,KAAK,OAAkB,CAAA;AAAA;AACvC,GACH,CAAA;AAED,EAAI,IAAA,WAAA,CAAY,SAAS,CAAG,EAAA;AACxB,IAAM,MAAA,IAAIA,YAAY,6CAA+C,EAAA;AAAA,MACjE,SAAW,EAAA;AAAA,KACd,CAAA;AAAA;AAET;ACnMO,SAAS,gCAAgC,WAAwD,EAAA;AACpG,EAAA,MAAM,oBAAuB,GAAA,qBAAA,EAAwB,CAAA,MAAA,CAAO,WAAW,CAAA;AACvE,EAAO,OAAA,gBAAA,EAAmB,CAAA,MAAA,CAAO,oBAAoB,CAAA;AACzD;ACdO,IAAM,uBAA0B,GAAA;AAMhC,IAAM,4BACT,EAAoD,GAAA;AAQjD,IAAM,yBAAyB,uBAA0B,GAAA;AAUzD,SAAS,mBAAmB,WAAkC,EAAA;AACjE,EAAO,OAAA,qBAAA,EAAwB,CAAA,gBAAA,CAAiB,WAAW,CAAA;AAC/D;AA+BO,SAAS,6BACZ,WACwD,EAAA;AACxD,EAAO,OAAA,kBAAA,CAAmB,WAAW,CAAK,IAAA,sBAAA;AAC9C;AAgBO,SAAS,mCACZ,WACgE,EAAA;AAChE,EAAM,MAAA,eAAA,GAAkB,mBAAmB,WAAW,CAAA;AACtD,EAAA,IAAI,kBAAkB,sBAAwB,EAAA;AAC1C,IAAM,MAAA,IAAIA,YAAY,6CAA+C,EAAA;AAAA,MACjE,eAAA;AAAA,MACA,oBAAsB,EAAA;AAAA,KACzB,CAAA;AAAA;AAET;;;ACpFO,SAAS,0BAA0B,kBAA0D,EAAA;AAChG,EAAO,OAAA,kBAAA,CAAmB,kBAAmB,CAAA,kBAAkB,CAAC,CAAA;AACpE;AAeO,SAAS,oCACZ,kBAC6E,EAAA;AAC7E,EAAO,OAAA,yBAAA,CAA0B,kBAAkB,CAAK,IAAA,sBAAA;AAC5D;AAiBO,SAAS,0CACZ,kBACqF,EAAA;AACrF,EAAM,MAAA,eAAA,GAAkB,0BAA0B,kBAAkB,CAAA;AACpE,EAAA,IAAI,kBAAkB,sBAAwB,EAAA;AAC1C,IAAM,MAAA,IAAIA,YAAYC,6CAA+C,EAAA;AAAA,MACjE,eAAA;AAAA,MACA,oBAAsB,EAAA;AAAA,KACzB,CAAA;AAAA;AAET;;;AClCO,IAAM,8BAAiC,GAAA","file":"index.browser.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 {\n CompilableTransactionMessage,\n compileTransactionMessage,\n getCompiledTransactionMessageEncoder,\n isTransactionMessageWithBlockhashLifetime,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type {\n SignaturesMap,\n TransactionFromCompilableTransactionMessage,\n TransactionMessageBytes,\n} 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 CompilableTransactionMessage>(\n transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromCompilableTransactionMessage<TTransactionMessage>> {\n type ReturnType = Readonly<TransactionFromCompilableTransactionMessage<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'];\n if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n lifetimeConstraint = {\n blockhash: transactionMessage.lifetimeConstraint.blockhash,\n lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n };\n } else {\n lifetimeConstraint = {\n nonce: transactionMessage.lifetimeConstraint.nonce,\n nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n };\n }\n\n return Object.freeze({\n lifetimeConstraint,\n messageBytes: messageBytes,\n signatures: Object.freeze(signatures),\n }) as ReturnType;\n}\n","import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { 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'> & Transaction;\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\nfunction uint8ArraysEqual(arr1: Uint8Array, arr2: Uint8Array) {\n return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);\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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<T> {\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 && uint8ArraysEqual(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<T extends Transaction>(\n keyPairs: CryptoKeyPair[],\n transaction: T,\n): Promise<FullySignedTransaction & T> {\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 { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { CompilableTransactionMessage, TransactionMessageWithinSizeLimit } 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(transactionMessage: CompilableTransactionMessage): 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<TTransactionMessage extends CompilableTransactionMessage>(\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<TTransactionMessage extends CompilableTransactionMessage>(\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","import { assertIsFullySignedTransaction } from './signatures';\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 * @deprecated Use {@link assertIsFullySignedTransaction} instead. It was only renamed.\n *\n * @example\n * ```ts\n * import { assertTransactionIsFullySigned } 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 * assertTransactionIsFullySigned(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 const assertTransactionIsFullySigned = assertIsFullySignedTransaction;\n"]}
@@ -2,7 +2,7 @@ import { getAddressDecoder, getAddressFromPublicKey } from '@solana/addresses';
2
2
  import { transformDecoder, fixDecoderSize, combineCodec, padRightDecoder, transformEncoder, fixEncoderSize } from '@solana/codecs-core';
3
3
  import { getStructEncoder, getBytesEncoder, getStructDecoder, getArrayDecoder, getBytesDecoder, getTupleDecoder, getArrayEncoder } from '@solana/codecs-data-structures';
4
4
  import { getShortU16Decoder, getU8Decoder, getShortU16Encoder } from '@solana/codecs-numbers';
5
- import { SolanaError, SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES } from '@solana/errors';
5
+ import { SolanaError, SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES } from '@solana/errors';
6
6
  import { getTransactionVersionDecoder, compileTransactionMessage, getCompiledTransactionMessageEncoder, isTransactionMessageWithBlockhashLifetime } from '@solana/transaction-messages';
7
7
  import { getBase58Decoder, getBase64Decoder } from '@solana/codecs-strings';
8
8
  import { signBytes } from '@solana/keys';
@@ -100,12 +100,11 @@ function compileTransaction(transactionMessage) {
100
100
  nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address
101
101
  };
102
102
  }
103
- const transaction = {
103
+ return Object.freeze({
104
104
  lifetimeConstraint,
105
105
  messageBytes,
106
106
  signatures: Object.freeze(signatures)
107
- };
108
- return Object.freeze(transaction);
107
+ });
109
108
  }
110
109
  var base58Decoder;
111
110
  function getSignatureFromTransaction(transaction) {
@@ -163,11 +162,14 @@ async function partiallySignTransaction(keyPairs, transaction) {
163
162
  }
164
163
  async function signTransaction(keyPairs, transaction) {
165
164
  const out = await partiallySignTransaction(keyPairs, transaction);
166
- assertTransactionIsFullySigned(out);
165
+ assertIsFullySignedTransaction(out);
167
166
  Object.freeze(out);
168
167
  return out;
169
168
  }
170
- function assertTransactionIsFullySigned(transaction) {
169
+ function isFullySignedTransaction(transaction) {
170
+ return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);
171
+ }
172
+ function assertIsFullySignedTransaction(transaction) {
171
173
  const missingSigs = [];
172
174
  Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {
173
175
  if (!signatureBytes) {
@@ -184,7 +186,45 @@ function getBase64EncodedWireTransaction(transaction) {
184
186
  const wireTransactionBytes = getTransactionEncoder().encode(transaction);
185
187
  return getBase64Decoder().decode(wireTransactionBytes);
186
188
  }
189
+ var TRANSACTION_PACKET_SIZE = 1280;
190
+ var TRANSACTION_PACKET_HEADER = 40 + 8;
191
+ var TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;
192
+ function getTransactionSize(transaction) {
193
+ return getTransactionEncoder().getSizeFromValue(transaction);
194
+ }
195
+ function isTransactionWithinSizeLimit(transaction) {
196
+ return getTransactionSize(transaction) <= TRANSACTION_SIZE_LIMIT;
197
+ }
198
+ function assertIsTransactionWithinSizeLimit(transaction) {
199
+ const transactionSize = getTransactionSize(transaction);
200
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
201
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
202
+ transactionSize,
203
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
204
+ });
205
+ }
206
+ }
207
+
208
+ // src/transaction-message-size.ts
209
+ function getTransactionMessageSize(transactionMessage) {
210
+ return getTransactionSize(compileTransaction(transactionMessage));
211
+ }
212
+ function isTransactionMessageWithinSizeLimit(transactionMessage) {
213
+ return getTransactionMessageSize(transactionMessage) <= TRANSACTION_SIZE_LIMIT;
214
+ }
215
+ function assertIsTransactionMessageWithinSizeLimit(transactionMessage) {
216
+ const transactionSize = getTransactionMessageSize(transactionMessage);
217
+ if (transactionSize > TRANSACTION_SIZE_LIMIT) {
218
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {
219
+ transactionSize,
220
+ transactionSizeLimit: TRANSACTION_SIZE_LIMIT
221
+ });
222
+ }
223
+ }
224
+
225
+ // src/deprecated.ts
226
+ var assertTransactionIsFullySigned = assertIsFullySignedTransaction;
187
227
 
188
- export { assertTransactionIsFullySigned, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, partiallySignTransaction, signTransaction };
228
+ export { TRANSACTION_PACKET_HEADER, TRANSACTION_PACKET_SIZE, TRANSACTION_SIZE_LIMIT, assertIsFullySignedTransaction, assertIsTransactionMessageWithinSizeLimit, assertIsTransactionWithinSizeLimit, assertTransactionIsFullySigned, compileTransaction, getBase64EncodedWireTransaction, getSignatureFromTransaction, getTransactionCodec, getTransactionDecoder, getTransactionEncoder, getTransactionMessageSize, getTransactionSize, isFullySignedTransaction, isTransactionMessageWithinSizeLimit, isTransactionWithinSizeLimit, partiallySignTransaction, signTransaction };
189
229
  //# sourceMappingURL=index.native.mjs.map
190
230
  //# sourceMappingURL=index.native.mjs.map