@solana/transactions 2.0.0-rc.1 → 2.0.0-rc.3

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
@@ -1,6 +1,5 @@
1
1
  [![npm][npm-image]][npm-url]
2
2
  [![npm-downloads][npm-downloads-image]][npm-url]
3
- [![semantic-release][semantic-release-image]][semantic-release-url]
4
3
  <br />
5
4
  [![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
6
5
 
@@ -9,8 +8,6 @@
9
8
  [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transactions/rc.svg?style=flat
10
9
  [npm-image]: https://img.shields.io/npm/v/@solana/transactions/rc.svg?style=flat
11
10
  [npm-url]: https://www.npmjs.com/package/@solana/transactions/v/rc
12
- [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
13
- [semantic-release-url]: https://github.com/semantic-release/semantic-release
14
11
 
15
12
  # @solana/transactions
16
13
 
@@ -84,9 +84,7 @@ function decodePartiallyDecodedTransaction(transaction) {
84
84
  }
85
85
  function compileTransaction(transactionMessage) {
86
86
  const compiledMessage = transactionMessages.compileTransactionMessage(transactionMessage);
87
- const messageBytes = transactionMessages.getCompiledTransactionMessageEncoder().encode(
88
- compiledMessage
89
- );
87
+ const messageBytes = transactionMessages.getCompiledTransactionMessageEncoder().encode(compiledMessage);
90
88
  const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);
91
89
  const signatures = {};
92
90
  for (const signerAddress of transactionSigners) {
@@ -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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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 { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\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\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(\n compiledMessage,\n ) as ReadonlyUint8Array 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 as TransactionMessageBytes,\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\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"],"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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\n};\n\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"]}
@@ -82,9 +82,7 @@ function decodePartiallyDecodedTransaction(transaction) {
82
82
  }
83
83
  function compileTransaction(transactionMessage) {
84
84
  const compiledMessage = compileTransactionMessage(transactionMessage);
85
- const messageBytes = getCompiledTransactionMessageEncoder().encode(
86
- compiledMessage
87
- );
85
+ const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage);
88
86
  const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);
89
87
  const signatures = {};
90
88
  for (const signerAddress of transactionSigners) {
@@ -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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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 { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\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\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(\n compiledMessage,\n ) as ReadonlyUint8Array 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 as TransactionMessageBytes,\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\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"],"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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\n};\n\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"]}
@@ -82,9 +82,7 @@ function decodePartiallyDecodedTransaction(transaction) {
82
82
  }
83
83
  function compileTransaction(transactionMessage) {
84
84
  const compiledMessage = compileTransactionMessage(transactionMessage);
85
- const messageBytes = getCompiledTransactionMessageEncoder().encode(
86
- compiledMessage
87
- );
85
+ const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage);
88
86
  const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);
89
87
  const signatures = {};
90
88
  for (const signerAddress of transactionSigners) {
@@ -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.native.mjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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 { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\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\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(\n compiledMessage,\n ) as ReadonlyUint8Array 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 as TransactionMessageBytes,\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\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"],"names":["getBytesEncoder","SolanaError"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\n};\n\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"]}
@@ -84,9 +84,7 @@ function decodePartiallyDecodedTransaction(transaction) {
84
84
  }
85
85
  function compileTransaction(transactionMessage) {
86
86
  const compiledMessage = transactionMessages.compileTransactionMessage(transactionMessage);
87
- const messageBytes = transactionMessages.getCompiledTransactionMessageEncoder().encode(
88
- compiledMessage
89
- );
87
+ const messageBytes = transactionMessages.getCompiledTransactionMessageEncoder().encode(compiledMessage);
90
88
  const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);
91
89
  const signatures = {};
92
90
  for (const signerAddress of transactionSigners) {
@@ -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.node.cjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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 { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\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\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(\n compiledMessage,\n ) as ReadonlyUint8Array 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 as TransactionMessageBytes,\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\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"],"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.node.cjs","sourcesContent":["import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n const signatures = Object.values(signaturesMap);\n if (signatures.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n }\n\n return signatures.map(signature => {\n if (!signature) {\n return new Uint8Array(64).fill(0) as SignatureBytes;\n }\n return signature;\n });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<SignaturesMap> {\n return transformEncoder(\n getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n getSignaturesToEncode,\n );\n}\n","import { getAddressDecoder } from '@solana/addresses';\nimport {\n combineCodec,\n fixDecoderSize,\n padRightDecoder,\n ReadonlyUint8Array,\n transformDecoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n getArrayDecoder,\n getBytesDecoder,\n getBytesEncoder,\n getStructDecoder,\n getStructEncoder,\n getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoder } from './signatures-encoder';\n\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\n};\n\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"]}
@@ -82,9 +82,7 @@ function decodePartiallyDecodedTransaction(transaction) {
82
82
  }
83
83
  function compileTransaction(transactionMessage) {
84
84
  const compiledMessage = compileTransactionMessage(transactionMessage);
85
- const messageBytes = getCompiledTransactionMessageEncoder().encode(
86
- compiledMessage
87
- );
85
+ const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage);
88
86
  const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);
89
87
  const signatures = {};
90
88
  for (const signerAddress of transactionSigners) {
@@ -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.node.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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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 { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\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\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(\n compiledMessage,\n ) as ReadonlyUint8Array 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 as TransactionMessageBytes,\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\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"],"names":["getBytesEncoder","SolanaError"],"mappings":"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","file":"index.node.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\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n return getStructEncoder([\n ['signatures', getSignaturesEncoder()],\n ['messageBytes', getBytesEncoder()],\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\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\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';\n\nimport { Transaction } from './transaction';\n\nexport interface FullySignedTransaction extends Transaction {\n readonly __brand: unique symbol;\n}\n\nlet base58Decoder: Decoder<string> | undefined;\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\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\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\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';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\nexport type Base64EncodedWireTransaction = string & {\n readonly __brand: unique symbol;\n};\n\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compile-transaction.d.ts","sourceRoot":"","sources":["../../src/compile-transaction.ts"],"names":[],"mappings":"AACA,OAAO,EACH,4BAA4B,EAI5B,uCAAuC,EACvC,0CAA0C,EAC7C,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACH,gCAAgC,EAChC,mCAAmC,EACnC,uBAAuB,EAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,WAAW,EAA2B,MAAM,eAAe,CAAC;AAEpF,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GAAG,uCAAuC,GAC3F,QAAQ,CAAC,WAAW,GAAG,gCAAgC,CAAC,CAAC;AAE5D,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GAAG,0CAA0C,GAC9F,QAAQ,CAAC,WAAW,GAAG,mCAAmC,CAAC,CAAC;AAE/D,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GACjD,QAAQ,CAAC,WAAW,GAAG,uBAAuB,CAAC,CAAC"}
1
+ {"version":3,"file":"compile-transaction.d.ts","sourceRoot":"","sources":["../../src/compile-transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,4BAA4B,EAI5B,uCAAuC,EACvC,0CAA0C,EAC7C,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACH,gCAAgC,EAChC,mCAAmC,EACnC,uBAAuB,EAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAiB,WAAW,EAA2B,MAAM,eAAe,CAAC;AAEpF,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GAAG,uCAAuC,GAC3F,QAAQ,CAAC,WAAW,GAAG,gCAAgC,CAAC,CAAC;AAE5D,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GAAG,0CAA0C,GAC9F,QAAQ,CAAC,WAAW,GAAG,mCAAmC,CAAC,CAAC;AAE/D,wBAAgB,kBAAkB,CAC9B,kBAAkB,EAAE,4BAA4B,GACjD,QAAQ,CAAC,WAAW,GAAG,uBAAuB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@solana/transactions",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.3",
4
4
  "description": "Helpers for creating and serializing transactions",
5
5
  "exports": {
6
+ "edge-light": {
7
+ "import": "./dist/index.node.mjs",
8
+ "require": "./dist/index.node.cjs"
9
+ },
10
+ "workerd": {
11
+ "import": "./dist/index.node.mjs",
12
+ "require": "./dist/index.node.cjs"
13
+ },
6
14
  "browser": {
7
15
  "import": "./dist/index.browser.mjs",
8
16
  "require": "./dist/index.browser.cjs"
@@ -46,17 +54,17 @@
46
54
  "maintained node versions"
47
55
  ],
48
56
  "dependencies": {
49
- "@solana/addresses": "2.0.0-rc.1",
50
- "@solana/codecs-core": "2.0.0-rc.1",
51
- "@solana/codecs-data-structures": "2.0.0-rc.1",
52
- "@solana/codecs-strings": "2.0.0-rc.1",
53
- "@solana/errors": "2.0.0-rc.1",
54
- "@solana/codecs-numbers": "2.0.0-rc.1",
55
- "@solana/functional": "2.0.0-rc.1",
56
- "@solana/keys": "2.0.0-rc.1",
57
- "@solana/instructions": "2.0.0-rc.1",
58
- "@solana/rpc-types": "2.0.0-rc.1",
59
- "@solana/transaction-messages": "2.0.0-rc.1"
57
+ "@solana/addresses": "2.0.0-rc.3",
58
+ "@solana/codecs-numbers": "2.0.0-rc.3",
59
+ "@solana/codecs-data-structures": "2.0.0-rc.3",
60
+ "@solana/codecs-strings": "2.0.0-rc.3",
61
+ "@solana/codecs-core": "2.0.0-rc.3",
62
+ "@solana/errors": "2.0.0-rc.3",
63
+ "@solana/functional": "2.0.0-rc.3",
64
+ "@solana/instructions": "2.0.0-rc.3",
65
+ "@solana/keys": "2.0.0-rc.3",
66
+ "@solana/transaction-messages": "2.0.0-rc.3",
67
+ "@solana/rpc-types": "2.0.0-rc.3"
60
68
  },
61
69
  "peerDependencies": {
62
70
  "typescript": ">=5"
@@ -69,13 +77,16 @@
69
77
  }
70
78
  ]
71
79
  },
80
+ "engines": {
81
+ "node": ">=20.18.0"
82
+ },
72
83
  "scripts": {
73
84
  "compile:js": "tsup --config build-scripts/tsup.config.package.ts",
74
85
  "compile:typedefs": "tsc -p ./tsconfig.declarations.json",
75
86
  "dev": "jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
76
87
  "publish-impl": "npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks",
77
88
  "publish-packages": "pnpm prepublishOnly && pnpm publish-impl",
78
- "style:fix": "pnpm eslint --fix src/* && pnpm prettier --log-level warn --ignore-unknown --write ./*",
89
+ "style:fix": "pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*",
79
90
  "test:lint": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
80
91
  "test:prettier": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
81
92
  "test:treeshakability:browser": "agadoo dist/index.browser.mjs",