@solana/compat 2.0.0-experimental.03b965b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2023 Solana Labs, Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ [![npm][npm-image]][npm-url]
2
+ [![npm-downloads][npm-downloads-image]][npm-url]
3
+ [![semantic-release][semantic-release-image]][semantic-release-url]
4
+ <br />
5
+ [![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]
6
+
7
+ [code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
8
+ [code-style-prettier-url]: https://github.com/prettier/prettier
9
+ [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/compat/experimental.svg?style=flat
10
+ [npm-image]: https://img.shields.io/npm/v/@solana/compat/experimental.svg?style=flat
11
+ [npm-url]: https://www.npmjs.com/package/@solana/compat/v/experimental
12
+ [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
13
+ [semantic-release-url]: https://github.com/semantic-release/semantic-release
14
+
15
+ # @solana/compat
16
+
17
+ This package contains utilities for converting from legacy web3js classes to the new data structures. It can be used standalone, but it is also exported as part of the Solana JavaScript SDK [`@solana/web3.js@experimental`](https://github.com/solana-labs/solana-web3.js/tree/master/packages/library).
18
+
19
+ ## Types
20
+
21
+ TODO
22
+
23
+ ## Functions
24
+
25
+ TODO
@@ -0,0 +1,181 @@
1
+ 'use strict';
2
+
3
+ var functional = require('@solana/functional');
4
+ var instructions = require('@solana/instructions');
5
+ var transactions = require('@solana/transactions');
6
+
7
+ // ../codecs-strings/dist/index.browser.js
8
+ function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
9
+ if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
10
+ throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
11
+ }
12
+ }
13
+ var getBaseXEncoder = (alphabet4) => {
14
+ const base = alphabet4.length;
15
+ const baseBigInt = BigInt(base);
16
+ return {
17
+ description: `base${base}`,
18
+ encode(value) {
19
+ assertValidBaseString(alphabet4, value);
20
+ if (value === "")
21
+ return new Uint8Array();
22
+ const chars = [...value];
23
+ let trailIndex = chars.findIndex((c) => c !== alphabet4[0]);
24
+ trailIndex = trailIndex === -1 ? chars.length : trailIndex;
25
+ const leadingZeroes = Array(trailIndex).fill(0);
26
+ if (trailIndex === chars.length)
27
+ return Uint8Array.from(leadingZeroes);
28
+ const tailChars = chars.slice(trailIndex);
29
+ let base10Number = 0n;
30
+ let baseXPower = 1n;
31
+ for (let i = tailChars.length - 1; i >= 0; i -= 1) {
32
+ base10Number += baseXPower * BigInt(alphabet4.indexOf(tailChars[i]));
33
+ baseXPower *= baseBigInt;
34
+ }
35
+ const tailBytes = [];
36
+ while (base10Number > 0n) {
37
+ tailBytes.unshift(Number(base10Number % 256n));
38
+ base10Number /= 256n;
39
+ }
40
+ return Uint8Array.from(leadingZeroes.concat(tailBytes));
41
+ },
42
+ fixedSize: null,
43
+ maxSize: null
44
+ };
45
+ };
46
+ var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
47
+ var getBase58Encoder = () => getBaseXEncoder(alphabet2);
48
+
49
+ // ../addresses/dist/index.browser.js
50
+ var memoizedBase58Encoder;
51
+ function getMemoizedBase58Encoder() {
52
+ if (!memoizedBase58Encoder)
53
+ memoizedBase58Encoder = getBase58Encoder();
54
+ return memoizedBase58Encoder;
55
+ }
56
+ function assertIsAddress(putativeBase58EncodedAddress) {
57
+ try {
58
+ if (
59
+ // Lowest address (32 bytes of zeroes)
60
+ putativeBase58EncodedAddress.length < 32 || // Highest address (32 bytes of 255)
61
+ putativeBase58EncodedAddress.length > 44
62
+ ) {
63
+ throw new Error("Expected input string to decode to a byte array of length 32.");
64
+ }
65
+ const base58Encoder = getMemoizedBase58Encoder();
66
+ const bytes = base58Encoder.encode(putativeBase58EncodedAddress);
67
+ const numBytes = bytes.byteLength;
68
+ if (numBytes !== 32) {
69
+ throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
70
+ }
71
+ } catch (e2) {
72
+ throw new Error(`\`${putativeBase58EncodedAddress}\` is not a base-58 encoded address`, {
73
+ cause: e2
74
+ });
75
+ }
76
+ }
77
+ function convertAccount(message, accountKeys, accountIndex) {
78
+ const accountPublicKey = accountKeys.get(accountIndex);
79
+ if (!accountPublicKey) {
80
+ throw new Error(`Could not find account address at index ${accountIndex}`);
81
+ }
82
+ const isSigner = message.isAccountSigner(accountIndex);
83
+ const isWritable = message.isAccountWritable(accountIndex);
84
+ const role = isSigner ? isWritable ? instructions.AccountRole.WRITABLE_SIGNER : instructions.AccountRole.READONLY_SIGNER : isWritable ? instructions.AccountRole.WRITABLE : instructions.AccountRole.READONLY;
85
+ return {
86
+ address: accountPublicKey.toBase58(),
87
+ role
88
+ };
89
+ }
90
+ function convertInstruction(message, accountKeys, instruction) {
91
+ const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);
92
+ if (!programAddressPublicKey) {
93
+ throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);
94
+ }
95
+ const accounts = instruction.accountKeyIndexes.map(
96
+ (accountIndex) => convertAccount(message, accountKeys, accountIndex)
97
+ );
98
+ return {
99
+ programAddress: programAddressPublicKey.toBase58(),
100
+ ...accounts.length ? { accounts } : {},
101
+ ...instruction.data.length ? { data: instruction.data } : {}
102
+ };
103
+ }
104
+ function convertSignatures(transaction, staticAccountKeys) {
105
+ return transaction.signatures.reduce((acc, sig, index) => {
106
+ const allZeros = sig.every((byte) => byte === 0);
107
+ if (allZeros)
108
+ return acc;
109
+ const address = staticAccountKeys[index].toBase58();
110
+ return { ...acc, [address]: sig };
111
+ }, {});
112
+ }
113
+ function fromVersionedTransactionWithBlockhash(transaction, lastValidBlockHeight) {
114
+ if (transaction.message.addressTableLookups.length > 0) {
115
+ throw new Error("Cannot convert transaction with addressTableLookups");
116
+ }
117
+ const accountKeys = transaction.message.getAccountKeys();
118
+ const feePayer = accountKeys.staticAccountKeys[0];
119
+ if (!feePayer)
120
+ throw new Error("No fee payer set in VersionedTransaction");
121
+ const blockhashLifetime = {
122
+ blockhash: transaction.message.recentBlockhash,
123
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
124
+ // U64 MAX
125
+ };
126
+ const instructions = transaction.message.compiledInstructions.map(
127
+ (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
128
+ );
129
+ const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);
130
+ return functional.pipe(
131
+ transactions.createTransaction({ version: transaction.version }),
132
+ (tx) => transactions.setTransactionFeePayer(feePayer.toBase58(), tx),
133
+ (tx) => transactions.setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),
134
+ (tx) => instructions.reduce((acc, instruction) => {
135
+ return transactions.appendTransactionInstruction(instruction, acc);
136
+ }, tx),
137
+ (tx) => transaction.signatures.length ? { ...tx, signatures } : tx
138
+ );
139
+ }
140
+ function fromVersionedTransactionWithDurableNonce(transaction) {
141
+ if (transaction.message.addressTableLookups.length > 0) {
142
+ throw new Error("Cannot convert transaction with addressTableLookups");
143
+ }
144
+ const accountKeys = transaction.message.getAccountKeys();
145
+ const feePayer = accountKeys.staticAccountKeys[0];
146
+ if (!feePayer)
147
+ throw new Error("No fee payer set in VersionedTransaction");
148
+ const instructions = transaction.message.compiledInstructions.map(
149
+ (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
150
+ );
151
+ if (instructions.length === 0) {
152
+ throw new Error("transaction with no instructions cannot be durable nonce transaction");
153
+ }
154
+ if (!transactions.isAdvanceNonceAccountInstruction(instructions[0])) {
155
+ throw new Error("transaction first instruction is not advance nonce account instruction");
156
+ }
157
+ const nonceAccountAddress = instructions[0].accounts[0].address;
158
+ assertIsAddress(nonceAccountAddress);
159
+ const nonceAuthorityAddress = instructions[0].accounts[2].address;
160
+ assertIsAddress(nonceAuthorityAddress);
161
+ const durableNonceLifetime = {
162
+ nonce: transaction.message.recentBlockhash,
163
+ nonceAccountAddress,
164
+ nonceAuthorityAddress
165
+ };
166
+ const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);
167
+ return functional.pipe(
168
+ transactions.createTransaction({ version: transaction.version }),
169
+ (tx) => transactions.setTransactionFeePayer(feePayer.toBase58(), tx),
170
+ (tx) => transactions.setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),
171
+ (tx) => instructions.slice(1).reduce((acc, instruction) => {
172
+ return transactions.appendTransactionInstruction(instruction, acc);
173
+ }, tx),
174
+ (tx) => transaction.signatures.length ? { ...tx, signatures } : tx
175
+ );
176
+ }
177
+
178
+ exports.fromVersionedTransactionWithBlockhash = fromVersionedTransactionWithBlockhash;
179
+ exports.fromVersionedTransactionWithDurableNonce = fromVersionedTransactionWithDurableNonce;
180
+ //# sourceMappingURL=out.js.map
181
+ //# sourceMappingURL=index.browser.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../codecs-strings/dist/index.browser.js","../../addresses/src/address.ts","../src/transaction.ts"],"names":["e"],"mappings":"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","sourcesContent":["import { combineCodec, fixEncoder, mergeBytes, fixDecoder, assertByteArrayIsNotEmptyForCodec, assertByteArrayHasEnoughBytesForCodec } from '@solana/codecs-core';\nimport { getU32Encoder, getU32Decoder } from '@solana/codecs-numbers';\n\n// src/assertions.ts\nfunction assertValidBaseString(alphabet4, testValue, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {\n throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);\n }\n}\nvar getBaseXEncoder = (alphabet4) => {\n const base = alphabet4.length;\n const baseBigInt = BigInt(base);\n return {\n description: `base${base}`,\n encode(value) {\n assertValidBaseString(alphabet4, value);\n if (value === \"\")\n return new Uint8Array();\n const chars = [...value];\n let trailIndex = chars.findIndex((c) => c !== alphabet4[0]);\n trailIndex = trailIndex === -1 ? chars.length : trailIndex;\n const leadingZeroes = Array(trailIndex).fill(0);\n if (trailIndex === chars.length)\n return Uint8Array.from(leadingZeroes);\n const tailChars = chars.slice(trailIndex);\n let base10Number = 0n;\n let baseXPower = 1n;\n for (let i = tailChars.length - 1; i >= 0; i -= 1) {\n base10Number += baseXPower * BigInt(alphabet4.indexOf(tailChars[i]));\n baseXPower *= baseBigInt;\n }\n const tailBytes = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n return Uint8Array.from(leadingZeroes.concat(tailBytes));\n },\n fixedSize: null,\n maxSize: null\n };\n};\nvar getBaseXDecoder = (alphabet4) => {\n const base = alphabet4.length;\n const baseBigInt = BigInt(base);\n return {\n decode(rawBytes, offset = 0) {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0)\n return [\"\", 0];\n let trailIndex = bytes.findIndex((n) => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet4[0].repeat(trailIndex);\n if (trailIndex === bytes.length)\n return [leadingZeroes, rawBytes.length];\n let base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n const tailChars = [];\n while (base10Number > 0n) {\n tailChars.unshift(alphabet4[Number(base10Number % baseBigInt)]);\n base10Number /= baseBigInt;\n }\n return [leadingZeroes + tailChars.join(\"\"), rawBytes.length];\n },\n description: `base${base}`,\n fixedSize: null,\n maxSize: null\n };\n};\nvar getBaseXCodec = (alphabet4) => combineCodec(getBaseXEncoder(alphabet4), getBaseXDecoder(alphabet4));\n\n// src/base10.ts\nvar alphabet = \"0123456789\";\nvar getBase10Encoder = () => getBaseXEncoder(alphabet);\nvar getBase10Decoder = () => getBaseXDecoder(alphabet);\nvar getBase10Codec = () => getBaseXCodec(alphabet);\nvar getBase16Encoder = () => ({\n description: \"base16\",\n encode(value) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString(\"0123456789abcdef\", lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n return Uint8Array.from(matches ? matches.map((byte) => parseInt(byte, 16)) : []);\n },\n fixedSize: null,\n maxSize: null\n});\nvar getBase16Decoder = () => ({\n decode(bytes, offset = 0) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, \"0\"), \"\");\n return [value, bytes.length];\n },\n description: \"base16\",\n fixedSize: null,\n maxSize: null\n});\nvar getBase16Codec = () => combineCodec(getBase16Encoder(), getBase16Decoder());\n\n// src/base58.ts\nvar alphabet2 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nvar getBase58Encoder = () => getBaseXEncoder(alphabet2);\nvar getBase58Decoder = () => getBaseXDecoder(alphabet2);\nvar getBase58Codec = () => getBaseXCodec(alphabet2);\nvar getBaseXResliceEncoder = (alphabet4, bits) => ({\n description: `base${alphabet4.length}`,\n encode(value) {\n assertValidBaseString(alphabet4, value);\n if (value === \"\")\n return new Uint8Array();\n const charIndices = [...value].map((c) => alphabet4.indexOf(c));\n return new Uint8Array(reslice(charIndices, bits, 8, false));\n },\n fixedSize: null,\n maxSize: null\n});\nvar getBaseXResliceDecoder = (alphabet4, bits) => ({\n decode(rawBytes, offset = 0) {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0)\n return [\"\", rawBytes.length];\n const charIndices = reslice([...bytes], 8, bits, true);\n return [charIndices.map((i) => alphabet4[i]).join(\"\"), rawBytes.length];\n },\n description: `base${alphabet4.length}`,\n fixedSize: null,\n maxSize: null\n});\nvar getBaseXResliceCodec = (alphabet4, bits) => combineCodec(getBaseXResliceEncoder(alphabet4, bits), getBaseXResliceDecoder(alphabet4, bits));\nfunction reslice(input, inputBits, outputBits, useRemainder) {\n const output = [];\n let accumulator = 0;\n let bitsInAccumulator = 0;\n const mask = (1 << outputBits) - 1;\n for (const value of input) {\n accumulator = accumulator << inputBits | value;\n bitsInAccumulator += inputBits;\n while (bitsInAccumulator >= outputBits) {\n bitsInAccumulator -= outputBits;\n output.push(accumulator >> bitsInAccumulator & mask);\n }\n }\n if (useRemainder && bitsInAccumulator > 0) {\n output.push(accumulator << outputBits - bitsInAccumulator & mask);\n }\n return output;\n}\nvar getBase64Encoder = () => {\n {\n return {\n description: `base64`,\n encode(value) {\n try {\n const bytes = atob(value).split(\"\").map((c) => c.charCodeAt(0));\n return new Uint8Array(bytes);\n } catch (e2) {\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n fixedSize: null,\n maxSize: null\n };\n }\n};\nvar getBase64Decoder = () => {\n {\n return {\n decode(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = btoa(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n description: `base64`,\n fixedSize: null,\n maxSize: null\n };\n }\n};\nvar getBase64Codec = () => combineCodec(getBase64Encoder(), getBase64Decoder());\n\n// src/null-characters.ts\nvar removeNullCharacters = (value) => (\n // eslint-disable-next-line no-control-regex\n value.replace(/\\u0000/g, \"\")\n);\nvar padNullCharacters = (value, chars) => value.padEnd(chars, \"\\0\");\n\n// ../text-encoding-impl/dist/index.browser.js\nvar e = globalThis.TextDecoder;\nvar o = globalThis.TextEncoder;\n\n// src/utf8.ts\nvar getUtf8Encoder = () => {\n let textEncoder;\n return {\n description: \"utf8\",\n encode: (value) => new Uint8Array((textEncoder || (textEncoder = new o())).encode(value)),\n fixedSize: null,\n maxSize: null\n };\n};\nvar getUtf8Decoder = () => {\n let textDecoder;\n return {\n decode(bytes, offset = 0) {\n const value = (textDecoder || (textDecoder = new e())).decode(bytes.slice(offset));\n return [removeNullCharacters(value), bytes.length];\n },\n description: \"utf8\",\n fixedSize: null,\n maxSize: null\n };\n};\nvar getUtf8Codec = () => combineCodec(getUtf8Encoder(), getUtf8Decoder());\n\n// src/string.ts\nvar getStringEncoder = (options = {}) => {\n const size = options.size ?? getU32Encoder();\n const encoding = options.encoding ?? getUtf8Encoder();\n const description = options.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`;\n if (size === \"variable\") {\n return { ...encoding, description };\n }\n if (typeof size === \"number\") {\n return fixEncoder(encoding, size, description);\n }\n return {\n description,\n encode: (value) => {\n const contentBytes = encoding.encode(value);\n const lengthBytes = size.encode(contentBytes.length);\n return mergeBytes([lengthBytes, contentBytes]);\n },\n fixedSize: null,\n maxSize: null\n };\n};\nvar getStringDecoder = (options = {}) => {\n const size = options.size ?? getU32Decoder();\n const encoding = options.encoding ?? getUtf8Decoder();\n const description = options.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`;\n if (size === \"variable\") {\n return { ...encoding, description };\n }\n if (typeof size === \"number\") {\n return fixDecoder(encoding, size, description);\n }\n return {\n decode: (bytes, offset = 0) => {\n assertByteArrayIsNotEmptyForCodec(\"string\", bytes, offset);\n const [lengthBigInt, lengthOffset] = size.decode(bytes, offset);\n const length = Number(lengthBigInt);\n offset = lengthOffset;\n const contentBytes = bytes.slice(offset, offset + length);\n assertByteArrayHasEnoughBytesForCodec(\"string\", length, contentBytes);\n const [value, contentOffset] = encoding.decode(contentBytes);\n offset += contentOffset;\n return [value, offset];\n },\n description,\n fixedSize: null,\n maxSize: null\n };\n};\nvar getStringCodec = (options = {}) => combineCodec(getStringEncoder(options), getStringDecoder(options));\nfunction getSizeDescription(size) {\n return typeof size === \"object\" ? size.description : `${size}`;\n}\n\nexport { assertValidBaseString, getBase10Codec, getBase10Decoder, getBase10Encoder, getBase16Codec, getBase16Decoder, getBase16Encoder, getBase58Codec, getBase58Decoder, getBase58Encoder, getBase64Codec, getBase64Decoder, getBase64Encoder, getBaseXCodec, getBaseXDecoder, getBaseXEncoder, getBaseXResliceCodec, getBaseXResliceDecoder, getBaseXResliceEncoder, getStringCodec, getStringDecoder, getStringEncoder, getUtf8Codec, getUtf8Decoder, getUtf8Encoder, padNullCharacters, removeNullCharacters };\n","import { Codec, combineCodec, Decoder, Encoder, mapEncoder } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\n\nexport type Base58EncodedAddress<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(\n putativeBase58EncodedAddress: string\n): putativeBase58EncodedAddress is Base58EncodedAddress<typeof putativeBase58EncodedAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeBase58EncodedAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeBase58EncodedAddress.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(putativeBase58EncodedAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(\n putativeBase58EncodedAddress: string\n): asserts putativeBase58EncodedAddress is Base58EncodedAddress<typeof putativeBase58EncodedAddress> {\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 putativeBase58EncodedAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeBase58EncodedAddress.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(putativeBase58EncodedAddress);\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(`\\`${putativeBase58EncodedAddress}\\` is not a base-58 encoded address`, {\n cause: e,\n });\n }\n}\n\nexport function address<TAddress extends string = string>(\n putativeBase58EncodedAddress: TAddress\n): Base58EncodedAddress<TAddress> {\n assertIsAddress(putativeBase58EncodedAddress);\n return putativeBase58EncodedAddress as Base58EncodedAddress<TAddress>;\n}\n\nexport function getAddressEncoder(config?: Readonly<{ description: string }>): Encoder<Base58EncodedAddress> {\n return mapEncoder(\n getStringEncoder({\n description: config?.description ?? 'Base58EncodedAddress',\n encoding: getMemoizedBase58Encoder(),\n size: 32,\n }),\n putativeAddress => address(putativeAddress)\n );\n}\n\nexport function getAddressDecoder(config?: Readonly<{ description: string }>): Decoder<Base58EncodedAddress> {\n return getStringDecoder({\n description: config?.description ?? 'Base58EncodedAddress',\n encoding: getMemoizedBase58Decoder(),\n size: 32,\n }) as Decoder<Base58EncodedAddress>;\n}\n\nexport function getAddressCodec(config?: Readonly<{ description: string }>): Codec<Base58EncodedAddress> {\n return combineCodec(getAddressEncoder(config), getAddressDecoder(config));\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 { assertIsAddress, type Base58EncodedAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { Ed25519Signature } from '@solana/keys';\nimport {\n appendTransactionInstruction,\n type Blockhash,\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 Base58EncodedAddress,\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 Base58EncodedAddress,\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 Base58EncodedAddress;\n return { ...acc, [address]: sig as Ed25519Signature };\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 // TOOD: add support for durable nonce transactions\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 Base58EncodedAddress, 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 Base58EncodedAddress, 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"]}
@@ -0,0 +1,178 @@
1
+ import { pipe } from '@solana/functional';
2
+ import { AccountRole } from '@solana/instructions';
3
+ import { createTransaction, setTransactionFeePayer, setTransactionLifetimeUsingBlockhash, appendTransactionInstruction, isAdvanceNonceAccountInstruction, setTransactionLifetimeUsingDurableNonce } from '@solana/transactions';
4
+
5
+ // ../codecs-strings/dist/index.browser.js
6
+ function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
7
+ if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
8
+ throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
9
+ }
10
+ }
11
+ var getBaseXEncoder = (alphabet4) => {
12
+ const base = alphabet4.length;
13
+ const baseBigInt = BigInt(base);
14
+ return {
15
+ description: `base${base}`,
16
+ encode(value) {
17
+ assertValidBaseString(alphabet4, value);
18
+ if (value === "")
19
+ return new Uint8Array();
20
+ const chars = [...value];
21
+ let trailIndex = chars.findIndex((c) => c !== alphabet4[0]);
22
+ trailIndex = trailIndex === -1 ? chars.length : trailIndex;
23
+ const leadingZeroes = Array(trailIndex).fill(0);
24
+ if (trailIndex === chars.length)
25
+ return Uint8Array.from(leadingZeroes);
26
+ const tailChars = chars.slice(trailIndex);
27
+ let base10Number = 0n;
28
+ let baseXPower = 1n;
29
+ for (let i = tailChars.length - 1; i >= 0; i -= 1) {
30
+ base10Number += baseXPower * BigInt(alphabet4.indexOf(tailChars[i]));
31
+ baseXPower *= baseBigInt;
32
+ }
33
+ const tailBytes = [];
34
+ while (base10Number > 0n) {
35
+ tailBytes.unshift(Number(base10Number % 256n));
36
+ base10Number /= 256n;
37
+ }
38
+ return Uint8Array.from(leadingZeroes.concat(tailBytes));
39
+ },
40
+ fixedSize: null,
41
+ maxSize: null
42
+ };
43
+ };
44
+ var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
45
+ var getBase58Encoder = () => getBaseXEncoder(alphabet2);
46
+
47
+ // ../addresses/dist/index.browser.js
48
+ var memoizedBase58Encoder;
49
+ function getMemoizedBase58Encoder() {
50
+ if (!memoizedBase58Encoder)
51
+ memoizedBase58Encoder = getBase58Encoder();
52
+ return memoizedBase58Encoder;
53
+ }
54
+ function assertIsAddress(putativeBase58EncodedAddress) {
55
+ try {
56
+ if (
57
+ // Lowest address (32 bytes of zeroes)
58
+ putativeBase58EncodedAddress.length < 32 || // Highest address (32 bytes of 255)
59
+ putativeBase58EncodedAddress.length > 44
60
+ ) {
61
+ throw new Error("Expected input string to decode to a byte array of length 32.");
62
+ }
63
+ const base58Encoder = getMemoizedBase58Encoder();
64
+ const bytes = base58Encoder.encode(putativeBase58EncodedAddress);
65
+ const numBytes = bytes.byteLength;
66
+ if (numBytes !== 32) {
67
+ throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${numBytes}`);
68
+ }
69
+ } catch (e2) {
70
+ throw new Error(`\`${putativeBase58EncodedAddress}\` is not a base-58 encoded address`, {
71
+ cause: e2
72
+ });
73
+ }
74
+ }
75
+ function convertAccount(message, accountKeys, accountIndex) {
76
+ const accountPublicKey = accountKeys.get(accountIndex);
77
+ if (!accountPublicKey) {
78
+ throw new Error(`Could not find account address at index ${accountIndex}`);
79
+ }
80
+ const isSigner = message.isAccountSigner(accountIndex);
81
+ const isWritable = message.isAccountWritable(accountIndex);
82
+ const role = isSigner ? isWritable ? AccountRole.WRITABLE_SIGNER : AccountRole.READONLY_SIGNER : isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
83
+ return {
84
+ address: accountPublicKey.toBase58(),
85
+ role
86
+ };
87
+ }
88
+ function convertInstruction(message, accountKeys, instruction) {
89
+ const programAddressPublicKey = accountKeys.get(instruction.programIdIndex);
90
+ if (!programAddressPublicKey) {
91
+ throw new Error(`Could not find program address at index ${instruction.programIdIndex}`);
92
+ }
93
+ const accounts = instruction.accountKeyIndexes.map(
94
+ (accountIndex) => convertAccount(message, accountKeys, accountIndex)
95
+ );
96
+ return {
97
+ programAddress: programAddressPublicKey.toBase58(),
98
+ ...accounts.length ? { accounts } : {},
99
+ ...instruction.data.length ? { data: instruction.data } : {}
100
+ };
101
+ }
102
+ function convertSignatures(transaction, staticAccountKeys) {
103
+ return transaction.signatures.reduce((acc, sig, index) => {
104
+ const allZeros = sig.every((byte) => byte === 0);
105
+ if (allZeros)
106
+ return acc;
107
+ const address = staticAccountKeys[index].toBase58();
108
+ return { ...acc, [address]: sig };
109
+ }, {});
110
+ }
111
+ function fromVersionedTransactionWithBlockhash(transaction, lastValidBlockHeight) {
112
+ if (transaction.message.addressTableLookups.length > 0) {
113
+ throw new Error("Cannot convert transaction with addressTableLookups");
114
+ }
115
+ const accountKeys = transaction.message.getAccountKeys();
116
+ const feePayer = accountKeys.staticAccountKeys[0];
117
+ if (!feePayer)
118
+ throw new Error("No fee payer set in VersionedTransaction");
119
+ const blockhashLifetime = {
120
+ blockhash: transaction.message.recentBlockhash,
121
+ lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n
122
+ // U64 MAX
123
+ };
124
+ const instructions = transaction.message.compiledInstructions.map(
125
+ (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
126
+ );
127
+ const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);
128
+ return pipe(
129
+ createTransaction({ version: transaction.version }),
130
+ (tx) => setTransactionFeePayer(feePayer.toBase58(), tx),
131
+ (tx) => setTransactionLifetimeUsingBlockhash(blockhashLifetime, tx),
132
+ (tx) => instructions.reduce((acc, instruction) => {
133
+ return appendTransactionInstruction(instruction, acc);
134
+ }, tx),
135
+ (tx) => transaction.signatures.length ? { ...tx, signatures } : tx
136
+ );
137
+ }
138
+ function fromVersionedTransactionWithDurableNonce(transaction) {
139
+ if (transaction.message.addressTableLookups.length > 0) {
140
+ throw new Error("Cannot convert transaction with addressTableLookups");
141
+ }
142
+ const accountKeys = transaction.message.getAccountKeys();
143
+ const feePayer = accountKeys.staticAccountKeys[0];
144
+ if (!feePayer)
145
+ throw new Error("No fee payer set in VersionedTransaction");
146
+ const instructions = transaction.message.compiledInstructions.map(
147
+ (instruction) => convertInstruction(transaction.message, accountKeys, instruction)
148
+ );
149
+ if (instructions.length === 0) {
150
+ throw new Error("transaction with no instructions cannot be durable nonce transaction");
151
+ }
152
+ if (!isAdvanceNonceAccountInstruction(instructions[0])) {
153
+ throw new Error("transaction first instruction is not advance nonce account instruction");
154
+ }
155
+ const nonceAccountAddress = instructions[0].accounts[0].address;
156
+ assertIsAddress(nonceAccountAddress);
157
+ const nonceAuthorityAddress = instructions[0].accounts[2].address;
158
+ assertIsAddress(nonceAuthorityAddress);
159
+ const durableNonceLifetime = {
160
+ nonce: transaction.message.recentBlockhash,
161
+ nonceAccountAddress,
162
+ nonceAuthorityAddress
163
+ };
164
+ const signatures = convertSignatures(transaction, accountKeys.staticAccountKeys);
165
+ return pipe(
166
+ createTransaction({ version: transaction.version }),
167
+ (tx) => setTransactionFeePayer(feePayer.toBase58(), tx),
168
+ (tx) => setTransactionLifetimeUsingDurableNonce(durableNonceLifetime, tx),
169
+ (tx) => instructions.slice(1).reduce((acc, instruction) => {
170
+ return appendTransactionInstruction(instruction, acc);
171
+ }, tx),
172
+ (tx) => transaction.signatures.length ? { ...tx, signatures } : tx
173
+ );
174
+ }
175
+
176
+ export { fromVersionedTransactionWithBlockhash, fromVersionedTransactionWithDurableNonce };
177
+ //# sourceMappingURL=out.js.map
178
+ //# sourceMappingURL=index.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../codecs-strings/dist/index.browser.js","../../addresses/src/address.ts","../src/transaction.ts"],"names":["e"],"mappings":"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","sourcesContent":["import { combineCodec, fixEncoder, mergeBytes, fixDecoder, assertByteArrayIsNotEmptyForCodec, assertByteArrayHasEnoughBytesForCodec } from '@solana/codecs-core';\nimport { getU32Encoder, getU32Decoder } from '@solana/codecs-numbers';\n\n// src/assertions.ts\nfunction assertValidBaseString(alphabet4, testValue, givenValue = testValue) {\n if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {\n throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);\n }\n}\nvar getBaseXEncoder = (alphabet4) => {\n const base = alphabet4.length;\n const baseBigInt = BigInt(base);\n return {\n description: `base${base}`,\n encode(value) {\n assertValidBaseString(alphabet4, value);\n if (value === \"\")\n return new Uint8Array();\n const chars = [...value];\n let trailIndex = chars.findIndex((c) => c !== alphabet4[0]);\n trailIndex = trailIndex === -1 ? chars.length : trailIndex;\n const leadingZeroes = Array(trailIndex).fill(0);\n if (trailIndex === chars.length)\n return Uint8Array.from(leadingZeroes);\n const tailChars = chars.slice(trailIndex);\n let base10Number = 0n;\n let baseXPower = 1n;\n for (let i = tailChars.length - 1; i >= 0; i -= 1) {\n base10Number += baseXPower * BigInt(alphabet4.indexOf(tailChars[i]));\n baseXPower *= baseBigInt;\n }\n const tailBytes = [];\n while (base10Number > 0n) {\n tailBytes.unshift(Number(base10Number % 256n));\n base10Number /= 256n;\n }\n return Uint8Array.from(leadingZeroes.concat(tailBytes));\n },\n fixedSize: null,\n maxSize: null\n };\n};\nvar getBaseXDecoder = (alphabet4) => {\n const base = alphabet4.length;\n const baseBigInt = BigInt(base);\n return {\n decode(rawBytes, offset = 0) {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0)\n return [\"\", 0];\n let trailIndex = bytes.findIndex((n) => n !== 0);\n trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n const leadingZeroes = alphabet4[0].repeat(trailIndex);\n if (trailIndex === bytes.length)\n return [leadingZeroes, rawBytes.length];\n let base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n const tailChars = [];\n while (base10Number > 0n) {\n tailChars.unshift(alphabet4[Number(base10Number % baseBigInt)]);\n base10Number /= baseBigInt;\n }\n return [leadingZeroes + tailChars.join(\"\"), rawBytes.length];\n },\n description: `base${base}`,\n fixedSize: null,\n maxSize: null\n };\n};\nvar getBaseXCodec = (alphabet4) => combineCodec(getBaseXEncoder(alphabet4), getBaseXDecoder(alphabet4));\n\n// src/base10.ts\nvar alphabet = \"0123456789\";\nvar getBase10Encoder = () => getBaseXEncoder(alphabet);\nvar getBase10Decoder = () => getBaseXDecoder(alphabet);\nvar getBase10Codec = () => getBaseXCodec(alphabet);\nvar getBase16Encoder = () => ({\n description: \"base16\",\n encode(value) {\n const lowercaseValue = value.toLowerCase();\n assertValidBaseString(\"0123456789abcdef\", lowercaseValue, value);\n const matches = lowercaseValue.match(/.{1,2}/g);\n return Uint8Array.from(matches ? matches.map((byte) => parseInt(byte, 16)) : []);\n },\n fixedSize: null,\n maxSize: null\n});\nvar getBase16Decoder = () => ({\n decode(bytes, offset = 0) {\n const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, \"0\"), \"\");\n return [value, bytes.length];\n },\n description: \"base16\",\n fixedSize: null,\n maxSize: null\n});\nvar getBase16Codec = () => combineCodec(getBase16Encoder(), getBase16Decoder());\n\n// src/base58.ts\nvar alphabet2 = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nvar getBase58Encoder = () => getBaseXEncoder(alphabet2);\nvar getBase58Decoder = () => getBaseXDecoder(alphabet2);\nvar getBase58Codec = () => getBaseXCodec(alphabet2);\nvar getBaseXResliceEncoder = (alphabet4, bits) => ({\n description: `base${alphabet4.length}`,\n encode(value) {\n assertValidBaseString(alphabet4, value);\n if (value === \"\")\n return new Uint8Array();\n const charIndices = [...value].map((c) => alphabet4.indexOf(c));\n return new Uint8Array(reslice(charIndices, bits, 8, false));\n },\n fixedSize: null,\n maxSize: null\n});\nvar getBaseXResliceDecoder = (alphabet4, bits) => ({\n decode(rawBytes, offset = 0) {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0)\n return [\"\", rawBytes.length];\n const charIndices = reslice([...bytes], 8, bits, true);\n return [charIndices.map((i) => alphabet4[i]).join(\"\"), rawBytes.length];\n },\n description: `base${alphabet4.length}`,\n fixedSize: null,\n maxSize: null\n});\nvar getBaseXResliceCodec = (alphabet4, bits) => combineCodec(getBaseXResliceEncoder(alphabet4, bits), getBaseXResliceDecoder(alphabet4, bits));\nfunction reslice(input, inputBits, outputBits, useRemainder) {\n const output = [];\n let accumulator = 0;\n let bitsInAccumulator = 0;\n const mask = (1 << outputBits) - 1;\n for (const value of input) {\n accumulator = accumulator << inputBits | value;\n bitsInAccumulator += inputBits;\n while (bitsInAccumulator >= outputBits) {\n bitsInAccumulator -= outputBits;\n output.push(accumulator >> bitsInAccumulator & mask);\n }\n }\n if (useRemainder && bitsInAccumulator > 0) {\n output.push(accumulator << outputBits - bitsInAccumulator & mask);\n }\n return output;\n}\nvar getBase64Encoder = () => {\n {\n return {\n description: `base64`,\n encode(value) {\n try {\n const bytes = atob(value).split(\"\").map((c) => c.charCodeAt(0));\n return new Uint8Array(bytes);\n } catch (e2) {\n throw new Error(`Expected a string of base 64, got [${value}].`);\n }\n },\n fixedSize: null,\n maxSize: null\n };\n }\n};\nvar getBase64Decoder = () => {\n {\n return {\n decode(bytes, offset = 0) {\n const slice = bytes.slice(offset);\n const value = btoa(String.fromCharCode(...slice));\n return [value, bytes.length];\n },\n description: `base64`,\n fixedSize: null,\n maxSize: null\n };\n }\n};\nvar getBase64Codec = () => combineCodec(getBase64Encoder(), getBase64Decoder());\n\n// src/null-characters.ts\nvar removeNullCharacters = (value) => (\n // eslint-disable-next-line no-control-regex\n value.replace(/\\u0000/g, \"\")\n);\nvar padNullCharacters = (value, chars) => value.padEnd(chars, \"\\0\");\n\n// ../text-encoding-impl/dist/index.browser.js\nvar e = globalThis.TextDecoder;\nvar o = globalThis.TextEncoder;\n\n// src/utf8.ts\nvar getUtf8Encoder = () => {\n let textEncoder;\n return {\n description: \"utf8\",\n encode: (value) => new Uint8Array((textEncoder || (textEncoder = new o())).encode(value)),\n fixedSize: null,\n maxSize: null\n };\n};\nvar getUtf8Decoder = () => {\n let textDecoder;\n return {\n decode(bytes, offset = 0) {\n const value = (textDecoder || (textDecoder = new e())).decode(bytes.slice(offset));\n return [removeNullCharacters(value), bytes.length];\n },\n description: \"utf8\",\n fixedSize: null,\n maxSize: null\n };\n};\nvar getUtf8Codec = () => combineCodec(getUtf8Encoder(), getUtf8Decoder());\n\n// src/string.ts\nvar getStringEncoder = (options = {}) => {\n const size = options.size ?? getU32Encoder();\n const encoding = options.encoding ?? getUtf8Encoder();\n const description = options.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`;\n if (size === \"variable\") {\n return { ...encoding, description };\n }\n if (typeof size === \"number\") {\n return fixEncoder(encoding, size, description);\n }\n return {\n description,\n encode: (value) => {\n const contentBytes = encoding.encode(value);\n const lengthBytes = size.encode(contentBytes.length);\n return mergeBytes([lengthBytes, contentBytes]);\n },\n fixedSize: null,\n maxSize: null\n };\n};\nvar getStringDecoder = (options = {}) => {\n const size = options.size ?? getU32Decoder();\n const encoding = options.encoding ?? getUtf8Decoder();\n const description = options.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`;\n if (size === \"variable\") {\n return { ...encoding, description };\n }\n if (typeof size === \"number\") {\n return fixDecoder(encoding, size, description);\n }\n return {\n decode: (bytes, offset = 0) => {\n assertByteArrayIsNotEmptyForCodec(\"string\", bytes, offset);\n const [lengthBigInt, lengthOffset] = size.decode(bytes, offset);\n const length = Number(lengthBigInt);\n offset = lengthOffset;\n const contentBytes = bytes.slice(offset, offset + length);\n assertByteArrayHasEnoughBytesForCodec(\"string\", length, contentBytes);\n const [value, contentOffset] = encoding.decode(contentBytes);\n offset += contentOffset;\n return [value, offset];\n },\n description,\n fixedSize: null,\n maxSize: null\n };\n};\nvar getStringCodec = (options = {}) => combineCodec(getStringEncoder(options), getStringDecoder(options));\nfunction getSizeDescription(size) {\n return typeof size === \"object\" ? size.description : `${size}`;\n}\n\nexport { assertValidBaseString, getBase10Codec, getBase10Decoder, getBase10Encoder, getBase16Codec, getBase16Decoder, getBase16Encoder, getBase58Codec, getBase58Decoder, getBase58Encoder, getBase64Codec, getBase64Decoder, getBase64Encoder, getBaseXCodec, getBaseXDecoder, getBaseXEncoder, getBaseXResliceCodec, getBaseXResliceDecoder, getBaseXResliceEncoder, getStringCodec, getStringDecoder, getStringEncoder, getUtf8Codec, getUtf8Decoder, getUtf8Encoder, padNullCharacters, removeNullCharacters };\n","import { Codec, combineCodec, Decoder, Encoder, mapEncoder } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder, getStringDecoder, getStringEncoder } from '@solana/codecs-strings';\n\nexport type Base58EncodedAddress<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(\n putativeBase58EncodedAddress: string\n): putativeBase58EncodedAddress is Base58EncodedAddress<typeof putativeBase58EncodedAddress> {\n // Fast-path; see if the input string is of an acceptable length.\n if (\n // Lowest address (32 bytes of zeroes)\n putativeBase58EncodedAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeBase58EncodedAddress.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(putativeBase58EncodedAddress);\n const numBytes = bytes.byteLength;\n if (numBytes !== 32) {\n return false;\n }\n return true;\n}\n\nexport function assertIsAddress(\n putativeBase58EncodedAddress: string\n): asserts putativeBase58EncodedAddress is Base58EncodedAddress<typeof putativeBase58EncodedAddress> {\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 putativeBase58EncodedAddress.length < 32 ||\n // Highest address (32 bytes of 255)\n putativeBase58EncodedAddress.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(putativeBase58EncodedAddress);\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(`\\`${putativeBase58EncodedAddress}\\` is not a base-58 encoded address`, {\n cause: e,\n });\n }\n}\n\nexport function address<TAddress extends string = string>(\n putativeBase58EncodedAddress: TAddress\n): Base58EncodedAddress<TAddress> {\n assertIsAddress(putativeBase58EncodedAddress);\n return putativeBase58EncodedAddress as Base58EncodedAddress<TAddress>;\n}\n\nexport function getAddressEncoder(config?: Readonly<{ description: string }>): Encoder<Base58EncodedAddress> {\n return mapEncoder(\n getStringEncoder({\n description: config?.description ?? 'Base58EncodedAddress',\n encoding: getMemoizedBase58Encoder(),\n size: 32,\n }),\n putativeAddress => address(putativeAddress)\n );\n}\n\nexport function getAddressDecoder(config?: Readonly<{ description: string }>): Decoder<Base58EncodedAddress> {\n return getStringDecoder({\n description: config?.description ?? 'Base58EncodedAddress',\n encoding: getMemoizedBase58Decoder(),\n size: 32,\n }) as Decoder<Base58EncodedAddress>;\n}\n\nexport function getAddressCodec(config?: Readonly<{ description: string }>): Codec<Base58EncodedAddress> {\n return combineCodec(getAddressEncoder(config), getAddressDecoder(config));\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 { assertIsAddress, type Base58EncodedAddress } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport type { IAccountMeta, IInstruction } from '@solana/instructions';\nimport { AccountRole } from '@solana/instructions';\nimport type { Ed25519Signature } from '@solana/keys';\nimport {\n appendTransactionInstruction,\n type Blockhash,\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 Base58EncodedAddress,\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 Base58EncodedAddress,\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 Base58EncodedAddress;\n return { ...acc, [address]: sig as Ed25519Signature };\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 // TOOD: add support for durable nonce transactions\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 Base58EncodedAddress, 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 Base58EncodedAddress, 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"]}