@solana/compat 2.0.0-experimental.a64df70 → 2.0.0-experimental.a71a2db

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { createKeyPairFromBytes } from '@solana/keys';
2
+ import { SolanaError, SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER, SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS, SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE, SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH, SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH, SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS, SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE } from '@solana/errors';
2
3
  import { pipe } from '@solana/functional';
3
4
  import { AccountRole } from '@solana/instructions';
4
5
  import { createTransaction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, appendTransactionInstruction, isAdvanceNonceAccountInstruction, setTransactionLifetimeUsingDurableNonce } from '@solana/transactions';
@@ -17,8 +18,6 @@ async function fromLegacyKeypair(keypair, extractable) {
17
18
  );
18
19
  return createKeyPairFromBytes(bytes, extractable);
19
20
  }
20
-
21
- // ../codecs-core/dist/index.browser.js
22
21
  function getEncodedSize(value, encoder) {
23
22
  return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
24
23
  }
@@ -32,11 +31,13 @@ function createEncoder(encoder) {
32
31
  }
33
32
  });
34
33
  }
35
-
36
- // ../codecs-strings/dist/index.browser.js
37
34
  function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
38
35
  if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
39
- throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
36
+ throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {
37
+ alphabet: alphabet4,
38
+ base: alphabet4.length,
39
+ value: givenValue
40
+ });
40
41
  }
41
42
  }
42
43
  var getBaseXEncoder = (alphabet4) => {
@@ -84,8 +85,6 @@ function getBigIntFromBaseX(value, alphabet4) {
84
85
  }
85
86
  var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
86
87
  var getBase58Encoder = () => getBaseXEncoder(alphabet2);
87
-
88
- // ../addresses/dist/index.browser.js
89
88
  var memoizedBase58Encoder;
90
89
  function getMemoizedBase58Encoder() {
91
90
  if (!memoizedBase58Encoder)
@@ -99,24 +98,28 @@ function assertIsAddress(putativeAddress) {
99
98
  putativeAddress.length < 32 || // Highest address (32 bytes of 255)
100
99
  putativeAddress.length > 44
101
100
  ) {
102
- throw new Error("Expected input string to decode to a byte array of length 32.");
101
+ throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH, {
102
+ actualLength: putativeAddress.length
103
+ });
103
104
  }
104
105
  const base58Encoder = getMemoizedBase58Encoder();
105
106
  const bytes = base58Encoder.encode(putativeAddress);
106
107
  const numBytes = bytes.byteLength;
107
108
  if (numBytes !== 32) {
108
- throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
109
+ throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH, {
110
+ actualLength: numBytes
111
+ });
109
112
  }
110
113
  } catch (e2) {
111
- throw new Error(`\`${putativeAddress}\` is not a base-58 encoded address`, {
112
- cause: e2
113
- });
114
+ throw new SolanaError(SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS, { putativeAddress });
114
115
  }
115
116
  }
116
117
  function convertAccount(message, accountKeys, accountIndex) {
117
118
  const accountPublicKey = accountKeys.get(accountIndex);
118
119
  if (!accountPublicKey) {
119
- throw new Error(`Could not find account address at index ${accountIndex}`);
120
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {
121
+ index: accountIndex
122
+ });
120
123
  }
121
124
  const isSigner = message.isAccountSigner(accountIndex);
122
125
  const isWritable = message.isAccountWritable(accountIndex);
@@ -129,7 +132,9 @@ function convertAccount(message, accountKeys, accountIndex) {
129
132
  function convertInstruction(message, accountKeys, instruction) {
130
133
  const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);
131
134
  if (!programAddressPublicKey) {
132
- throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);
135
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {
136
+ index: instruction.programIdIndex
137
+ });
133
138
  }
134
139
  const accounts = instruction.accountKeyIndexes.map(
135
140
  (accountIndex) => convertAccount(message, accountKeys, accountIndex)
@@ -156,7 +161,7 @@ function fromVersionedTransactionWithBlockhash(transaction, lastValidBlockHeight
156
161
  const accountKeys = transaction.message.getAccountKeys();
157
162
  const feePayer = accountKeys.staticAccountKeys[0];
158
163
  if (!feePayer)
159
- throw new Error("No fee payer set in VersionedTransaction");
164
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);
160
165
  const blockhashLifetime = {
161
166
  blockhash: transaction.message.recentBlockhash,
162
167
  lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
@@ -183,15 +188,15 @@ function fromVersionedTransactionWithDurableNonce(transaction) {
183
188
  const accountKeys = transaction.message.getAccountKeys();
184
189
  const feePayer = accountKeys.staticAccountKeys[0];
185
190
  if (!feePayer)
186
- throw new Error("No fee payer set in VersionedTransaction");
191
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);
187
192
  const instructions = transaction.message.compiledInstructions.map(
188
193
  (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
189
194
  );
190
195
  if (instructions.length === 0) {
191
- throw new Error("transaction with no instructions cannot be durable nonce transaction");
196
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS);
192
197
  }
193
198
  if (!isAdvanceNonceAccountInstruction(instructions[0])) {
194
- throw new Error("transaction first instruction is not advance nonce account instruction");
199
+ throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE);
195
200
  }
196
201
  const nonceAccountAddress = instructions[0].accounts[0].address;
197
202
  assertIsAddress(nonceAccountAddress);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/address.ts","../src/keypair.ts","../../codecs-core/src/codec.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/base64.ts","../../addresses/src/address.ts","../src/transaction.ts"],"names":["alphabet","e"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS PublicKey to a base58 encoded address\n * @param publicKey The PublicKey to convert\n * @returns An Address\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n return publicKey.toBase58() as Address<TAddress>;\n}\n","import { createKeyPairFromBytes } from '@solana/keys';\nimport { Keypair } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair\n * @param keypair The Keypair to convert\n * @returns A CryptoKeyPair\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n const bytes = new Uint8Array(64);\n bytes.set(keypair.secretKey);\n bytes.set(keypair.publicKey.toBytes(), /* offset */ 32);\n return createKeyPairFromBytes(bytes, extractable);\n}\n","/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n message?: string,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n message?: string,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n message?: string,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a fixed-size codec, got a variable-size one.');\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(\n encoder: Encoder<T>,\n message?: string,\n): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(\n decoder: Decoder<T>,\n message?: string,\n): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n message?: string,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a variable-size codec, got a fixed-size one.');\n }\n}\n","/**\n * Asserts that a given string matches a given alphabet.\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base ${alphabet.length}, got [${givenValue}].`);\n }\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Encodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXEncoder = (alphabet: string): VariableSizeEncoder<string> => {\n return createEncoder({\n getSizeFromValue: (value: string): number => {\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) return value.length;\n\n const base10Number = getBigIntFromBaseX(tailChars, alphabet);\n return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);\n },\n write(value: string, bytes, offset) {\n // Check if the value is valid.\n assertValidBaseString(alphabet, value);\n if (value === '') return offset;\n\n // Handle leading zeroes.\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) {\n bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);\n return offset + leadingZeroes.length;\n }\n\n // From baseX to base10.\n let base10Number = getBigIntFromBaseX(tailChars, alphabet);\n\n // From base10 to bytes.\n const tailBytes: number[] = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n\n const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];\n bytes.set(bytesToAdd, offset);\n return offset + bytesToAdd.length;\n },\n });\n};\n\n/**\n * Decodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXDecoder = (alphabet: string): VariableSizeDecoder<string> => {\n return createDecoder({\n read(rawBytes, offset): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', 0];\n\n // Handle leading zeroes.\n let trailIndex = bytes.findIndex(n => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet[0].repeat(trailIndex);\n if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n // From bytes to base10.\n const base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n // From base10 to baseX.\n const tailChars = getBaseXFromBigInt(base10Number, alphabet);\n\n return [leadingZeroes + tailChars, rawBytes.length];\n },\n });\n};\n\n/**\n * A string codec that requires a custom alphabet and uses\n * the length of that alphabet as the base. It then divides\n * the input by the base as many times as necessary to get\n * the output. It also supports leading zeroes by using the\n * first character of the alphabet as the zero character.\n *\n * This can be used to create codecs such as base10 or base58.\n */\nexport const getBaseXCodec = (alphabet: string): VariableSizeCodec<string> =>\n combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n\nfunction partitionLeadingZeroes(\n value: string,\n zeroCharacter: string,\n): [leadingZeros: string, tailChars: string | undefined] {\n const [leadingZeros, tailChars] = value.split(new RegExp(`((?!${zeroCharacter}).*)`));\n return [leadingZeros, tailChars];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n const base = BigInt(alphabet.length);\n let sum = 0n;\n for (const char of value) {\n sum *= base;\n sum += BigInt(alphabet.indexOf(char));\n }\n return sum;\n}\n\nfunction getBaseXFromBigInt(value: bigint, alphabet: string): string {\n const base = BigInt(alphabet.length);\n const tailChars = [];\n while (value > 0n) {\n tailChars.unshift(alphabet[Number(value % base)]);\n value /= base;\n }\n return tailChars.join('');\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/** Encodes strings in base16. */\nexport const getBase16Encoder = (): VariableSizeEncoder<string> =>\n createEncoder({\n getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n write(value: string, bytes, offset) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString('0123456789abcdef', lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n bytes.set(hexBytes, offset);\n return hexBytes.length + offset;\n },\n });\n\n/** Decodes strings in base16. */\nexport const getBase16Decoder = (): VariableSizeDecoder<string> =>\n createDecoder({\n read(bytes, offset) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n return [value, bytes.length];\n },\n });\n\n/** Encodes and decodes strings in base16. */\nexport const getBase16Codec = (): VariableSizeCodec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n mapDecoder,\n mapEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/** Encodes strings in base64. */\nexport const getBase64Encoder = (): VariableSizeEncoder<string> => {\n if (__BROWSER__) {\n return createEncoder({\n getSizeFromValue: (value: string) => {\n try {\n return (atob as Window['atob'])(value).length;\n } catch (e) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n write(value: string, bytes, offset) {\n try {\n const bytesToAdd = (atob as Window['atob'])(value)\n .split('')\n .map(c => c.charCodeAt(0));\n bytes.set(bytesToAdd, offset);\n return bytesToAdd.length + offset;\n } catch (e) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n });\n }\n\n if (__NODEJS__) {\n return createEncoder({\n getSizeFromValue: (value: string) => Buffer.from(value, 'base64').length,\n write(value: string, bytes, offset) {\n assertValidBaseString(alphabet, value.replace(/=/g, ''));\n const buffer = Buffer.from(value, 'base64');\n bytes.set(buffer, offset);\n return buffer.length + offset;\n },\n });\n }\n\n return mapEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/** Decodes strings in base64. */\nexport const getBase64Decoder = (): VariableSizeDecoder<string> => {\n if (__BROWSER__) {\n return createDecoder({\n read(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n });\n }\n\n if (__NODEJS__) {\n return createDecoder({\n read: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length],\n });\n }\n\n return mapDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n value.padEnd(Math.ceil(value.length / 4) * 4, '='),\n );\n};\n\n/** Encodes and decodes strings in base64. */\nexport const getBase64Codec = (): VariableSizeCodec<string> => combineCodec(getBase64Encoder(), getBase64Decoder());\n","import {\n combineCodec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n mapEncoder,\n} from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\n\nexport type Address<TAddress extends string = string> = TAddress & {\n readonly __brand: unique symbol;\n};\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n return memoizedBase58Decoder;\n}\n\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n try {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n throw new Error('Expected input string to decode to a byte array of length 32.');\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);\n }\n } catch (e) {\n throw new Error(`\\`${putativeAddress}\\` is not a base-58 encoded address`, {\n cause: e,\n });\n }\n}\n\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n assertIsAddress(putativeAddress);\n return putativeAddress as Address<TAddress>;\n}\n\nexport function getAddressEncoder(): FixedSizeEncoder<Address, 32> {\n return mapEncoder(getStringEncoder({ encoding: getMemoizedBase58Encoder(), size: 32 }), putativeAddress =>\n address(putativeAddress),\n );\n}\n\nexport function getAddressDecoder(): FixedSizeDecoder<Address, 32> {\n return getStringDecoder({ encoding: getMemoizedBase58Decoder(), size: 32 }) as FixedSizeDecoder<Address, 32>;\n}\n\nexport function getAddressCodec(): FixedSizeCodec<Address, Address, 32> {\n return combineCodec(getAddressEncoder(), getAddressDecoder());\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n return new Intl.Collator('en', {\n caseFirst: 'lower',\n ignorePunctuation: false,\n localeMatcher: 'best fit',\n numeric: false,\n sensitivity: 'variant',\n usage: 'sort',\n }).compare;\n}\n","import { type Address, assertIsAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n appendTransactionInstruction,\n createTransaction,\n type IDurableNonceTransaction,\n isAdvanceNonceAccountInstruction,\n type ITransactionWithBlockhashLifetime,\n type ITransactionWithFeePayer,\n type ITransactionWithSignatures,\n type Nonce,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n setTransactionLifetimeUsingDurableNonce,\n type Transaction,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number,\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n // TODO coded error\n throw new Error(`Could not find account address at index ${accountIndex}`);\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Address,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction,\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n // TODO coded error\n throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex),\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Address,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[],\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Address;\n return { ...acc, [address]: sig as SignatureBytes };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint,\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n\nexport function fromVersionedTransactionWithDurableNonce(\n transaction: VersionedTransaction,\n): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n // Check first instruction is durable nonce + extract params\n if (instructions.length === 0) {\n // TODO: coded error\n throw new Error('transaction with no instructions cannot be durable nonce transaction');\n }\n\n if (!isAdvanceNonceAccountInstruction(instructions[0])) {\n // TODO: coded error\n throw new Error('transaction first instruction is not advance nonce account instruction');\n }\n\n // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n const nonceAccountAddress = instructions[0].accounts![0].address;\n assertIsAddress(nonceAccountAddress);\n\n const nonceAuthorityAddress = instructions[0].accounts![2].address;\n assertIsAddress(nonceAuthorityAddress);\n\n const durableNonceLifetime = {\n nonce: transaction.message.recentBlockhash as Nonce,\n nonceAccountAddress,\n nonceAuthorityAddress,\n };\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),\n tx =>\n instructions.slice(1).reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/address.ts","../src/keypair.ts","../../codecs-core/src/bytes.ts","../../codecs-core/src/codec.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/base64.ts","../../addresses/src/address.ts","../src/transaction.ts"],"names":["SolanaError","alphabet","isSolanaError","e"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS PublicKey to a base58 encoded address\n * @param publicKey The PublicKey to convert\n * @returns An Address\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n return publicKey.toBase58() as Address<TAddress>;\n}\n","import { createKeyPairFromBytes } from '@solana/keys';\nimport { Keypair } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair\n * @param keypair The Keypair to convert\n * @returns A CryptoKeyPair\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n const bytes = new Uint8Array(64);\n bytes.set(keypair.secretKey);\n bytes.set(keypair.publicKey.toBytes(), /* offset */ 32);\n return createKeyPairFromBytes(bytes, extractable);\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","import {\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(encoder: Encoder<T>): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(decoder: Decoder<T>): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);\n }\n}\n","import { SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\n/**\n * Asserts that a given string matches a given alphabet.\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: alphabet.length,\n value: givenValue,\n });\n }\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Encodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXEncoder = (alphabet: string): VariableSizeEncoder<string> => {\n return createEncoder({\n getSizeFromValue: (value: string): number => {\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) return value.length;\n\n const base10Number = getBigIntFromBaseX(tailChars, alphabet);\n return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);\n },\n write(value: string, bytes, offset) {\n // Check if the value is valid.\n assertValidBaseString(alphabet, value);\n if (value === '') return offset;\n\n // Handle leading zeroes.\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) {\n bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);\n return offset + leadingZeroes.length;\n }\n\n // From baseX to base10.\n let base10Number = getBigIntFromBaseX(tailChars, alphabet);\n\n // From base10 to bytes.\n const tailBytes: number[] = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n\n const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];\n bytes.set(bytesToAdd, offset);\n return offset + bytesToAdd.length;\n },\n });\n};\n\n/**\n * Decodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXDecoder = (alphabet: string): VariableSizeDecoder<string> => {\n return createDecoder({\n read(rawBytes, offset): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', 0];\n\n // Handle leading zeroes.\n let trailIndex = bytes.findIndex(n => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet[0].repeat(trailIndex);\n if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n // From bytes to base10.\n const base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n // From base10 to baseX.\n const tailChars = getBaseXFromBigInt(base10Number, alphabet);\n\n return [leadingZeroes + tailChars, rawBytes.length];\n },\n });\n};\n\n/**\n * A string codec that requires a custom alphabet and uses\n * the length of that alphabet as the base. It then divides\n * the input by the base as many times as necessary to get\n * the output. It also supports leading zeroes by using the\n * first character of the alphabet as the zero character.\n *\n * This can be used to create codecs such as base10 or base58.\n */\nexport const getBaseXCodec = (alphabet: string): VariableSizeCodec<string> =>\n combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n\nfunction partitionLeadingZeroes(\n value: string,\n zeroCharacter: string,\n): [leadingZeros: string, tailChars: string | undefined] {\n const [leadingZeros, tailChars] = value.split(new RegExp(`((?!${zeroCharacter}).*)`));\n return [leadingZeros, tailChars];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n const base = BigInt(alphabet.length);\n let sum = 0n;\n for (const char of value) {\n sum *= base;\n sum += BigInt(alphabet.indexOf(char));\n }\n return sum;\n}\n\nfunction getBaseXFromBigInt(value: bigint, alphabet: string): string {\n const base = BigInt(alphabet.length);\n const tailChars = [];\n while (value > 0n) {\n tailChars.unshift(alphabet[Number(value % base)]);\n value /= base;\n }\n return tailChars.join('');\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/** Encodes strings in base16. */\nexport const getBase16Encoder = (): VariableSizeEncoder<string> =>\n createEncoder({\n getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n write(value: string, bytes, offset) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString('0123456789abcdef', lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n bytes.set(hexBytes, offset);\n return hexBytes.length + offset;\n },\n });\n\n/** Decodes strings in base16. */\nexport const getBase16Decoder = (): VariableSizeDecoder<string> =>\n createDecoder({\n read(bytes, offset) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n return [value, bytes.length];\n },\n });\n\n/** Encodes and decodes strings in base16. */\nexport const getBase16Codec = (): VariableSizeCodec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n mapDecoder,\n mapEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/** Encodes strings in base64. */\nexport const getBase64Encoder = (): VariableSizeEncoder<string> => {\n if (__BROWSER__) {\n return createEncoder({\n getSizeFromValue: (value: string) => {\n try {\n return (atob as Window['atob'])(value).length;\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: 64,\n value,\n });\n }\n },\n write(value: string, bytes, offset) {\n try {\n const bytesToAdd = (atob as Window['atob'])(value)\n .split('')\n .map(c => c.charCodeAt(0));\n bytes.set(bytesToAdd, offset);\n return bytesToAdd.length + offset;\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: 64,\n value,\n });\n }\n },\n });\n }\n\n if (__NODEJS__) {\n return createEncoder({\n getSizeFromValue: (value: string) => Buffer.from(value, 'base64').length,\n write(value: string, bytes, offset) {\n assertValidBaseString(alphabet, value.replace(/=/g, ''));\n const buffer = Buffer.from(value, 'base64');\n bytes.set(buffer, offset);\n return buffer.length + offset;\n },\n });\n }\n\n return mapEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/** Decodes strings in base64. */\nexport const getBase64Decoder = (): VariableSizeDecoder<string> => {\n if (__BROWSER__) {\n return createDecoder({\n read(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n });\n }\n\n if (__NODEJS__) {\n return createDecoder({\n read: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length],\n });\n }\n\n return mapDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n value.padEnd(Math.ceil(value.length / 4) * 4, '='),\n );\n};\n\n/** Encodes and decodes strings in base64. */\nexport const getBase64Codec = (): VariableSizeCodec<string> => combineCodec(getBase64Encoder(), getBase64Decoder());\n","import {\n combineCodec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n mapEncoder,\n} from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH,\n SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH,\n SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS,\n SolanaError,\n} from '@solana/errors';\n\nexport type Address<TAddress extends string = string> = TAddress & {\n readonly __brand: unique symbol;\n};\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n return memoizedBase58Decoder;\n}\n\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n try {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH, {\n actualLength: putativeAddress.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS, { putativeAddress });\n }\n}\n\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n assertIsAddress(putativeAddress);\n return putativeAddress as Address<TAddress>;\n}\n\nexport function getAddressEncoder(): FixedSizeEncoder<Address, 32> {\n return mapEncoder(getStringEncoder({ encoding: getMemoizedBase58Encoder(), size: 32 }), putativeAddress =>\n address(putativeAddress),\n );\n}\n\nexport function getAddressDecoder(): FixedSizeDecoder<Address, 32> {\n return getStringDecoder({ encoding: getMemoizedBase58Decoder(), size: 32 }) as FixedSizeDecoder<Address, 32>;\n}\n\nexport function getAddressCodec(): FixedSizeCodec<Address, Address, 32> {\n return combineCodec(getAddressEncoder(), getAddressDecoder());\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n return new Intl.Collator('en', {\n caseFirst: 'lower',\n ignorePunctuation: false,\n localeMatcher: 'best fit',\n numeric: false,\n sensitivity: 'variant',\n usage: 'sort',\n }).compare;\n}\n","import { type Address, assertIsAddress } from '@solana/addresses';\nimport {\n SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE,\n SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS,\n SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS,\n SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER,\n SolanaError,\n} from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n appendTransactionInstruction,\n createTransaction,\n type IDurableNonceTransaction,\n isAdvanceNonceAccountInstruction,\n type ITransactionWithBlockhashLifetime,\n type ITransactionWithFeePayer,\n type ITransactionWithSignatures,\n type Nonce,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n setTransactionLifetimeUsingDurableNonce,\n type Transaction,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number,\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {\n index: accountIndex,\n });\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Address,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction,\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {\n index: instruction.programIdIndex,\n });\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex),\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Address,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[],\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Address;\n return { ...acc, [address]: sig as SignatureBytes };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint,\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n // This should probably not be a `SolanaError`, since we need to add\n // this functionality.\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n if (!feePayer) throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);\n\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n\nexport function fromVersionedTransactionWithDurableNonce(\n transaction: VersionedTransaction,\n): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n // This should probably not be a `SolanaError`, since we need to add\n // this functionality.\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n if (!feePayer) throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n // Check first instruction is durable nonce + extract params\n if (instructions.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS);\n }\n\n if (!isAdvanceNonceAccountInstruction(instructions[0])) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE);\n }\n\n // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n const nonceAccountAddress = instructions[0].accounts![0].address;\n assertIsAddress(nonceAccountAddress);\n\n const nonceAuthorityAddress = instructions[0].accounts![2].address;\n assertIsAddress(nonceAuthorityAddress);\n\n const durableNonceLifetime = {\n nonce: transaction.message.recentBlockhash as Nonce,\n nonceAccountAddress,\n nonceAuthorityAddress,\n };\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),\n tx =>\n instructions.slice(1).reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var keys = require('@solana/keys');
4
+ var errors = require('@solana/errors');
4
5
  var functional = require('@solana/functional');
5
6
  var instructions = require('@solana/instructions');
6
7
  var transactions = require('@solana/transactions');
@@ -19,8 +20,6 @@ async function fromLegacyKeypair(keypair, extractable) {
19
20
  );
20
21
  return keys.createKeyPairFromBytes(bytes, extractable);
21
22
  }
22
-
23
- // ../codecs-core/dist/index.node.js
24
23
  function getEncodedSize(value, encoder) {
25
24
  return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
26
25
  }
@@ -34,11 +33,13 @@ function createEncoder(encoder) {
34
33
  }
35
34
  });
36
35
  }
37
-
38
- // ../codecs-strings/dist/index.node.js
39
36
  function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
40
37
  if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
41
- throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
38
+ throw new errors.SolanaError(errors.SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {
39
+ alphabet: alphabet4,
40
+ base: alphabet4.length,
41
+ value: givenValue
42
+ });
42
43
  }
43
44
  }
44
45
  var getBaseXEncoder = (alphabet4) => {
@@ -86,8 +87,6 @@ function getBigIntFromBaseX(value, alphabet4) {
86
87
  }
87
88
  var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
88
89
  var getBase58Encoder = () => getBaseXEncoder(alphabet2);
89
-
90
- // ../addresses/dist/index.node.js
91
90
  var memoizedBase58Encoder;
92
91
  function getMemoizedBase58Encoder() {
93
92
  if (!memoizedBase58Encoder)
@@ -101,24 +100,28 @@ function assertIsAddress(putativeAddress) {
101
100
  putativeAddress.length < 32 || // Highest address (32 bytes of 255)
102
101
  putativeAddress.length > 44
103
102
  ) {
104
- throw new Error("Expected input string to decode to a byte array of length 32.");
103
+ throw new errors.SolanaError(errors.SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH, {
104
+ actualLength: putativeAddress.length
105
+ });
105
106
  }
106
107
  const base58Encoder = getMemoizedBase58Encoder();
107
108
  const bytes = base58Encoder.encode(putativeAddress);
108
109
  const numBytes = bytes.byteLength;
109
110
  if (numBytes !== 32) {
110
- throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
111
+ throw new errors.SolanaError(errors.SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH, {
112
+ actualLength: numBytes
113
+ });
111
114
  }
112
115
  } catch (e2) {
113
- throw new Error(`\`${putativeAddress}\` is not a base-58 encoded address`, {
114
- cause: e2
115
- });
116
+ throw new errors.SolanaError(errors.SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS, { putativeAddress });
116
117
  }
117
118
  }
118
119
  function convertAccount(message, accountKeys, accountIndex) {
119
120
  const accountPublicKey = accountKeys.get(accountIndex);
120
121
  if (!accountPublicKey) {
121
- throw new Error(`Could not find account address at index ${accountIndex}`);
122
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {
123
+ index: accountIndex
124
+ });
122
125
  }
123
126
  const isSigner = message.isAccountSigner(accountIndex);
124
127
  const isWritable = message.isAccountWritable(accountIndex);
@@ -131,7 +134,9 @@ function convertAccount(message, accountKeys, accountIndex) {
131
134
  function convertInstruction(message, accountKeys, instruction) {
132
135
  const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);
133
136
  if (!programAddressPublicKey) {
134
- throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);
137
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {
138
+ index: instruction.programIdIndex
139
+ });
135
140
  }
136
141
  const accounts = instruction.accountKeyIndexes.map(
137
142
  (accountIndex) => convertAccount(message, accountKeys, accountIndex)
@@ -158,7 +163,7 @@ function fromVersionedTransactionWithBlockhash(transaction, lastValidBlockHeight
158
163
  const accountKeys = transaction.message.getAccountKeys();
159
164
  const feePayer = accountKeys.staticAccountKeys[0];
160
165
  if (!feePayer)
161
- throw new Error("No fee payer set in VersionedTransaction");
166
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);
162
167
  const blockhashLifetime = {
163
168
  blockhash: transaction.message.recentBlockhash,
164
169
  lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
@@ -185,15 +190,15 @@ function fromVersionedTransactionWithDurableNonce(transaction) {
185
190
  const accountKeys = transaction.message.getAccountKeys();
186
191
  const feePayer = accountKeys.staticAccountKeys[0];
187
192
  if (!feePayer)
188
- throw new Error("No fee payer set in VersionedTransaction");
193
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);
189
194
  const instructions = transaction.message.compiledInstructions.map(
190
195
  (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
191
196
  );
192
197
  if (instructions.length === 0) {
193
- throw new Error("transaction with no instructions cannot be durable nonce transaction");
198
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS);
194
199
  }
195
200
  if (!transactions.isAdvanceNonceAccountInstruction(instructions[0])) {
196
- throw new Error("transaction first instruction is not advance nonce account instruction");
201
+ throw new errors.SolanaError(errors.SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE);
197
202
  }
198
203
  const nonceAccountAddress = instructions[0].accounts[0].address;
199
204
  assertIsAddress(nonceAccountAddress);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/address.ts","../src/keypair.ts","../../codecs-core/src/codec.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/base64.ts","../../addresses/src/address.ts","../src/transaction.ts"],"names":["alphabet","e"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS PublicKey to a base58 encoded address\n * @param publicKey The PublicKey to convert\n * @returns An Address\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n return publicKey.toBase58() as Address<TAddress>;\n}\n","import { createKeyPairFromBytes } from '@solana/keys';\nimport { Keypair } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair\n * @param keypair The Keypair to convert\n * @returns A CryptoKeyPair\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n const bytes = new Uint8Array(64);\n bytes.set(keypair.secretKey);\n bytes.set(keypair.publicKey.toBytes(), /* offset */ 32);\n return createKeyPairFromBytes(bytes, extractable);\n}\n","/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n message?: string,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n message?: string,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n message?: string,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a fixed-size codec, got a variable-size one.');\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(\n encoder: Encoder<T>,\n message?: string,\n): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(\n decoder: Decoder<T>,\n message?: string,\n): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n message?: string,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n message?: string,\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n // TODO: Coded error.\n throw new Error(message ?? 'Expected a variable-size codec, got a fixed-size one.');\n }\n}\n","/**\n * Asserts that a given string matches a given alphabet.\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base ${alphabet.length}, got [${givenValue}].`);\n }\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Encodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXEncoder = (alphabet: string): VariableSizeEncoder<string> => {\n return createEncoder({\n getSizeFromValue: (value: string): number => {\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) return value.length;\n\n const base10Number = getBigIntFromBaseX(tailChars, alphabet);\n return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);\n },\n write(value: string, bytes, offset) {\n // Check if the value is valid.\n assertValidBaseString(alphabet, value);\n if (value === '') return offset;\n\n // Handle leading zeroes.\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) {\n bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);\n return offset + leadingZeroes.length;\n }\n\n // From baseX to base10.\n let base10Number = getBigIntFromBaseX(tailChars, alphabet);\n\n // From base10 to bytes.\n const tailBytes: number[] = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n\n const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];\n bytes.set(bytesToAdd, offset);\n return offset + bytesToAdd.length;\n },\n });\n};\n\n/**\n * Decodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXDecoder = (alphabet: string): VariableSizeDecoder<string> => {\n return createDecoder({\n read(rawBytes, offset): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', 0];\n\n // Handle leading zeroes.\n let trailIndex = bytes.findIndex(n => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet[0].repeat(trailIndex);\n if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n // From bytes to base10.\n const base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n // From base10 to baseX.\n const tailChars = getBaseXFromBigInt(base10Number, alphabet);\n\n return [leadingZeroes + tailChars, rawBytes.length];\n },\n });\n};\n\n/**\n * A string codec that requires a custom alphabet and uses\n * the length of that alphabet as the base. It then divides\n * the input by the base as many times as necessary to get\n * the output. It also supports leading zeroes by using the\n * first character of the alphabet as the zero character.\n *\n * This can be used to create codecs such as base10 or base58.\n */\nexport const getBaseXCodec = (alphabet: string): VariableSizeCodec<string> =>\n combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n\nfunction partitionLeadingZeroes(\n value: string,\n zeroCharacter: string,\n): [leadingZeros: string, tailChars: string | undefined] {\n const [leadingZeros, tailChars] = value.split(new RegExp(`((?!${zeroCharacter}).*)`));\n return [leadingZeros, tailChars];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n const base = BigInt(alphabet.length);\n let sum = 0n;\n for (const char of value) {\n sum *= base;\n sum += BigInt(alphabet.indexOf(char));\n }\n return sum;\n}\n\nfunction getBaseXFromBigInt(value: bigint, alphabet: string): string {\n const base = BigInt(alphabet.length);\n const tailChars = [];\n while (value > 0n) {\n tailChars.unshift(alphabet[Number(value % base)]);\n value /= base;\n }\n return tailChars.join('');\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/** Encodes strings in base16. */\nexport const getBase16Encoder = (): VariableSizeEncoder<string> =>\n createEncoder({\n getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n write(value: string, bytes, offset) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString('0123456789abcdef', lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n bytes.set(hexBytes, offset);\n return hexBytes.length + offset;\n },\n });\n\n/** Decodes strings in base16. */\nexport const getBase16Decoder = (): VariableSizeDecoder<string> =>\n createDecoder({\n read(bytes, offset) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n return [value, bytes.length];\n },\n });\n\n/** Encodes and decodes strings in base16. */\nexport const getBase16Codec = (): VariableSizeCodec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n mapDecoder,\n mapEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/** Encodes strings in base64. */\nexport const getBase64Encoder = (): VariableSizeEncoder<string> => {\n if (__BROWSER__) {\n return createEncoder({\n getSizeFromValue: (value: string) => {\n try {\n return (atob as Window['atob'])(value).length;\n } catch (e) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n write(value: string, bytes, offset) {\n try {\n const bytesToAdd = (atob as Window['atob'])(value)\n .split('')\n .map(c => c.charCodeAt(0));\n bytes.set(bytesToAdd, offset);\n return bytesToAdd.length + offset;\n } catch (e) {\n // TODO: Coded error.\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n });\n }\n\n if (__NODEJS__) {\n return createEncoder({\n getSizeFromValue: (value: string) => Buffer.from(value, 'base64').length,\n write(value: string, bytes, offset) {\n assertValidBaseString(alphabet, value.replace(/=/g, ''));\n const buffer = Buffer.from(value, 'base64');\n bytes.set(buffer, offset);\n return buffer.length + offset;\n },\n });\n }\n\n return mapEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/** Decodes strings in base64. */\nexport const getBase64Decoder = (): VariableSizeDecoder<string> => {\n if (__BROWSER__) {\n return createDecoder({\n read(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n });\n }\n\n if (__NODEJS__) {\n return createDecoder({\n read: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length],\n });\n }\n\n return mapDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n value.padEnd(Math.ceil(value.length / 4) * 4, '='),\n );\n};\n\n/** Encodes and decodes strings in base64. */\nexport const getBase64Codec = (): VariableSizeCodec<string> => combineCodec(getBase64Encoder(), getBase64Decoder());\n","import {\n combineCodec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n mapEncoder,\n} from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\n\nexport type Address<TAddress extends string = string> = TAddress & {\n readonly __brand: unique symbol;\n};\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n return memoizedBase58Decoder;\n}\n\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n try {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n throw new Error('Expected input string to decode to a byte array of length 32.');\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);\n }\n } catch (e) {\n throw new Error(`\\`${putativeAddress}\\` is not a base-58 encoded address`, {\n cause: e,\n });\n }\n}\n\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n assertIsAddress(putativeAddress);\n return putativeAddress as Address<TAddress>;\n}\n\nexport function getAddressEncoder(): FixedSizeEncoder<Address, 32> {\n return mapEncoder(getStringEncoder({ encoding: getMemoizedBase58Encoder(), size: 32 }), putativeAddress =>\n address(putativeAddress),\n );\n}\n\nexport function getAddressDecoder(): FixedSizeDecoder<Address, 32> {\n return getStringDecoder({ encoding: getMemoizedBase58Decoder(), size: 32 }) as FixedSizeDecoder<Address, 32>;\n}\n\nexport function getAddressCodec(): FixedSizeCodec<Address, Address, 32> {\n return combineCodec(getAddressEncoder(), getAddressDecoder());\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n return new Intl.Collator('en', {\n caseFirst: 'lower',\n ignorePunctuation: false,\n localeMatcher: 'best fit',\n numeric: false,\n sensitivity: 'variant',\n usage: 'sort',\n }).compare;\n}\n","import { type Address, assertIsAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n appendTransactionInstruction,\n createTransaction,\n type IDurableNonceTransaction,\n isAdvanceNonceAccountInstruction,\n type ITransactionWithBlockhashLifetime,\n type ITransactionWithFeePayer,\n type ITransactionWithSignatures,\n type Nonce,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n setTransactionLifetimeUsingDurableNonce,\n type Transaction,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number,\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n // TODO coded error\n throw new Error(`Could not find account address at index ${accountIndex}`);\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Address,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction,\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n // TODO coded error\n throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex),\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Address,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[],\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Address;\n return { ...acc, [address]: sig as SignatureBytes };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint,\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n\nexport function fromVersionedTransactionWithDurableNonce(\n transaction: VersionedTransaction,\n): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n // TODO: coded error\n if (!feePayer) throw new Error('No fee payer set in VersionedTransaction');\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n // Check first instruction is durable nonce + extract params\n if (instructions.length === 0) {\n // TODO: coded error\n throw new Error('transaction with no instructions cannot be durable nonce transaction');\n }\n\n if (!isAdvanceNonceAccountInstruction(instructions[0])) {\n // TODO: coded error\n throw new Error('transaction first instruction is not advance nonce account instruction');\n }\n\n // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n const nonceAccountAddress = instructions[0].accounts![0].address;\n assertIsAddress(nonceAccountAddress);\n\n const nonceAuthorityAddress = instructions[0].accounts![2].address;\n assertIsAddress(nonceAuthorityAddress);\n\n const durableNonceLifetime = {\n nonce: transaction.message.recentBlockhash as Nonce,\n nonceAccountAddress,\n nonceAuthorityAddress,\n };\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),\n tx =>\n instructions.slice(1).reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/address.ts","../src/keypair.ts","../../codecs-core/src/bytes.ts","../../codecs-core/src/codec.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/base64.ts","../../addresses/src/address.ts","../src/transaction.ts"],"names":["SolanaError","alphabet","createEncoder","isSolanaError","e"],"mappings":"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","sourcesContent":["import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS PublicKey to a base58 encoded address\n * @param publicKey The PublicKey to convert\n * @returns An Address\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n return publicKey.toBase58() as Address<TAddress>;\n}\n","import { createKeyPairFromBytes } from '@solana/keys';\nimport { Keypair } from '@solana/web3.js';\n\n/**\n * Convert from a Legacy Web3 JS Keypair to a CryptoKeyPair\n * @param keypair The Keypair to convert\n * @returns A CryptoKeyPair\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n const bytes = new Uint8Array(64);\n bytes.set(keypair.secretKey);\n bytes.set(keypair.publicKey.toBytes(), /* offset */ 32);\n return createKeyPairFromBytes(bytes, extractable);\n}\n","/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n if (nonEmptyByteArrays.length === 0) {\n return byteArrays.length ? byteArrays[0] : new Uint8Array();\n }\n\n if (nonEmptyByteArrays.length === 1) {\n return nonEmptyByteArrays[0];\n }\n\n const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n nonEmptyByteArrays.forEach(arr => {\n result.set(arr, offset);\n offset += arr.length;\n });\n return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n */\nexport const padBytes = (bytes: Uint8Array, length: number): Uint8Array => {\n if (bytes.length >= length) return bytes;\n const paddedBytes = new Uint8Array(length).fill(0);\n paddedBytes.set(bytes);\n return paddedBytes;\n};\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n */\nexport const fixBytes = (bytes: Uint8Array, length: number): Uint8Array =>\n padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n","import {\n SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH,\n SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH,\n SolanaError,\n} from '@solana/errors';\n\n/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\ntype BaseEncoder<TFrom> = {\n /** Encode the provided value and return the encoded bytes directly. */\n readonly encode: (value: TFrom) => Uint8Array;\n /**\n * Writes the encoded value into the provided byte array at the given offset.\n * Returns the offset of the next byte after the encoded value.\n */\n readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n /** The total size of the encoded value in bytes. */\n readonly getSizeFromValue: (value: TFrom) => number;\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value to a `Uint8Array`.\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\ntype BaseDecoder<TTo> = {\n /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n readonly decode: (bytes: Uint8Array, offset?: Offset) => TTo;\n /**\n * Reads the encoded value from the provided byte array at the given offset.\n * Returns the decoded value and the offset of the next byte after the encoded value.\n */\n readonly read: (bytes: Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n /** The fixed size of the encoded value in bytes. */\n readonly fixedSize: TSize;\n};\n\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n /** The maximum size an encoded value can be in bytes, if applicable. */\n readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a value from a `Uint8Array`.\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeEncoder<\n TFrom,\n TSize\n> &\n FixedSizeDecoder<TTo, TSize>;\n\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeEncoder<TFrom> & VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a `Uint8Array`.\n * It supports encoding looser types than it decodes for convenience.\n * For example, a `bigint` encoder will always decode to a `bigint`\n * but can be used to encode a `number`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value. Defaults to `TFrom`.\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Get the encoded size of a given value in bytes.\n */\nexport function getEncodedSize<TFrom>(\n value: TFrom,\n encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/** Fills the missing `encode` function using the existing `write` function. */\nexport function createEncoder<TFrom, TSize extends number>(\n encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n return Object.freeze({\n ...encoder,\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, encoder));\n encoder.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\n/** Fills the missing `decode` function using the existing `read` function. */\nexport function createDecoder<TTo, TSize extends number>(\n decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n return Object.freeze({\n ...decoder,\n decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n });\n}\n\n/** Fills the missing `encode` and `decode` function using the existing `write` and `read` functions. */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'encode' | 'decode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec: Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n codec:\n | Omit<FixedSizeCodec<TFrom, TTo>, 'encode' | 'decode'>\n | Omit<VariableSizeCodec<TFrom, TTo>, 'encode' | 'decode'>,\n): Codec<TFrom, TTo> {\n return Object.freeze({\n ...codec,\n decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n encode: value => {\n const bytes = new Uint8Array(getEncodedSize(value, codec));\n codec.write(value, bytes, 0);\n return bytes;\n },\n });\n}\n\nexport function isFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n codec: { fixedSize: TSize } | { maxSize?: number },\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { fixedSize: number } {\n if (!isFixedSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_FIXED_LENGTH_GOT_VARIABLE_LENGTH);\n }\n}\n\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n return !isFixedSize(codec);\n}\n\nexport function assertIsVariableSize<T>(encoder: Encoder<T>): asserts encoder is VariableSizeEncoder<T>;\nexport function assertIsVariableSize<T>(decoder: Decoder<T>): asserts decoder is VariableSizeDecoder<T>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n codec: Codec<TFrom, TTo>,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number } {\n if (!isVariableSize(codec)) {\n throw new SolanaError(SOLANA_ERROR__CODECS_EXPECTED_VARIABLE_LENGTH_GOT_FIXED_LENGTH);\n }\n}\n","import { SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\n/**\n * Asserts that a given string matches a given alphabet.\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: alphabet.length,\n value: givenValue,\n });\n }\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Encodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXEncoder = (alphabet: string): VariableSizeEncoder<string> => {\n return createEncoder({\n getSizeFromValue: (value: string): number => {\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) return value.length;\n\n const base10Number = getBigIntFromBaseX(tailChars, alphabet);\n return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);\n },\n write(value: string, bytes, offset) {\n // Check if the value is valid.\n assertValidBaseString(alphabet, value);\n if (value === '') return offset;\n\n // Handle leading zeroes.\n const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n if (!tailChars) {\n bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);\n return offset + leadingZeroes.length;\n }\n\n // From baseX to base10.\n let base10Number = getBigIntFromBaseX(tailChars, alphabet);\n\n // From base10 to bytes.\n const tailBytes: number[] = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n\n const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];\n bytes.set(bytesToAdd, offset);\n return offset + bytesToAdd.length;\n },\n });\n};\n\n/**\n * Decodes a string using a custom alphabet by dividing\n * by the base and handling leading zeroes.\n * @see {@link getBaseXCodec} for a more detailed description.\n */\nexport const getBaseXDecoder = (alphabet: string): VariableSizeDecoder<string> => {\n return createDecoder({\n read(rawBytes, offset): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', 0];\n\n // Handle leading zeroes.\n let trailIndex = bytes.findIndex(n => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet[0].repeat(trailIndex);\n if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n // From bytes to base10.\n const base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n // From base10 to baseX.\n const tailChars = getBaseXFromBigInt(base10Number, alphabet);\n\n return [leadingZeroes + tailChars, rawBytes.length];\n },\n });\n};\n\n/**\n * A string codec that requires a custom alphabet and uses\n * the length of that alphabet as the base. It then divides\n * the input by the base as many times as necessary to get\n * the output. It also supports leading zeroes by using the\n * first character of the alphabet as the zero character.\n *\n * This can be used to create codecs such as base10 or base58.\n */\nexport const getBaseXCodec = (alphabet: string): VariableSizeCodec<string> =>\n combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n\nfunction partitionLeadingZeroes(\n value: string,\n zeroCharacter: string,\n): [leadingZeros: string, tailChars: string | undefined] {\n const [leadingZeros, tailChars] = value.split(new RegExp(`((?!${zeroCharacter}).*)`));\n return [leadingZeros, tailChars];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n const base = BigInt(alphabet.length);\n let sum = 0n;\n for (const char of value) {\n sum *= base;\n sum += BigInt(alphabet.indexOf(char));\n }\n return sum;\n}\n\nfunction getBaseXFromBigInt(value: bigint, alphabet: string): string {\n const base = BigInt(alphabet.length);\n const tailChars = [];\n while (value > 0n) {\n tailChars.unshift(alphabet[Number(value % base)]);\n value /= base;\n }\n return tailChars.join('');\n}\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/** Encodes strings in base16. */\nexport const getBase16Encoder = (): VariableSizeEncoder<string> =>\n createEncoder({\n getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n write(value: string, bytes, offset) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString('0123456789abcdef', lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n bytes.set(hexBytes, offset);\n return hexBytes.length + offset;\n },\n });\n\n/** Decodes strings in base16. */\nexport const getBase16Decoder = (): VariableSizeDecoder<string> =>\n createDecoder({\n read(bytes, offset) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n return [value, bytes.length];\n },\n });\n\n/** Encodes and decodes strings in base16. */\nexport const getBase16Codec = (): VariableSizeCodec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n","import {\n combineCodec,\n createDecoder,\n createEncoder,\n mapDecoder,\n mapEncoder,\n VariableSizeCodec,\n VariableSizeDecoder,\n VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/** Encodes strings in base64. */\nexport const getBase64Encoder = (): VariableSizeEncoder<string> => {\n if (__BROWSER__) {\n return createEncoder({\n getSizeFromValue: (value: string) => {\n try {\n return (atob as Window['atob'])(value).length;\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: 64,\n value,\n });\n }\n },\n write(value: string, bytes, offset) {\n try {\n const bytesToAdd = (atob as Window['atob'])(value)\n .split('')\n .map(c => c.charCodeAt(0));\n bytes.set(bytesToAdd, offset);\n return bytesToAdd.length + offset;\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__CODECS_INVALID_STRING_FOR_BASE, {\n alphabet,\n base: 64,\n value,\n });\n }\n },\n });\n }\n\n if (__NODEJS__) {\n return createEncoder({\n getSizeFromValue: (value: string) => Buffer.from(value, 'base64').length,\n write(value: string, bytes, offset) {\n assertValidBaseString(alphabet, value.replace(/=/g, ''));\n const buffer = Buffer.from(value, 'base64');\n bytes.set(buffer, offset);\n return buffer.length + offset;\n },\n });\n }\n\n return mapEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/** Decodes strings in base64. */\nexport const getBase64Decoder = (): VariableSizeDecoder<string> => {\n if (__BROWSER__) {\n return createDecoder({\n read(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n });\n }\n\n if (__NODEJS__) {\n return createDecoder({\n read: (bytes, offset = 0) => [Buffer.from(bytes, offset).toString('base64'), bytes.length],\n });\n }\n\n return mapDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n value.padEnd(Math.ceil(value.length / 4) * 4, '='),\n );\n};\n\n/** Encodes and decodes strings in base64. */\nexport const getBase64Codec = (): VariableSizeCodec<string> => combineCodec(getBase64Encoder(), getBase64Decoder());\n","import {\n combineCodec,\n Decoder,\n Encoder,\n FixedSizeCodec,\n FixedSizeDecoder,\n FixedSizeEncoder,\n mapEncoder,\n} from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\nimport {\n SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH,\n SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH,\n SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS,\n SolanaError,\n} from '@solana/errors';\n\nexport type Address<TAddress extends string = string> = TAddress & {\n readonly __brand: unique symbol;\n};\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n return memoizedBase58Decoder;\n}\n\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n return false;\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n try {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeAddress.length > 44\n ) {\n throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_LENGTH, {\n actualLength: putativeAddress.length,\n });\n }\n // Slow-path; actually attempt to decode the input string.\n const base58Encoder = getMemoizedBase58Encoder();\n const bytes = base58Encoder.encode(putativeAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n throw new SolanaError(SOLANA_ERROR__INCORRECT_BASE58_ADDRESS_BYTE_LENGTH, {\n actualLength: numBytes,\n });\n }\n } catch (e) {\n throw new SolanaError(SOLANA_ERROR__NOT_A_BASE58_ENCODED_ADDRESS, { putativeAddress });\n }\n}\n\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n assertIsAddress(putativeAddress);\n return putativeAddress as Address<TAddress>;\n}\n\nexport function getAddressEncoder(): FixedSizeEncoder<Address, 32> {\n return mapEncoder(getStringEncoder({ encoding: getMemoizedBase58Encoder(), size: 32 }), putativeAddress =>\n address(putativeAddress),\n );\n}\n\nexport function getAddressDecoder(): FixedSizeDecoder<Address, 32> {\n return getStringDecoder({ encoding: getMemoizedBase58Decoder(), size: 32 }) as FixedSizeDecoder<Address, 32>;\n}\n\nexport function getAddressCodec(): FixedSizeCodec<Address, Address, 32> {\n return combineCodec(getAddressEncoder(), getAddressDecoder());\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n return new Intl.Collator('en', {\n caseFirst: 'lower',\n ignorePunctuation: false,\n localeMatcher: 'best fit',\n numeric: false,\n sensitivity: 'variant',\n usage: 'sort',\n }).compare;\n}\n","import { type Address, assertIsAddress } from '@solana/addresses';\nimport {\n SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE,\n SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS,\n SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS,\n SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER,\n SolanaError,\n} from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n appendTransactionInstruction,\n createTransaction,\n type IDurableNonceTransaction,\n isAdvanceNonceAccountInstruction,\n type ITransactionWithBlockhashLifetime,\n type ITransactionWithFeePayer,\n type ITransactionWithSignatures,\n type Nonce,\n setTransactionFeePayer,\n setTransactionLifetimeUsingBlockhash,\n setTransactionLifetimeUsingDurableNonce,\n type Transaction,\n} from '@solana/transactions';\nimport type {\n MessageAccountKeys,\n MessageCompiledInstruction,\n PublicKey,\n VersionedMessage,\n VersionedTransaction,\n} from '@solana/web3.js';\n\nfunction convertAccount(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n accountIndex: number,\n): IAccountMeta {\n const accountPublicKey = accountKeys.get(accountIndex);\n if (!accountPublicKey) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {\n index: accountIndex,\n });\n }\n const isSigner = message.isAccountSigner(accountIndex);\n const isWritable = message.isAccountWritable(accountIndex);\n\n const role = isSigner\n ? isWritable\n ? AccountRole.WRITABLE_SIGNER\n : AccountRole.READONLY_SIGNER\n : isWritable\n ? AccountRole.WRITABLE\n : AccountRole.READONLY;\n\n return {\n address: accountPublicKey.toBase58() as Address,\n role,\n };\n}\n\nfunction convertInstruction(\n message: VersionedMessage,\n accountKeys: MessageAccountKeys,\n instruction: MessageCompiledInstruction,\n): IInstruction {\n const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);\n if (!programAddressPublicKey) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_ADDRESS, {\n index: instruction.programIdIndex,\n });\n }\n\n const accounts = instruction.accountKeyIndexes.map(accountIndex =>\n convertAccount(message, accountKeys, accountIndex),\n );\n\n return {\n programAddress: programAddressPublicKey.toBase58() as Address,\n ...(accounts.length ? { accounts } : {}),\n ...(instruction.data.length ? { data: instruction.data } : {}),\n };\n}\n\nfunction convertSignatures(\n transaction: VersionedTransaction,\n staticAccountKeys: PublicKey[],\n): ITransactionWithSignatures['signatures'] {\n return transaction.signatures.reduce((acc, sig, index) => {\n // legacy web3js includes a fake all 0 signature if it hasn't been signed\n // we don't do that for the new tx model. So just skip if it's all 0s\n const allZeros = sig.every(byte => byte === 0);\n if (allZeros) return acc;\n\n const address = staticAccountKeys[index].toBase58() as Address;\n return { ...acc, [address]: sig as SignatureBytes };\n }, {});\n}\n\nexport function fromVersionedTransactionWithBlockhash(\n transaction: VersionedTransaction,\n lastValidBlockHeight?: bigint,\n): Transaction & ITransactionWithFeePayer & ITransactionWithBlockhashLifetime {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n // This should probably not be a `SolanaError`, since we need to add\n // this functionality.\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n if (!feePayer) throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);\n\n const blockhashLifetime = {\n blockhash: transaction.message.recentBlockhash as Blockhash,\n lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n };\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),\n tx =>\n instructions.reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n\nexport function fromVersionedTransactionWithDurableNonce(\n transaction: VersionedTransaction,\n): Transaction & ITransactionWithFeePayer & IDurableNonceTransaction {\n // TODO: add support for address table lookups\n // - will need to take `AddressLookupTableAccounts[]` as input\n // - will need to convert account instructions to `IAccountLookupMeta` when appropriate\n if (transaction.message.addressTableLookups.length > 0) {\n // TODO coded error\n // This should probably not be a `SolanaError`, since we need to add\n // this functionality.\n throw new Error('Cannot convert transaction with addressTableLookups');\n }\n\n const accountKeys = transaction.message.getAccountKeys();\n\n // Fee payer is first account\n const feePayer = accountKeys.staticAccountKeys[0];\n if (!feePayer) throw new SolanaError(SOLANA_ERROR__TRANSACTION_MISSING_FEE_PAYER);\n\n const instructions = transaction.message.compiledInstructions.map(instruction =>\n convertInstruction(transaction.message, accountKeys, instruction),\n );\n\n // Check first instruction is durable nonce + extract params\n if (instructions.length === 0) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_NO_INSTRUCTIONS);\n }\n\n if (!isAdvanceNonceAccountInstruction(instructions[0])) {\n throw new SolanaError(SOLANA_ERROR__TRANSACTION_INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_NOT_ADVANCE_NONCE);\n }\n\n // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n const nonceAccountAddress = instructions[0].accounts![0].address;\n assertIsAddress(nonceAccountAddress);\n\n const nonceAuthorityAddress = instructions[0].accounts![2].address;\n assertIsAddress(nonceAuthorityAddress);\n\n const durableNonceLifetime = {\n nonce: transaction.message.recentBlockhash as Nonce,\n nonceAccountAddress,\n nonceAuthorityAddress,\n };\n\n const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);\n\n return pipe(\n createTransaction({ version: transaction.version }),\n tx => setTransactionFeePayer(feePayer.toBase58() as Address, tx),\n tx => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),\n tx =>\n instructions.slice(1).reduce((acc, instruction) => {\n return appendTransactionInstruction(instruction, acc);\n }, tx),\n tx => (transaction.signatures.length ? { ...tx, signatures } : tx),\n );\n}\n"]}