@solana/accounts 2.0.0-experimental.1db8859

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.
@@ -0,0 +1,179 @@
1
+ this.globalThis = this.globalThis || {};
2
+ this.globalThis.solanaWeb3 = (function (exports) {
3
+ 'use strict';
4
+
5
+ // src/account.ts
6
+ var BASE_ACCOUNT_SIZE = 128;
7
+
8
+ // src/decode-account.ts
9
+ function decodeAccount(encodedAccount, decoder) {
10
+ try {
11
+ if ("exists" in encodedAccount && !encodedAccount.exists) {
12
+ return encodedAccount;
13
+ }
14
+ return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });
15
+ } catch (error) {
16
+ const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);
17
+ newError.cause = error;
18
+ throw newError;
19
+ }
20
+ }
21
+
22
+ // ../codecs-core/dist/index.browser.js
23
+ function getEncodedSize(value, encoder) {
24
+ return "fixedSize" in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);
25
+ }
26
+ function createEncoder(encoder) {
27
+ return Object.freeze({
28
+ ...encoder,
29
+ encode: (value) => {
30
+ const bytes = new Uint8Array(getEncodedSize(value, encoder));
31
+ encoder.write(value, bytes, 0);
32
+ return bytes;
33
+ }
34
+ });
35
+ }
36
+
37
+ // ../codecs-strings/dist/index.browser.js
38
+ function assertValidBaseString(alphabet4, testValue, givenValue = testValue) {
39
+ if (!testValue.match(new RegExp(`^[${alphabet4}]*$`))) {
40
+ throw new Error(`Expected a string of base ${alphabet4.length}, got [${givenValue}].`);
41
+ }
42
+ }
43
+ var getBaseXEncoder = (alphabet4) => {
44
+ return createEncoder({
45
+ getSizeFromValue: (value) => {
46
+ const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet4[0]);
47
+ if (tailChars === "")
48
+ return value.length;
49
+ const base10Number = getBigIntFromBaseX(tailChars, alphabet4);
50
+ return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);
51
+ },
52
+ write(value, bytes, offset) {
53
+ assertValidBaseString(alphabet4, value);
54
+ if (value === "")
55
+ return offset;
56
+ const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet4[0]);
57
+ if (tailChars === "") {
58
+ bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);
59
+ return offset + leadingZeroes.length;
60
+ }
61
+ let base10Number = getBigIntFromBaseX(tailChars, alphabet4);
62
+ const tailBytes = [];
63
+ while (base10Number > 0n) {
64
+ tailBytes.unshift(Number(base10Number % 256n));
65
+ base10Number /= 256n;
66
+ }
67
+ const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];
68
+ bytes.set(bytesToAdd, offset);
69
+ return offset + bytesToAdd.length;
70
+ }
71
+ });
72
+ };
73
+ function partitionLeadingZeroes(value, zeroCharacter) {
74
+ const leadingZeroIndex = [...value].findIndex((c) => c !== zeroCharacter);
75
+ return leadingZeroIndex === -1 ? [value, ""] : [value.slice(0, leadingZeroIndex), value.slice(leadingZeroIndex)];
76
+ }
77
+ function getBigIntFromBaseX(value, alphabet4) {
78
+ const base = BigInt(alphabet4.length);
79
+ return [...value].reduce((sum, char) => sum * base + BigInt(alphabet4.indexOf(char)), 0n);
80
+ }
81
+ var alphabet2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
82
+ var getBase58Encoder = () => getBaseXEncoder(alphabet2);
83
+ var getBase64Encoder = () => {
84
+ {
85
+ return createEncoder({
86
+ getSizeFromValue: (value) => {
87
+ try {
88
+ return atob(value).length;
89
+ } catch (e2) {
90
+ throw new Error(`Expected a string of base 64, got [${value}].`);
91
+ }
92
+ },
93
+ write(value, bytes, offset) {
94
+ try {
95
+ const bytesToAdd = atob(value).split("").map((c) => c.charCodeAt(0));
96
+ bytes.set(bytesToAdd, offset);
97
+ return bytesToAdd.length + offset;
98
+ } catch (e2) {
99
+ throw new Error(`Expected a string of base 64, got [${value}].`);
100
+ }
101
+ }
102
+ });
103
+ }
104
+ };
105
+
106
+ // src/parse-account.ts
107
+ function parseBase64RpcAccount(address, rpcAccount) {
108
+ if (!rpcAccount)
109
+ return Object.freeze({ address, exists: false });
110
+ const data = getBase64Encoder().encode(rpcAccount.data[0]);
111
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
112
+ }
113
+ function parseBase58RpcAccount(address, rpcAccount) {
114
+ if (!rpcAccount)
115
+ return Object.freeze({ address, exists: false });
116
+ const data = getBase58Encoder().encode(typeof rpcAccount.data === "string" ? rpcAccount.data : rpcAccount.data[0]);
117
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
118
+ }
119
+ function parseJsonRpcAccount(address, rpcAccount) {
120
+ if (!rpcAccount)
121
+ return Object.freeze({ address, exists: false });
122
+ const data = rpcAccount.data.parsed.info;
123
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
124
+ }
125
+ function parseBaseAccount(rpcAccount) {
126
+ return Object.freeze({
127
+ executable: rpcAccount.executable,
128
+ lamports: rpcAccount.lamports,
129
+ programAddress: rpcAccount.owner
130
+ });
131
+ }
132
+
133
+ // src/fetch-account.ts
134
+ async function fetchEncodedAccount(rpc, address, config = {}) {
135
+ const { abortSignal, ...rpcConfig } = config;
136
+ const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
137
+ return parseBase64RpcAccount(address, response.value);
138
+ }
139
+ async function fetchJsonParsedAccount(rpc, address, config = {}) {
140
+ const { abortSignal, ...rpcConfig } = config;
141
+ const { value: account } = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
142
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(address, account) : parseBase64RpcAccount(address, account);
143
+ }
144
+ async function fetchEncodedAccounts(rpc, addresses, config = {}) {
145
+ const { abortSignal, ...rpcConfig } = config;
146
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
147
+ return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account));
148
+ }
149
+ async function fetchJsonParsedAccounts(rpc, addresses, config = {}) {
150
+ const { abortSignal, ...rpcConfig } = config;
151
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
152
+ return response.value.map((account, index) => {
153
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(addresses[index], account) : parseBase64RpcAccount(addresses[index], account);
154
+ });
155
+ }
156
+
157
+ // src/maybe-account.ts
158
+ function assertAccountExists(account) {
159
+ if (!account.exists) {
160
+ throw new Error(`Expected account [${account.address}] to exist.`);
161
+ }
162
+ }
163
+
164
+ exports.BASE_ACCOUNT_SIZE = BASE_ACCOUNT_SIZE;
165
+ exports.assertAccountExists = assertAccountExists;
166
+ exports.decodeAccount = decodeAccount;
167
+ exports.fetchEncodedAccount = fetchEncodedAccount;
168
+ exports.fetchEncodedAccounts = fetchEncodedAccounts;
169
+ exports.fetchJsonParsedAccount = fetchJsonParsedAccount;
170
+ exports.fetchJsonParsedAccounts = fetchJsonParsedAccounts;
171
+ exports.parseBase58RpcAccount = parseBase58RpcAccount;
172
+ exports.parseBase64RpcAccount = parseBase64RpcAccount;
173
+ exports.parseJsonRpcAccount = parseJsonRpcAccount;
174
+
175
+ return exports;
176
+
177
+ })({});
178
+ //# sourceMappingURL=out.js.map
179
+ //# sourceMappingURL=index.development.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/account.ts","../src/decode-account.ts","../../codecs-core/src/codec.ts","../../codecs-strings/src/assertions.ts","../../codecs-strings/src/baseX.ts","../../codecs-strings/src/base16.ts","../../codecs-strings/src/baseX-reslice.ts","../../codecs-strings/src/base64.ts","../src/parse-account.ts","../src/fetch-account.ts","../src/maybe-account.ts"],"names":["alphabet"],"mappings":"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","sourcesContent":["import type { Address } from '@solana/addresses';\nimport type { LamportsUnsafeBeyond2Pow53Minus1 } from '@solana/rpc-types';\n\n/** The amount of bytes required to store the base account information without its data. */\nexport const BASE_ACCOUNT_SIZE = 128;\n\n/** Describe the generic account details applicable to every account. */\nexport type BaseAccount = {\n readonly programAddress: Address;\n readonly executable: boolean;\n readonly lamports: LamportsUnsafeBeyond2Pow53Minus1;\n};\n\n/** Defines a Solana account with its generic details and parsed or encoded data. */\nexport type Account<TData extends object | Uint8Array, TAddress extends string = string> = BaseAccount & {\n readonly address: Address<TAddress>;\n readonly data: TData;\n};\n\n/** Defines a Solana account with its generic details and encoded data. */\nexport type EncodedAccount<TAddress extends string = string> = Account<Uint8Array, TAddress>;\n","import type { Decoder } from '@solana/codecs-core';\n\nimport type { Account, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\n/** Decodes the data of a given account using the provided decoder. */\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): MaybeAccount<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n try {\n if ('exists' in encodedAccount && !encodedAccount.exists) {\n return encodedAccount;\n }\n return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });\n } catch (error) {\n // TODO: Coded error.\n const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);\n newError.cause = error;\n throw newError;\n }\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(value: string, zeroCharacter: string): [string, string] {\n const leadingZeroIndex = [...value].findIndex(c => c !== zeroCharacter);\n return leadingZeroIndex === -1 ? [value, ''] : [value.slice(0, leadingZeroIndex), value.slice(leadingZeroIndex)];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n const base = BigInt(alphabet.length);\n return [...value].reduce((sum, char) => sum * base + BigInt(alphabet.indexOf(char)), 0n);\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 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 reslicing the bits of the byte array.\n * @see {@link getBaseXResliceCodec} for a more detailed description.\n */\nexport const getBaseXResliceEncoder = (alphabet: string, bits: number): VariableSizeEncoder<string> =>\n createEncoder({\n getSizeFromValue: (value: string) => Math.floor((value.length * bits) / 8),\n write(value: string, bytes, offset) {\n assertValidBaseString(alphabet, value);\n if (value === '') return offset;\n const charIndices = [...value].map(c => alphabet.indexOf(c));\n const reslicedBytes = reslice(charIndices, bits, 8, false);\n bytes.set(reslicedBytes, offset);\n return reslicedBytes.length + offset;\n },\n });\n\n/**\n * Decodes a string using a custom alphabet by reslicing the bits of the byte array.\n * @see {@link getBaseXResliceCodec} for a more detailed description.\n */\nexport const getBaseXResliceDecoder = (alphabet: string, bits: number): VariableSizeDecoder<string> =>\n createDecoder({\n read(rawBytes, offset = 0): [string, number] {\n const bytes = offset === 0 ? rawBytes : rawBytes.slice(offset);\n if (bytes.length === 0) return ['', rawBytes.length];\n const charIndices = reslice([...bytes], 8, bits, true);\n return [charIndices.map(i => alphabet[i]).join(''), rawBytes.length];\n },\n });\n\n/**\n * A string serializer that reslices bytes into custom chunks\n * of bits that are then mapped to a custom alphabet.\n *\n * This can be used to create serializers whose alphabet\n * is a power of 2 such as base16 or base64.\n */\nexport const getBaseXResliceCodec = (alphabet: string, bits: number): VariableSizeCodec<string> =>\n combineCodec(getBaseXResliceEncoder(alphabet, bits), getBaseXResliceDecoder(alphabet, bits));\n\n/** Helper function to reslice the bits inside bytes. */\nfunction reslice(input: number[], inputBits: number, outputBits: number, useRemainder: boolean): number[] {\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}\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 type { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Encoder } from '@solana/codecs-strings';\nimport type {\n AccountInfoBase,\n AccountInfoWithBase58Bytes,\n AccountInfoWithBase58EncodedData,\n AccountInfoWithBase64EncodedData,\n} from '@solana/rpc-core/dist/types/rpc-methods/common';\n\nimport type { Account, BaseAccount, EncodedAccount } from './account';\nimport { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\ntype Base64EncodedRpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\n\n/** Parse an account object received from a base64-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase64Encoder().encode(rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype Base58EncodedRpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\n\n/** Parse an account object received from a base58-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase58Encoder().encode(typeof rpcAccount.data === 'string' ? rpcAccount.data : rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedData<unknown> };\ntype JsonParsedData<TData> = { readonly parsed: { readonly info: TData } };\n\n/** Parse an account object received from a json-parsed RPC call into an Account or MaybeAccount type. */\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount,\n): Account<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): MaybeAccount<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = rpcAccount.data.parsed.info as TData;\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\nfunction parseBaseAccount(rpcAccount: AccountInfoBase): BaseAccount {\n return Object.freeze({\n executable: rpcAccount.executable,\n lamports: rpcAccount.lamports,\n programAddress: rpcAccount.owner,\n });\n}\n","import type { Address } from '@solana/addresses';\nimport type { Slot } from '@solana/rpc-core/dist/types/rpc-methods/common';\nimport type { GetAccountInfoApi } from '@solana/rpc-core/dist/types/rpc-methods/getAccountInfo';\nimport type { GetMultipleAccountsApi } from '@solana/rpc-core/dist/types/rpc-methods/getMultipleAccounts';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport { parseBase64RpcAccount, parseJsonRpcAccount } from './parse-account';\n\n/** Optional configuration for fetching a singular account. */\nexport type FetchAccountConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch a base64-encoded account that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccount<TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: 'base64' }).send({ abortSignal });\n return parseBase64RpcAccount(address, response.value);\n}\n\n/** Fetch a json-parsed account that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccount<TData extends object, TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeAccount<TData, TAddress> | MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const { value: account } = await rpc\n .getAccountInfo(address, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount<TData, TAddress>(address, account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount<TAddress>(address, account as Parameters<typeof parseBase64RpcAccount>[1]);\n}\n\n/** Optional configuration for fetching multiple accounts. */\nexport type FetchAccountsConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch multiple base64-encoded accounts that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccounts<\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'base64' })\n .send({ abortSignal });\n return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account)) as {\n [P in keyof TAddresses]: MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n\n/** Fetch multiple json-parsed accounts that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccounts<\n TData extends object[],\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return response.value.map((account, index) => {\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount(addresses[index], account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount(addresses[index], account as Parameters<typeof parseBase64RpcAccount>[1]);\n }) as {\n [P in keyof TData]:\n | MaybeAccount<TData[P], TAddresses[P & keyof TAddresses]>\n | MaybeEncodedAccount<TAddresses[P & keyof TAddresses]>;\n } & {\n [P in keyof TAddresses]:\n | MaybeAccount<TData[P & keyof TData], TAddresses[P]>\n | MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n","import { Address } from '@solana/addresses';\n\nimport { Account } from './account';\n\n/** Defines a Solana account that may or may not exist after having tried to fetch it. */\nexport type MaybeAccount<TData extends object | Uint8Array, TAddress extends string = string> =\n | ({ readonly exists: true } & Account<TData, TAddress>)\n | { readonly exists: false; readonly address: Address<TAddress> };\n\n/** Defines a Solana account with encoded data that may or may not exist after having tried to fetch it. */\nexport type MaybeEncodedAccount<TAddress extends string = string> = MaybeAccount<Uint8Array, TAddress>;\n\n/** Asserts that an account that may or may not exists, actually exists. */\nexport function assertAccountExists<TData extends object | Uint8Array, TAddress extends string = string>(\n account: MaybeAccount<TData, TAddress>\n): asserts account is Account<TData, TAddress> & { exists: true } {\n if (!account.exists) {\n // TODO: Coded error.\n throw new Error(`Expected account [${account.address}] to exist.`);\n }\n}\n"]}
@@ -0,0 +1,78 @@
1
+ import { getBase64Encoder, getBase58Encoder } from '@solana/codecs-strings';
2
+
3
+ // src/account.ts
4
+ var BASE_ACCOUNT_SIZE = 128;
5
+
6
+ // src/decode-account.ts
7
+ function decodeAccount(encodedAccount, decoder) {
8
+ try {
9
+ if ("exists" in encodedAccount && !encodedAccount.exists) {
10
+ return encodedAccount;
11
+ }
12
+ return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });
13
+ } catch (error) {
14
+ const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);
15
+ newError.cause = error;
16
+ throw newError;
17
+ }
18
+ }
19
+ function parseBase64RpcAccount(address, rpcAccount) {
20
+ if (!rpcAccount)
21
+ return Object.freeze({ address, exists: false });
22
+ const data = getBase64Encoder().encode(rpcAccount.data[0]);
23
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
24
+ }
25
+ function parseBase58RpcAccount(address, rpcAccount) {
26
+ if (!rpcAccount)
27
+ return Object.freeze({ address, exists: false });
28
+ const data = getBase58Encoder().encode(typeof rpcAccount.data === "string" ? rpcAccount.data : rpcAccount.data[0]);
29
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
30
+ }
31
+ function parseJsonRpcAccount(address, rpcAccount) {
32
+ if (!rpcAccount)
33
+ return Object.freeze({ address, exists: false });
34
+ const data = rpcAccount.data.parsed.info;
35
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
36
+ }
37
+ function parseBaseAccount(rpcAccount) {
38
+ return Object.freeze({
39
+ executable: rpcAccount.executable,
40
+ lamports: rpcAccount.lamports,
41
+ programAddress: rpcAccount.owner
42
+ });
43
+ }
44
+
45
+ // src/fetch-account.ts
46
+ async function fetchEncodedAccount(rpc, address, config = {}) {
47
+ const { abortSignal, ...rpcConfig } = config;
48
+ const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
49
+ return parseBase64RpcAccount(address, response.value);
50
+ }
51
+ async function fetchJsonParsedAccount(rpc, address, config = {}) {
52
+ const { abortSignal, ...rpcConfig } = config;
53
+ const { value: account } = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
54
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(address, account) : parseBase64RpcAccount(address, account);
55
+ }
56
+ async function fetchEncodedAccounts(rpc, addresses, config = {}) {
57
+ const { abortSignal, ...rpcConfig } = config;
58
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
59
+ return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account));
60
+ }
61
+ async function fetchJsonParsedAccounts(rpc, addresses, config = {}) {
62
+ const { abortSignal, ...rpcConfig } = config;
63
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
64
+ return response.value.map((account, index) => {
65
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(addresses[index], account) : parseBase64RpcAccount(addresses[index], account);
66
+ });
67
+ }
68
+
69
+ // src/maybe-account.ts
70
+ function assertAccountExists(account) {
71
+ if (!account.exists) {
72
+ throw new Error(`Expected account [${account.address}] to exist.`);
73
+ }
74
+ }
75
+
76
+ export { BASE_ACCOUNT_SIZE, assertAccountExists, decodeAccount, fetchEncodedAccount, fetchEncodedAccounts, fetchJsonParsedAccount, fetchJsonParsedAccounts, parseBase58RpcAccount, parseBase64RpcAccount, parseJsonRpcAccount };
77
+ //# sourceMappingURL=out.js.map
78
+ //# sourceMappingURL=index.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/account.ts","../src/decode-account.ts","../src/parse-account.ts","../src/fetch-account.ts","../src/maybe-account.ts"],"names":[],"mappings":";AAIO,IAAM,oBAAoB;;;ACU1B,SAAS,cACZ,gBACA,SACwD;AACxD,MAAI;AACA,QAAI,YAAY,kBAAkB,CAAC,eAAe,QAAQ;AACtD,aAAO;AAAA,IACX;AACA,WAAO,OAAO,OAAO,EAAE,GAAG,gBAAgB,MAAM,QAAQ,OAAO,eAAe,IAAI,EAAE,CAAC;AAAA,EACzF,SAAS,OAAO;AAEZ,UAAM,WAAW,IAAI,MAAM,6BAA6B,eAAe,OAAO,IAAI;AAClF,aAAS,QAAQ;AACjB,UAAM;AAAA,EACV;AACJ;;;AC5BA,SAAS,kBAAkB,wBAAwB;AAsB5C,SAAS,sBACZ,SACA,YACwD;AACxD,MAAI,CAAC;AAAY,WAAO,OAAO,OAAO,EAAE,SAAS,QAAQ,MAAM,CAAC;AAChE,QAAM,OAAO,iBAAiB,EAAE,OAAO,WAAW,KAAK,CAAC,CAAC;AACzD,SAAO,OAAO,OAAO,EAAE,GAAG,iBAAiB,UAAU,GAAG,SAAS,MAAM,QAAQ,KAAK,CAAC;AACzF;AAaO,SAAS,sBACZ,SACA,YACwD;AACxD,MAAI,CAAC;AAAY,WAAO,OAAO,OAAO,EAAE,SAAS,QAAQ,MAAM,CAAC;AAChE,QAAM,OAAO,iBAAiB,EAAE,OAAO,OAAO,WAAW,SAAS,WAAW,WAAW,OAAO,WAAW,KAAK,CAAC,CAAC;AACjH,SAAO,OAAO,OAAO,EAAE,GAAG,iBAAiB,UAAU,GAAG,SAAS,MAAM,QAAQ,KAAK,CAAC;AACzF;AAcO,SAAS,oBACZ,SACA,YACwD;AACxD,MAAI,CAAC;AAAY,WAAO,OAAO,OAAO,EAAE,SAAS,QAAQ,MAAM,CAAC;AAChE,QAAM,OAAO,WAAW,KAAK,OAAO;AACpC,SAAO,OAAO,OAAO,EAAE,GAAG,iBAAiB,UAAU,GAAG,SAAS,MAAM,QAAQ,KAAK,CAAC;AACzF;AAEA,SAAS,iBAAiB,YAA0C;AAChE,SAAO,OAAO,OAAO;AAAA,IACjB,YAAY,WAAW;AAAA,IACvB,UAAU,WAAW;AAAA,IACrB,gBAAgB,WAAW;AAAA,EAC/B,CAAC;AACL;;;AC7DA,eAAsB,oBAClB,KACA,SACA,SAA6B,CAAC,GACQ;AACtC,QAAM,EAAE,aAAa,GAAG,UAAU,IAAI;AACtC,QAAM,WAAW,MAAM,IAAI,eAAe,SAAS,EAAE,GAAG,WAAW,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC;AAC7G,SAAO,sBAAsB,SAAS,SAAS,KAAK;AACxD;AAGA,eAAsB,uBAClB,KACA,SACA,SAA6B,CAAC,GACwC;AACtE,QAAM,EAAE,aAAa,GAAG,UAAU,IAAI;AACtC,QAAM,EAAE,OAAO,QAAQ,IAAI,MAAM,IAC5B,eAAe,SAAS,EAAE,GAAG,WAAW,UAAU,aAAa,CAAC,EAChE,KAAK,EAAE,YAAY,CAAC;AACzB,SAAO,CAAC,CAAC,WAAW,OAAO,YAAY,YAAY,YAAY,QAAQ,OACjE,oBAAqC,SAAS,OAAoD,IAClG,sBAAgC,SAAS,OAAsD;AACzG;AAUA,eAAsB,qBAKpB,KAAkC,WAA8B,SAA8B,CAAC,GAAG;AAChG,QAAM,EAAE,aAAa,GAAG,UAAU,IAAI;AACtC,QAAM,WAAW,MAAM,IAClB,oBAAoB,WAAW,EAAE,GAAG,WAAW,UAAU,SAAS,CAAC,EACnE,KAAK,EAAE,YAAY,CAAC;AACzB,SAAO,SAAS,MAAM,IAAI,CAAC,SAAS,UAAU,sBAAsB,UAAU,KAAK,GAAG,OAAO,CAAC;AAGlG;AAGA,eAAsB,wBAMpB,KAAkC,WAA8B,SAA8B,CAAC,GAAG;AAChG,QAAM,EAAE,aAAa,GAAG,UAAU,IAAI;AACtC,QAAM,WAAW,MAAM,IAClB,oBAAoB,WAAW,EAAE,GAAG,WAAW,UAAU,aAAa,CAAC,EACvE,KAAK,EAAE,YAAY,CAAC;AACzB,SAAO,SAAS,MAAM,IAAI,CAAC,SAAS,UAAU;AAC1C,WAAO,CAAC,CAAC,WAAW,OAAO,YAAY,YAAY,YAAY,QAAQ,OACjE,oBAAoB,UAAU,KAAK,GAAG,OAAoD,IAC1F,sBAAsB,UAAU,KAAK,GAAG,OAAsD;AAAA,EACxG,CAAC;AASL;;;AC9EO,SAAS,oBACZ,SAC8D;AAC9D,MAAI,CAAC,QAAQ,QAAQ;AAEjB,UAAM,IAAI,MAAM,qBAAqB,QAAQ,OAAO,aAAa;AAAA,EACrE;AACJ","sourcesContent":["import type { Address } from '@solana/addresses';\nimport type { LamportsUnsafeBeyond2Pow53Minus1 } from '@solana/rpc-types';\n\n/** The amount of bytes required to store the base account information without its data. */\nexport const BASE_ACCOUNT_SIZE = 128;\n\n/** Describe the generic account details applicable to every account. */\nexport type BaseAccount = {\n readonly programAddress: Address;\n readonly executable: boolean;\n readonly lamports: LamportsUnsafeBeyond2Pow53Minus1;\n};\n\n/** Defines a Solana account with its generic details and parsed or encoded data. */\nexport type Account<TData extends object | Uint8Array, TAddress extends string = string> = BaseAccount & {\n readonly address: Address<TAddress>;\n readonly data: TData;\n};\n\n/** Defines a Solana account with its generic details and encoded data. */\nexport type EncodedAccount<TAddress extends string = string> = Account<Uint8Array, TAddress>;\n","import type { Decoder } from '@solana/codecs-core';\n\nimport type { Account, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\n/** Decodes the data of a given account using the provided decoder. */\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): MaybeAccount<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n try {\n if ('exists' in encodedAccount && !encodedAccount.exists) {\n return encodedAccount;\n }\n return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });\n } catch (error) {\n // TODO: Coded error.\n const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);\n newError.cause = error;\n throw newError;\n }\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Encoder } from '@solana/codecs-strings';\nimport type {\n AccountInfoBase,\n AccountInfoWithBase58Bytes,\n AccountInfoWithBase58EncodedData,\n AccountInfoWithBase64EncodedData,\n} from '@solana/rpc-core/dist/types/rpc-methods/common';\n\nimport type { Account, BaseAccount, EncodedAccount } from './account';\nimport { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\ntype Base64EncodedRpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\n\n/** Parse an account object received from a base64-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase64Encoder().encode(rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype Base58EncodedRpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\n\n/** Parse an account object received from a base58-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase58Encoder().encode(typeof rpcAccount.data === 'string' ? rpcAccount.data : rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedData<unknown> };\ntype JsonParsedData<TData> = { readonly parsed: { readonly info: TData } };\n\n/** Parse an account object received from a json-parsed RPC call into an Account or MaybeAccount type. */\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount,\n): Account<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): MaybeAccount<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = rpcAccount.data.parsed.info as TData;\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\nfunction parseBaseAccount(rpcAccount: AccountInfoBase): BaseAccount {\n return Object.freeze({\n executable: rpcAccount.executable,\n lamports: rpcAccount.lamports,\n programAddress: rpcAccount.owner,\n });\n}\n","import type { Address } from '@solana/addresses';\nimport type { Slot } from '@solana/rpc-core/dist/types/rpc-methods/common';\nimport type { GetAccountInfoApi } from '@solana/rpc-core/dist/types/rpc-methods/getAccountInfo';\nimport type { GetMultipleAccountsApi } from '@solana/rpc-core/dist/types/rpc-methods/getMultipleAccounts';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport { parseBase64RpcAccount, parseJsonRpcAccount } from './parse-account';\n\n/** Optional configuration for fetching a singular account. */\nexport type FetchAccountConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch a base64-encoded account that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccount<TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: 'base64' }).send({ abortSignal });\n return parseBase64RpcAccount(address, response.value);\n}\n\n/** Fetch a json-parsed account that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccount<TData extends object, TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeAccount<TData, TAddress> | MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const { value: account } = await rpc\n .getAccountInfo(address, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount<TData, TAddress>(address, account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount<TAddress>(address, account as Parameters<typeof parseBase64RpcAccount>[1]);\n}\n\n/** Optional configuration for fetching multiple accounts. */\nexport type FetchAccountsConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch multiple base64-encoded accounts that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccounts<\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'base64' })\n .send({ abortSignal });\n return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account)) as {\n [P in keyof TAddresses]: MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n\n/** Fetch multiple json-parsed accounts that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccounts<\n TData extends object[],\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return response.value.map((account, index) => {\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount(addresses[index], account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount(addresses[index], account as Parameters<typeof parseBase64RpcAccount>[1]);\n }) as {\n [P in keyof TData]:\n | MaybeAccount<TData[P], TAddresses[P & keyof TAddresses]>\n | MaybeEncodedAccount<TAddresses[P & keyof TAddresses]>;\n } & {\n [P in keyof TAddresses]:\n | MaybeAccount<TData[P & keyof TData], TAddresses[P]>\n | MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n","import { Address } from '@solana/addresses';\n\nimport { Account } from './account';\n\n/** Defines a Solana account that may or may not exist after having tried to fetch it. */\nexport type MaybeAccount<TData extends object | Uint8Array, TAddress extends string = string> =\n | ({ readonly exists: true } & Account<TData, TAddress>)\n | { readonly exists: false; readonly address: Address<TAddress> };\n\n/** Defines a Solana account with encoded data that may or may not exist after having tried to fetch it. */\nexport type MaybeEncodedAccount<TAddress extends string = string> = MaybeAccount<Uint8Array, TAddress>;\n\n/** Asserts that an account that may or may not exists, actually exists. */\nexport function assertAccountExists<TData extends object | Uint8Array, TAddress extends string = string>(\n account: MaybeAccount<TData, TAddress>\n): asserts account is Account<TData, TAddress> & { exists: true } {\n if (!account.exists) {\n // TODO: Coded error.\n throw new Error(`Expected account [${account.address}] to exist.`);\n }\n}\n"]}
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ var codecsStrings = require('@solana/codecs-strings');
4
+
5
+ // src/account.ts
6
+ var BASE_ACCOUNT_SIZE = 128;
7
+
8
+ // src/decode-account.ts
9
+ function decodeAccount(encodedAccount, decoder) {
10
+ try {
11
+ if ("exists" in encodedAccount && !encodedAccount.exists) {
12
+ return encodedAccount;
13
+ }
14
+ return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });
15
+ } catch (error) {
16
+ const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);
17
+ newError.cause = error;
18
+ throw newError;
19
+ }
20
+ }
21
+ function parseBase64RpcAccount(address, rpcAccount) {
22
+ if (!rpcAccount)
23
+ return Object.freeze({ address, exists: false });
24
+ const data = codecsStrings.getBase64Encoder().encode(rpcAccount.data[0]);
25
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
26
+ }
27
+ function parseBase58RpcAccount(address, rpcAccount) {
28
+ if (!rpcAccount)
29
+ return Object.freeze({ address, exists: false });
30
+ const data = codecsStrings.getBase58Encoder().encode(typeof rpcAccount.data === "string" ? rpcAccount.data : rpcAccount.data[0]);
31
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
32
+ }
33
+ function parseJsonRpcAccount(address, rpcAccount) {
34
+ if (!rpcAccount)
35
+ return Object.freeze({ address, exists: false });
36
+ const data = rpcAccount.data.parsed.info;
37
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
38
+ }
39
+ function parseBaseAccount(rpcAccount) {
40
+ return Object.freeze({
41
+ executable: rpcAccount.executable,
42
+ lamports: rpcAccount.lamports,
43
+ programAddress: rpcAccount.owner
44
+ });
45
+ }
46
+
47
+ // src/fetch-account.ts
48
+ async function fetchEncodedAccount(rpc, address, config = {}) {
49
+ const { abortSignal, ...rpcConfig } = config;
50
+ const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
51
+ return parseBase64RpcAccount(address, response.value);
52
+ }
53
+ async function fetchJsonParsedAccount(rpc, address, config = {}) {
54
+ const { abortSignal, ...rpcConfig } = config;
55
+ const { value: account } = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
56
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(address, account) : parseBase64RpcAccount(address, account);
57
+ }
58
+ async function fetchEncodedAccounts(rpc, addresses, config = {}) {
59
+ const { abortSignal, ...rpcConfig } = config;
60
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
61
+ return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account));
62
+ }
63
+ async function fetchJsonParsedAccounts(rpc, addresses, config = {}) {
64
+ const { abortSignal, ...rpcConfig } = config;
65
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
66
+ return response.value.map((account, index) => {
67
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(addresses[index], account) : parseBase64RpcAccount(addresses[index], account);
68
+ });
69
+ }
70
+
71
+ // src/maybe-account.ts
72
+ function assertAccountExists(account) {
73
+ if (!account.exists) {
74
+ throw new Error(`Expected account [${account.address}] to exist.`);
75
+ }
76
+ }
77
+
78
+ exports.BASE_ACCOUNT_SIZE = BASE_ACCOUNT_SIZE;
79
+ exports.assertAccountExists = assertAccountExists;
80
+ exports.decodeAccount = decodeAccount;
81
+ exports.fetchEncodedAccount = fetchEncodedAccount;
82
+ exports.fetchEncodedAccounts = fetchEncodedAccounts;
83
+ exports.fetchJsonParsedAccount = fetchJsonParsedAccount;
84
+ exports.fetchJsonParsedAccounts = fetchJsonParsedAccounts;
85
+ exports.parseBase58RpcAccount = parseBase58RpcAccount;
86
+ exports.parseBase64RpcAccount = parseBase64RpcAccount;
87
+ exports.parseJsonRpcAccount = parseJsonRpcAccount;
88
+ //# sourceMappingURL=out.js.map
89
+ //# sourceMappingURL=index.node.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/account.ts","../src/decode-account.ts","../src/parse-account.ts","../src/fetch-account.ts","../src/maybe-account.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Address } from '@solana/addresses';\nimport type { LamportsUnsafeBeyond2Pow53Minus1 } from '@solana/rpc-types';\n\n/** The amount of bytes required to store the base account information without its data. */\nexport const BASE_ACCOUNT_SIZE = 128;\n\n/** Describe the generic account details applicable to every account. */\nexport type BaseAccount = {\n readonly programAddress: Address;\n readonly executable: boolean;\n readonly lamports: LamportsUnsafeBeyond2Pow53Minus1;\n};\n\n/** Defines a Solana account with its generic details and parsed or encoded data. */\nexport type Account<TData extends object | Uint8Array, TAddress extends string = string> = BaseAccount & {\n readonly address: Address<TAddress>;\n readonly data: TData;\n};\n\n/** Defines a Solana account with its generic details and encoded data. */\nexport type EncodedAccount<TAddress extends string = string> = Account<Uint8Array, TAddress>;\n","import type { Decoder } from '@solana/codecs-core';\n\nimport type { Account, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\n/** Decodes the data of a given account using the provided decoder. */\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): MaybeAccount<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n try {\n if ('exists' in encodedAccount && !encodedAccount.exists) {\n return encodedAccount;\n }\n return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });\n } catch (error) {\n // TODO: Coded error.\n const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);\n newError.cause = error;\n throw newError;\n }\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Encoder } from '@solana/codecs-strings';\nimport type {\n AccountInfoBase,\n AccountInfoWithBase58Bytes,\n AccountInfoWithBase58EncodedData,\n AccountInfoWithBase64EncodedData,\n} from '@solana/rpc-core/dist/types/rpc-methods/common';\n\nimport type { Account, BaseAccount, EncodedAccount } from './account';\nimport { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\ntype Base64EncodedRpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\n\n/** Parse an account object received from a base64-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase64Encoder().encode(rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype Base58EncodedRpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\n\n/** Parse an account object received from a base58-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase58Encoder().encode(typeof rpcAccount.data === 'string' ? rpcAccount.data : rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedData<unknown> };\ntype JsonParsedData<TData> = { readonly parsed: { readonly info: TData } };\n\n/** Parse an account object received from a json-parsed RPC call into an Account or MaybeAccount type. */\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount,\n): Account<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): MaybeAccount<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = rpcAccount.data.parsed.info as TData;\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\nfunction parseBaseAccount(rpcAccount: AccountInfoBase): BaseAccount {\n return Object.freeze({\n executable: rpcAccount.executable,\n lamports: rpcAccount.lamports,\n programAddress: rpcAccount.owner,\n });\n}\n","import type { Address } from '@solana/addresses';\nimport type { Slot } from '@solana/rpc-core/dist/types/rpc-methods/common';\nimport type { GetAccountInfoApi } from '@solana/rpc-core/dist/types/rpc-methods/getAccountInfo';\nimport type { GetMultipleAccountsApi } from '@solana/rpc-core/dist/types/rpc-methods/getMultipleAccounts';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport { parseBase64RpcAccount, parseJsonRpcAccount } from './parse-account';\n\n/** Optional configuration for fetching a singular account. */\nexport type FetchAccountConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch a base64-encoded account that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccount<TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: 'base64' }).send({ abortSignal });\n return parseBase64RpcAccount(address, response.value);\n}\n\n/** Fetch a json-parsed account that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccount<TData extends object, TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeAccount<TData, TAddress> | MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const { value: account } = await rpc\n .getAccountInfo(address, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount<TData, TAddress>(address, account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount<TAddress>(address, account as Parameters<typeof parseBase64RpcAccount>[1]);\n}\n\n/** Optional configuration for fetching multiple accounts. */\nexport type FetchAccountsConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch multiple base64-encoded accounts that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccounts<\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'base64' })\n .send({ abortSignal });\n return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account)) as {\n [P in keyof TAddresses]: MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n\n/** Fetch multiple json-parsed accounts that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccounts<\n TData extends object[],\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return response.value.map((account, index) => {\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount(addresses[index], account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount(addresses[index], account as Parameters<typeof parseBase64RpcAccount>[1]);\n }) as {\n [P in keyof TData]:\n | MaybeAccount<TData[P], TAddresses[P & keyof TAddresses]>\n | MaybeEncodedAccount<TAddresses[P & keyof TAddresses]>;\n } & {\n [P in keyof TAddresses]:\n | MaybeAccount<TData[P & keyof TData], TAddresses[P]>\n | MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n","import { Address } from '@solana/addresses';\n\nimport { Account } from './account';\n\n/** Defines a Solana account that may or may not exist after having tried to fetch it. */\nexport type MaybeAccount<TData extends object | Uint8Array, TAddress extends string = string> =\n | ({ readonly exists: true } & Account<TData, TAddress>)\n | { readonly exists: false; readonly address: Address<TAddress> };\n\n/** Defines a Solana account with encoded data that may or may not exist after having tried to fetch it. */\nexport type MaybeEncodedAccount<TAddress extends string = string> = MaybeAccount<Uint8Array, TAddress>;\n\n/** Asserts that an account that may or may not exists, actually exists. */\nexport function assertAccountExists<TData extends object | Uint8Array, TAddress extends string = string>(\n account: MaybeAccount<TData, TAddress>\n): asserts account is Account<TData, TAddress> & { exists: true } {\n if (!account.exists) {\n // TODO: Coded error.\n throw new Error(`Expected account [${account.address}] to exist.`);\n }\n}\n"]}
@@ -0,0 +1,78 @@
1
+ import { getBase64Encoder, getBase58Encoder } from '@solana/codecs-strings';
2
+
3
+ // src/account.ts
4
+ var BASE_ACCOUNT_SIZE = 128;
5
+
6
+ // src/decode-account.ts
7
+ function decodeAccount(encodedAccount, decoder) {
8
+ try {
9
+ if ("exists" in encodedAccount && !encodedAccount.exists) {
10
+ return encodedAccount;
11
+ }
12
+ return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });
13
+ } catch (error) {
14
+ const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);
15
+ newError.cause = error;
16
+ throw newError;
17
+ }
18
+ }
19
+ function parseBase64RpcAccount(address, rpcAccount) {
20
+ if (!rpcAccount)
21
+ return Object.freeze({ address, exists: false });
22
+ const data = getBase64Encoder().encode(rpcAccount.data[0]);
23
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
24
+ }
25
+ function parseBase58RpcAccount(address, rpcAccount) {
26
+ if (!rpcAccount)
27
+ return Object.freeze({ address, exists: false });
28
+ const data = getBase58Encoder().encode(typeof rpcAccount.data === "string" ? rpcAccount.data : rpcAccount.data[0]);
29
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
30
+ }
31
+ function parseJsonRpcAccount(address, rpcAccount) {
32
+ if (!rpcAccount)
33
+ return Object.freeze({ address, exists: false });
34
+ const data = rpcAccount.data.parsed.info;
35
+ return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });
36
+ }
37
+ function parseBaseAccount(rpcAccount) {
38
+ return Object.freeze({
39
+ executable: rpcAccount.executable,
40
+ lamports: rpcAccount.lamports,
41
+ programAddress: rpcAccount.owner
42
+ });
43
+ }
44
+
45
+ // src/fetch-account.ts
46
+ async function fetchEncodedAccount(rpc, address, config = {}) {
47
+ const { abortSignal, ...rpcConfig } = config;
48
+ const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
49
+ return parseBase64RpcAccount(address, response.value);
50
+ }
51
+ async function fetchJsonParsedAccount(rpc, address, config = {}) {
52
+ const { abortSignal, ...rpcConfig } = config;
53
+ const { value: account } = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
54
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(address, account) : parseBase64RpcAccount(address, account);
55
+ }
56
+ async function fetchEncodedAccounts(rpc, addresses, config = {}) {
57
+ const { abortSignal, ...rpcConfig } = config;
58
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "base64" }).send({ abortSignal });
59
+ return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account));
60
+ }
61
+ async function fetchJsonParsedAccounts(rpc, addresses, config = {}) {
62
+ const { abortSignal, ...rpcConfig } = config;
63
+ const response = await rpc.getMultipleAccounts(addresses, { ...rpcConfig, encoding: "jsonParsed" }).send({ abortSignal });
64
+ return response.value.map((account, index) => {
65
+ return !!account && typeof account === "object" && "parsed" in account.data ? parseJsonRpcAccount(addresses[index], account) : parseBase64RpcAccount(addresses[index], account);
66
+ });
67
+ }
68
+
69
+ // src/maybe-account.ts
70
+ function assertAccountExists(account) {
71
+ if (!account.exists) {
72
+ throw new Error(`Expected account [${account.address}] to exist.`);
73
+ }
74
+ }
75
+
76
+ export { BASE_ACCOUNT_SIZE, assertAccountExists, decodeAccount, fetchEncodedAccount, fetchEncodedAccounts, fetchJsonParsedAccount, fetchJsonParsedAccounts, parseBase58RpcAccount, parseBase64RpcAccount, parseJsonRpcAccount };
77
+ //# sourceMappingURL=out.js.map
78
+ //# sourceMappingURL=index.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/account.ts","../src/decode-account.ts","../src/parse-account.ts","../src/fetch-account.ts","../src/maybe-account.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Address } from '@solana/addresses';\nimport type { LamportsUnsafeBeyond2Pow53Minus1 } from '@solana/rpc-types';\n\n/** The amount of bytes required to store the base account information without its data. */\nexport const BASE_ACCOUNT_SIZE = 128;\n\n/** Describe the generic account details applicable to every account. */\nexport type BaseAccount = {\n readonly programAddress: Address;\n readonly executable: boolean;\n readonly lamports: LamportsUnsafeBeyond2Pow53Minus1;\n};\n\n/** Defines a Solana account with its generic details and parsed or encoded data. */\nexport type Account<TData extends object | Uint8Array, TAddress extends string = string> = BaseAccount & {\n readonly address: Address<TAddress>;\n readonly data: TData;\n};\n\n/** Defines a Solana account with its generic details and encoded data. */\nexport type EncodedAccount<TAddress extends string = string> = Account<Uint8Array, TAddress>;\n","import type { Decoder } from '@solana/codecs-core';\n\nimport type { Account, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\n/** Decodes the data of a given account using the provided decoder. */\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): MaybeAccount<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,\n decoder: Decoder<TData>\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n try {\n if ('exists' in encodedAccount && !encodedAccount.exists) {\n return encodedAccount;\n }\n return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });\n } catch (error) {\n // TODO: Coded error.\n const newError = new Error(`Failed to decode account [${encodedAccount.address}].`);\n newError.cause = error;\n throw newError;\n }\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Encoder } from '@solana/codecs-strings';\nimport type {\n AccountInfoBase,\n AccountInfoWithBase58Bytes,\n AccountInfoWithBase58EncodedData,\n AccountInfoWithBase64EncodedData,\n} from '@solana/rpc-core/dist/types/rpc-methods/common';\n\nimport type { Account, BaseAccount, EncodedAccount } from './account';\nimport { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\ntype Base64EncodedRpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\n\n/** Parse an account object received from a base64-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base64EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase64Encoder().encode(rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype Base58EncodedRpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\n\n/** Parse an account object received from a base58-encoded RPC call into an EncodedAccount or MaybeEncodedAccount type. */\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: Base58EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = getBase58Encoder().encode(typeof rpcAccount.data === 'string' ? rpcAccount.data : rpcAccount.data[0]);\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedData<unknown> };\ntype JsonParsedData<TData> = { readonly parsed: { readonly info: TData } };\n\n/** Parse an account object received from a json-parsed RPC call into an Account or MaybeAccount type. */\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount,\n): Account<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): MaybeAccount<TData, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n address: Address<TAddress>,\n rpcAccount: JsonParsedRpcAccount | null,\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n if (!rpcAccount) return Object.freeze({ address, exists: false });\n const data = rpcAccount.data.parsed.info as TData;\n return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\nfunction parseBaseAccount(rpcAccount: AccountInfoBase): BaseAccount {\n return Object.freeze({\n executable: rpcAccount.executable,\n lamports: rpcAccount.lamports,\n programAddress: rpcAccount.owner,\n });\n}\n","import type { Address } from '@solana/addresses';\nimport type { Slot } from '@solana/rpc-core/dist/types/rpc-methods/common';\nimport type { GetAccountInfoApi } from '@solana/rpc-core/dist/types/rpc-methods/getAccountInfo';\nimport type { GetMultipleAccountsApi } from '@solana/rpc-core/dist/types/rpc-methods/getMultipleAccounts';\nimport type { Rpc } from '@solana/rpc-transport/dist/types/json-rpc-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport { parseBase64RpcAccount, parseJsonRpcAccount } from './parse-account';\n\n/** Optional configuration for fetching a singular account. */\nexport type FetchAccountConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch a base64-encoded account that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccount<TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: 'base64' }).send({ abortSignal });\n return parseBase64RpcAccount(address, response.value);\n}\n\n/** Fetch a json-parsed account that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccount<TData extends object, TAddress extends string = string>(\n rpc: Rpc<GetAccountInfoApi>,\n address: Address<TAddress>,\n config: FetchAccountConfig = {},\n): Promise<MaybeAccount<TData, TAddress> | MaybeEncodedAccount<TAddress>> {\n const { abortSignal, ...rpcConfig } = config;\n const { value: account } = await rpc\n .getAccountInfo(address, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount<TData, TAddress>(address, account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount<TAddress>(address, account as Parameters<typeof parseBase64RpcAccount>[1]);\n}\n\n/** Optional configuration for fetching multiple accounts. */\nexport type FetchAccountsConfig = {\n commitment?: Commitment;\n minContextSlot?: Slot;\n abortSignal?: AbortSignal;\n};\n\n/** Fetch multiple base64-encoded accounts that may or may not exist using an RPC client. */\nexport async function fetchEncodedAccounts<\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'base64' })\n .send({ abortSignal });\n return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account)) as {\n [P in keyof TAddresses]: MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n\n/** Fetch multiple json-parsed accounts that may or may not exist using an RPC client. */\nexport async function fetchJsonParsedAccounts<\n TData extends object[],\n TAddresses extends string[] = string[],\n TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n [P in keyof TAddresses]: Address<TAddresses[P]>;\n },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n const { abortSignal, ...rpcConfig } = config;\n const response = await rpc\n .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'jsonParsed' })\n .send({ abortSignal });\n return response.value.map((account, index) => {\n return !!account && typeof account === 'object' && 'parsed' in account.data\n ? parseJsonRpcAccount(addresses[index], account as Parameters<typeof parseJsonRpcAccount>[1])\n : parseBase64RpcAccount(addresses[index], account as Parameters<typeof parseBase64RpcAccount>[1]);\n }) as {\n [P in keyof TData]:\n | MaybeAccount<TData[P], TAddresses[P & keyof TAddresses]>\n | MaybeEncodedAccount<TAddresses[P & keyof TAddresses]>;\n } & {\n [P in keyof TAddresses]:\n | MaybeAccount<TData[P & keyof TData], TAddresses[P]>\n | MaybeEncodedAccount<TAddresses[P]>;\n };\n}\n","import { Address } from '@solana/addresses';\n\nimport { Account } from './account';\n\n/** Defines a Solana account that may or may not exist after having tried to fetch it. */\nexport type MaybeAccount<TData extends object | Uint8Array, TAddress extends string = string> =\n | ({ readonly exists: true } & Account<TData, TAddress>)\n | { readonly exists: false; readonly address: Address<TAddress> };\n\n/** Defines a Solana account with encoded data that may or may not exist after having tried to fetch it. */\nexport type MaybeEncodedAccount<TAddress extends string = string> = MaybeAccount<Uint8Array, TAddress>;\n\n/** Asserts that an account that may or may not exists, actually exists. */\nexport function assertAccountExists<TData extends object | Uint8Array, TAddress extends string = string>(\n account: MaybeAccount<TData, TAddress>\n): asserts account is Account<TData, TAddress> & { exists: true } {\n if (!account.exists) {\n // TODO: Coded error.\n throw new Error(`Expected account [${account.address}] to exist.`);\n }\n}\n"]}