@rialo/spl-token 0.3.0-alpha.0

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/dist/index.mjs ADDED
@@ -0,0 +1,1356 @@
1
+ import { PublicKey, SYSTEM_PROGRAM_ID, TransactionBuilder, isOnCurve } from '@rialo/ts-cdk';
2
+
3
+ // src/client/spl-token-client.ts
4
+
5
+ // src/constants.ts
6
+ var TOKEN_2022_PROGRAM_ID = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
7
+ var ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
8
+ var TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
9
+ var MINT_SIZE = 82;
10
+ var TOKEN_ACCOUNT_SIZE = 165;
11
+ var MINT_SUPPLY_OFFSET = 36;
12
+ var MINT_DECIMALS_OFFSET = 44;
13
+ var MINT_IS_INITIALIZED_OFFSET = 45;
14
+ var MINT_FREEZE_AUTHORITY_OFFSET = 46;
15
+ var TOKEN_ACCOUNT_MINT_OFFSET = 0;
16
+ var TOKEN_ACCOUNT_OWNER_OFFSET = 32;
17
+ var TOKEN_ACCOUNT_AMOUNT_OFFSET = 64;
18
+ var TOKEN_ACCOUNT_DELEGATE_OFFSET = 72;
19
+ var TOKEN_ACCOUNT_STATE_OFFSET = 108;
20
+ var TOKEN_ACCOUNT_IS_NATIVE_OFFSET = 109;
21
+ var TOKEN_ACCOUNT_DELEGATED_AMOUNT_OFFSET = 121;
22
+ var TOKEN_ACCOUNT_CLOSE_AUTHORITY_OFFSET = 129;
23
+ var COPTION_SOME = 1;
24
+ var PUBKEY_SIZE = 32;
25
+ var TokenAccountState = /* @__PURE__ */ ((TokenAccountState2) => {
26
+ TokenAccountState2[TokenAccountState2["Uninitialized"] = 0] = "Uninitialized";
27
+ TokenAccountState2[TokenAccountState2["Initialized"] = 1] = "Initialized";
28
+ TokenAccountState2[TokenAccountState2["Frozen"] = 2] = "Frozen";
29
+ return TokenAccountState2;
30
+ })(TokenAccountState || {});
31
+ var ExtensionType = /* @__PURE__ */ ((ExtensionType2) => {
32
+ ExtensionType2[ExtensionType2["Uninitialized"] = 0] = "Uninitialized";
33
+ ExtensionType2[ExtensionType2["TransferFeeConfig"] = 1] = "TransferFeeConfig";
34
+ ExtensionType2[ExtensionType2["TransferFeeAmount"] = 2] = "TransferFeeAmount";
35
+ ExtensionType2[ExtensionType2["MintCloseAuthority"] = 3] = "MintCloseAuthority";
36
+ ExtensionType2[ExtensionType2["ConfidentialTransferMint"] = 4] = "ConfidentialTransferMint";
37
+ ExtensionType2[ExtensionType2["ConfidentialTransferAccount"] = 5] = "ConfidentialTransferAccount";
38
+ ExtensionType2[ExtensionType2["DefaultAccountState"] = 6] = "DefaultAccountState";
39
+ ExtensionType2[ExtensionType2["ImmutableOwner"] = 7] = "ImmutableOwner";
40
+ ExtensionType2[ExtensionType2["MemoTransfer"] = 8] = "MemoTransfer";
41
+ ExtensionType2[ExtensionType2["NonTransferable"] = 9] = "NonTransferable";
42
+ ExtensionType2[ExtensionType2["InterestBearingConfig"] = 10] = "InterestBearingConfig";
43
+ ExtensionType2[ExtensionType2["CpiGuard"] = 11] = "CpiGuard";
44
+ ExtensionType2[ExtensionType2["PermanentDelegate"] = 12] = "PermanentDelegate";
45
+ ExtensionType2[ExtensionType2["NonTransferableAccount"] = 13] = "NonTransferableAccount";
46
+ ExtensionType2[ExtensionType2["TransferHook"] = 14] = "TransferHook";
47
+ ExtensionType2[ExtensionType2["TransferHookAccount"] = 15] = "TransferHookAccount";
48
+ ExtensionType2[ExtensionType2["ConfidentialTransferFeeConfig"] = 16] = "ConfidentialTransferFeeConfig";
49
+ ExtensionType2[ExtensionType2["ConfidentialTransferFeeAmount"] = 17] = "ConfidentialTransferFeeAmount";
50
+ ExtensionType2[ExtensionType2["MetadataPointer"] = 18] = "MetadataPointer";
51
+ ExtensionType2[ExtensionType2["TokenMetadata"] = 19] = "TokenMetadata";
52
+ ExtensionType2[ExtensionType2["GroupPointer"] = 20] = "GroupPointer";
53
+ ExtensionType2[ExtensionType2["TokenGroup"] = 21] = "TokenGroup";
54
+ ExtensionType2[ExtensionType2["GroupMemberPointer"] = 22] = "GroupMemberPointer";
55
+ ExtensionType2[ExtensionType2["TokenGroupMember"] = 23] = "TokenGroupMember";
56
+ return ExtensionType2;
57
+ })(ExtensionType || {});
58
+ var AccountType = /* @__PURE__ */ ((AccountType2) => {
59
+ AccountType2[AccountType2["Uninitialized"] = 0] = "Uninitialized";
60
+ AccountType2[AccountType2["Mint"] = 1] = "Mint";
61
+ AccountType2[AccountType2["Account"] = 2] = "Account";
62
+ return AccountType2;
63
+ })(AccountType || {});
64
+ var TokenInstruction = /* @__PURE__ */ ((TokenInstruction2) => {
65
+ TokenInstruction2[TokenInstruction2["InitializeMint"] = 0] = "InitializeMint";
66
+ TokenInstruction2[TokenInstruction2["InitializeAccount"] = 1] = "InitializeAccount";
67
+ TokenInstruction2[TokenInstruction2["InitializeMultisig"] = 2] = "InitializeMultisig";
68
+ TokenInstruction2[TokenInstruction2["Transfer"] = 3] = "Transfer";
69
+ TokenInstruction2[TokenInstruction2["Approve"] = 4] = "Approve";
70
+ TokenInstruction2[TokenInstruction2["Revoke"] = 5] = "Revoke";
71
+ TokenInstruction2[TokenInstruction2["SetAuthority"] = 6] = "SetAuthority";
72
+ TokenInstruction2[TokenInstruction2["MintTo"] = 7] = "MintTo";
73
+ TokenInstruction2[TokenInstruction2["Burn"] = 8] = "Burn";
74
+ TokenInstruction2[TokenInstruction2["CloseAccount"] = 9] = "CloseAccount";
75
+ TokenInstruction2[TokenInstruction2["FreezeAccount"] = 10] = "FreezeAccount";
76
+ TokenInstruction2[TokenInstruction2["ThawAccount"] = 11] = "ThawAccount";
77
+ TokenInstruction2[TokenInstruction2["TransferChecked"] = 12] = "TransferChecked";
78
+ TokenInstruction2[TokenInstruction2["ApproveChecked"] = 13] = "ApproveChecked";
79
+ TokenInstruction2[TokenInstruction2["MintToChecked"] = 14] = "MintToChecked";
80
+ TokenInstruction2[TokenInstruction2["BurnChecked"] = 15] = "BurnChecked";
81
+ TokenInstruction2[TokenInstruction2["InitializeAccount2"] = 16] = "InitializeAccount2";
82
+ TokenInstruction2[TokenInstruction2["SyncNative"] = 17] = "SyncNative";
83
+ TokenInstruction2[TokenInstruction2["InitializeAccount3"] = 18] = "InitializeAccount3";
84
+ TokenInstruction2[TokenInstruction2["InitializeMultisig2"] = 19] = "InitializeMultisig2";
85
+ TokenInstruction2[TokenInstruction2["InitializeMint2"] = 20] = "InitializeMint2";
86
+ return TokenInstruction2;
87
+ })(TokenInstruction || {});
88
+ var TLV_TYPE_SIZE = 2;
89
+ var TLV_LENGTH_SIZE = 2;
90
+ var MINT_EXTENSIONS_OFFSET = MINT_SIZE + 1;
91
+
92
+ // src/errors.ts
93
+ var SplTokenErrorCode = /* @__PURE__ */ ((SplTokenErrorCode2) => {
94
+ SplTokenErrorCode2["INVALID_MINT"] = "INVALID_MINT";
95
+ SplTokenErrorCode2["INVALID_TOKEN_ACCOUNT"] = "INVALID_TOKEN_ACCOUNT";
96
+ SplTokenErrorCode2["TOKEN_ACCOUNT_NOT_FOUND"] = "TOKEN_ACCOUNT_NOT_FOUND";
97
+ SplTokenErrorCode2["MINT_NOT_FOUND"] = "MINT_NOT_FOUND";
98
+ SplTokenErrorCode2["ACCOUNT_FROZEN"] = "ACCOUNT_FROZEN";
99
+ SplTokenErrorCode2["INSUFFICIENT_BALANCE"] = "INSUFFICIENT_BALANCE";
100
+ SplTokenErrorCode2["INVALID_EXTENSION"] = "INVALID_EXTENSION";
101
+ SplTokenErrorCode2["PDA_DERIVATION_FAILED"] = "PDA_DERIVATION_FAILED";
102
+ SplTokenErrorCode2["INVALID_METADATA"] = "INVALID_METADATA";
103
+ SplTokenErrorCode2["ACCOUNT_NOT_INITIALIZED"] = "ACCOUNT_NOT_INITIALIZED";
104
+ return SplTokenErrorCode2;
105
+ })(SplTokenErrorCode || {});
106
+ var SplTokenError = class _SplTokenError extends Error {
107
+ code;
108
+ details;
109
+ constructor({ code, message, details }) {
110
+ super(message);
111
+ this.name = "SplTokenError";
112
+ this.code = code;
113
+ this.details = details;
114
+ if (Error.captureStackTrace) {
115
+ Error.captureStackTrace(this, _SplTokenError);
116
+ }
117
+ }
118
+ /**
119
+ * Creates an invalid mint error.
120
+ *
121
+ * @param options - Error options containing the reason
122
+ */
123
+ static invalidMint({ reason }) {
124
+ return new _SplTokenError({
125
+ code: "INVALID_MINT" /* INVALID_MINT */,
126
+ message: `Invalid mint: ${reason}`
127
+ });
128
+ }
129
+ /**
130
+ * Creates an invalid token account error.
131
+ *
132
+ * @param options - Error options containing the reason
133
+ */
134
+ static invalidTokenAccount({ reason }) {
135
+ return new _SplTokenError({
136
+ code: "INVALID_TOKEN_ACCOUNT" /* INVALID_TOKEN_ACCOUNT */,
137
+ message: `Invalid token account: ${reason}`
138
+ });
139
+ }
140
+ /**
141
+ * Creates a token account not found error.
142
+ *
143
+ * @param options - Error options containing the address
144
+ */
145
+ static tokenAccountNotFound({ address }) {
146
+ return new _SplTokenError({
147
+ code: "TOKEN_ACCOUNT_NOT_FOUND" /* TOKEN_ACCOUNT_NOT_FOUND */,
148
+ message: `Token account not found: ${address}`,
149
+ details: { address }
150
+ });
151
+ }
152
+ /**
153
+ * Creates a mint not found error.
154
+ *
155
+ * @param options - Error options containing the address
156
+ */
157
+ static mintNotFound({ address }) {
158
+ return new _SplTokenError({
159
+ code: "MINT_NOT_FOUND" /* MINT_NOT_FOUND */,
160
+ message: `Mint not found: ${address}`,
161
+ details: { address }
162
+ });
163
+ }
164
+ /**
165
+ * Creates an account frozen error.
166
+ *
167
+ * @param options - Error options containing the address
168
+ */
169
+ static accountFrozen({ address }) {
170
+ return new _SplTokenError({
171
+ code: "ACCOUNT_FROZEN" /* ACCOUNT_FROZEN */,
172
+ message: `Token account is frozen: ${address}`,
173
+ details: { address }
174
+ });
175
+ }
176
+ /**
177
+ * Creates an insufficient balance error.
178
+ *
179
+ * @param options - Error options containing required and available amounts
180
+ */
181
+ static insufficientBalance({
182
+ required,
183
+ available
184
+ }) {
185
+ return new _SplTokenError({
186
+ code: "INSUFFICIENT_BALANCE" /* INSUFFICIENT_BALANCE */,
187
+ message: `Insufficient balance: required ${required}, available ${available}`,
188
+ details: { required: required.toString(), available: available.toString() }
189
+ });
190
+ }
191
+ /**
192
+ * Creates an invalid extension error.
193
+ *
194
+ * @param options - Error options containing the reason
195
+ */
196
+ static invalidExtension({ reason }) {
197
+ return new _SplTokenError({
198
+ code: "INVALID_EXTENSION" /* INVALID_EXTENSION */,
199
+ message: `Invalid extension: ${reason}`
200
+ });
201
+ }
202
+ /**
203
+ * Creates a PDA derivation failed error.
204
+ *
205
+ * @param options - Error options containing the reason
206
+ */
207
+ static pdaDerivationFailed({ reason }) {
208
+ return new _SplTokenError({
209
+ code: "PDA_DERIVATION_FAILED" /* PDA_DERIVATION_FAILED */,
210
+ message: `PDA derivation failed: ${reason}`
211
+ });
212
+ }
213
+ /**
214
+ * Creates an invalid metadata error.
215
+ *
216
+ * @param options - Error options containing the reason
217
+ */
218
+ static invalidMetadata({ reason }) {
219
+ return new _SplTokenError({
220
+ code: "INVALID_METADATA" /* INVALID_METADATA */,
221
+ message: `Invalid metadata: ${reason}`
222
+ });
223
+ }
224
+ /**
225
+ * Creates an account not initialized error.
226
+ *
227
+ * @param options - Error options containing the address
228
+ */
229
+ static accountNotInitialized({ address }) {
230
+ return new _SplTokenError({
231
+ code: "ACCOUNT_NOT_INITIALIZED" /* ACCOUNT_NOT_INITIALIZED */,
232
+ message: `Account not initialized: ${address}`,
233
+ details: { address }
234
+ });
235
+ }
236
+ };
237
+ function createAssociatedTokenAccountInstruction({
238
+ payer,
239
+ associatedToken,
240
+ owner,
241
+ mint,
242
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
243
+ }) {
244
+ const associatedTokenProgramId = PublicKey.fromString(ASSOCIATED_TOKEN_PROGRAM_ID);
245
+ const systemProgramId = PublicKey.fromString(SYSTEM_PROGRAM_ID);
246
+ return {
247
+ programId: associatedTokenProgramId,
248
+ accounts: [
249
+ { pubkey: payer, isSigner: true, isWritable: true },
250
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
251
+ { pubkey: owner, isSigner: false, isWritable: false },
252
+ { pubkey: mint, isSigner: false, isWritable: false },
253
+ { pubkey: systemProgramId, isSigner: false, isWritable: false },
254
+ { pubkey: programId, isSigner: false, isWritable: false }
255
+ ],
256
+ // CreateAssociatedTokenAccount has no instruction data
257
+ data: new Uint8Array(0)
258
+ };
259
+ }
260
+ function createAssociatedTokenAccountIdempotentInstruction({
261
+ payer,
262
+ associatedToken,
263
+ owner,
264
+ mint,
265
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
266
+ }) {
267
+ const associatedTokenProgramId = PublicKey.fromString(ASSOCIATED_TOKEN_PROGRAM_ID);
268
+ const systemProgramId = PublicKey.fromString(SYSTEM_PROGRAM_ID);
269
+ return {
270
+ programId: associatedTokenProgramId,
271
+ accounts: [
272
+ { pubkey: payer, isSigner: true, isWritable: true },
273
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
274
+ { pubkey: owner, isSigner: false, isWritable: false },
275
+ { pubkey: mint, isSigner: false, isWritable: false },
276
+ { pubkey: systemProgramId, isSigner: false, isWritable: false },
277
+ { pubkey: programId, isSigner: false, isWritable: false }
278
+ ],
279
+ // Idempotent variant uses instruction discriminator 1
280
+ data: new Uint8Array([1])
281
+ };
282
+ }
283
+
284
+ // src/test-helpers.ts
285
+ function writeU64LE({
286
+ data,
287
+ offset,
288
+ value
289
+ }) {
290
+ for (let i = 0; i < 8; i++) {
291
+ data[offset + i] = Number(value >> BigInt(i * 8) & 0xffn);
292
+ }
293
+ }
294
+
295
+ // src/instructions/mint.ts
296
+ function initializeMintInstruction({
297
+ mint,
298
+ decimals,
299
+ mintAuthority,
300
+ freezeAuthority,
301
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
302
+ }) {
303
+ const data = new Uint8Array(67);
304
+ data[0] = 20 /* InitializeMint2 */;
305
+ data[1] = decimals;
306
+ data.set(mintAuthority.toBytes(), 2);
307
+ if (freezeAuthority) {
308
+ data[34] = 1;
309
+ data.set(freezeAuthority.toBytes(), 35);
310
+ } else {
311
+ data[34] = 0;
312
+ }
313
+ const [tombstonePda] = PublicKey.findProgramAddress(
314
+ ["mint_tombstone", mint.toBytes()],
315
+ programId
316
+ );
317
+ return {
318
+ programId,
319
+ accounts: [
320
+ { pubkey: mint, isSigner: false, isWritable: true },
321
+ { pubkey: tombstonePda, isSigner: false, isWritable: false }
322
+ ],
323
+ data
324
+ };
325
+ }
326
+ function mintToInstruction({
327
+ mint,
328
+ destination,
329
+ authority,
330
+ amount,
331
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
332
+ }) {
333
+ const data = new Uint8Array(9);
334
+ data[0] = 7 /* MintTo */;
335
+ writeU64LE({ data, offset: 1, value: amount });
336
+ return {
337
+ programId,
338
+ accounts: [
339
+ { pubkey: mint, isSigner: false, isWritable: true },
340
+ { pubkey: destination, isSigner: false, isWritable: true },
341
+ { pubkey: authority, isSigner: true, isWritable: false }
342
+ ],
343
+ data
344
+ };
345
+ }
346
+ function writeU64LE2({
347
+ data,
348
+ offset,
349
+ value
350
+ }) {
351
+ for (let i = 0; i < 8; i++) {
352
+ data[offset + i] = Number(value >> BigInt(i * 8) & 0xffn);
353
+ }
354
+ }
355
+ function transferCheckedInstruction({
356
+ source,
357
+ mint,
358
+ destination,
359
+ authority,
360
+ amount,
361
+ decimals,
362
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
363
+ }) {
364
+ const data = new Uint8Array(10);
365
+ data[0] = 12 /* TransferChecked */;
366
+ writeU64LE2({ data, offset: 1, value: amount });
367
+ data[9] = decimals;
368
+ return {
369
+ programId,
370
+ accounts: [
371
+ { pubkey: source, isSigner: false, isWritable: true },
372
+ { pubkey: mint, isSigner: false, isWritable: false },
373
+ { pubkey: destination, isSigner: false, isWritable: true },
374
+ { pubkey: authority, isSigner: true, isWritable: false }
375
+ ],
376
+ data
377
+ };
378
+ }
379
+ function transferInstruction({
380
+ source,
381
+ destination,
382
+ authority,
383
+ amount,
384
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
385
+ }) {
386
+ const data = new Uint8Array(9);
387
+ data[0] = 3 /* Transfer */;
388
+ writeU64LE2({ data, offset: 1, value: amount });
389
+ return {
390
+ programId,
391
+ accounts: [
392
+ { pubkey: source, isSigner: false, isWritable: true },
393
+ { pubkey: destination, isSigner: false, isWritable: true },
394
+ { pubkey: authority, isSigner: true, isWritable: false }
395
+ ],
396
+ data
397
+ };
398
+ }
399
+
400
+ // node_modules/@noble/hashes/utils.js
401
+ function isBytes(a) {
402
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
403
+ }
404
+ function abytes(value, length, title = "") {
405
+ const bytes = isBytes(value);
406
+ const len = value?.length;
407
+ const needsLen = length !== void 0;
408
+ if (!bytes || needsLen) {
409
+ const prefix = title && `"${title}" `;
410
+ const ofLen = "";
411
+ const got = bytes ? `length=${len}` : `type=${typeof value}`;
412
+ throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
413
+ }
414
+ return value;
415
+ }
416
+ function aexists(instance, checkFinished = true) {
417
+ if (instance.destroyed)
418
+ throw new Error("Hash instance has been destroyed");
419
+ if (checkFinished && instance.finished)
420
+ throw new Error("Hash#digest() has already been called");
421
+ }
422
+ function aoutput(out, instance) {
423
+ abytes(out, void 0, "digestInto() output");
424
+ const min = instance.outputLen;
425
+ if (out.length < min) {
426
+ throw new Error('"digestInto() output" expected to be of length >=' + min);
427
+ }
428
+ }
429
+ function clean(...arrays) {
430
+ for (let i = 0; i < arrays.length; i++) {
431
+ arrays[i].fill(0);
432
+ }
433
+ }
434
+ function createView(arr) {
435
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
436
+ }
437
+ function rotr(word, shift) {
438
+ return word << 32 - shift | word >>> shift;
439
+ }
440
+ function createHasher(hashCons, info = {}) {
441
+ const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
442
+ const tmp = hashCons(void 0);
443
+ hashC.outputLen = tmp.outputLen;
444
+ hashC.blockLen = tmp.blockLen;
445
+ hashC.create = (opts) => hashCons(opts);
446
+ Object.assign(hashC, info);
447
+ return Object.freeze(hashC);
448
+ }
449
+ var oidNist = (suffix) => ({
450
+ oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
451
+ });
452
+
453
+ // node_modules/@noble/hashes/_md.js
454
+ function Chi(a, b, c) {
455
+ return a & b ^ ~a & c;
456
+ }
457
+ function Maj(a, b, c) {
458
+ return a & b ^ a & c ^ b & c;
459
+ }
460
+ var HashMD = class {
461
+ blockLen;
462
+ outputLen;
463
+ padOffset;
464
+ isLE;
465
+ // For partial updates less than block size
466
+ buffer;
467
+ view;
468
+ finished = false;
469
+ length = 0;
470
+ pos = 0;
471
+ destroyed = false;
472
+ constructor(blockLen, outputLen, padOffset, isLE) {
473
+ this.blockLen = blockLen;
474
+ this.outputLen = outputLen;
475
+ this.padOffset = padOffset;
476
+ this.isLE = isLE;
477
+ this.buffer = new Uint8Array(blockLen);
478
+ this.view = createView(this.buffer);
479
+ }
480
+ update(data) {
481
+ aexists(this);
482
+ abytes(data);
483
+ const { view, buffer, blockLen } = this;
484
+ const len = data.length;
485
+ for (let pos = 0; pos < len; ) {
486
+ const take = Math.min(blockLen - this.pos, len - pos);
487
+ if (take === blockLen) {
488
+ const dataView = createView(data);
489
+ for (; blockLen <= len - pos; pos += blockLen)
490
+ this.process(dataView, pos);
491
+ continue;
492
+ }
493
+ buffer.set(data.subarray(pos, pos + take), this.pos);
494
+ this.pos += take;
495
+ pos += take;
496
+ if (this.pos === blockLen) {
497
+ this.process(view, 0);
498
+ this.pos = 0;
499
+ }
500
+ }
501
+ this.length += data.length;
502
+ this.roundClean();
503
+ return this;
504
+ }
505
+ digestInto(out) {
506
+ aexists(this);
507
+ aoutput(out, this);
508
+ this.finished = true;
509
+ const { buffer, view, blockLen, isLE } = this;
510
+ let { pos } = this;
511
+ buffer[pos++] = 128;
512
+ clean(this.buffer.subarray(pos));
513
+ if (this.padOffset > blockLen - pos) {
514
+ this.process(view, 0);
515
+ pos = 0;
516
+ }
517
+ for (let i = pos; i < blockLen; i++)
518
+ buffer[i] = 0;
519
+ view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
520
+ this.process(view, 0);
521
+ const oview = createView(out);
522
+ const len = this.outputLen;
523
+ if (len % 4)
524
+ throw new Error("_sha2: outputLen must be aligned to 32bit");
525
+ const outLen = len / 4;
526
+ const state = this.get();
527
+ if (outLen > state.length)
528
+ throw new Error("_sha2: outputLen bigger than state");
529
+ for (let i = 0; i < outLen; i++)
530
+ oview.setUint32(4 * i, state[i], isLE);
531
+ }
532
+ digest() {
533
+ const { buffer, outputLen } = this;
534
+ this.digestInto(buffer);
535
+ const res = buffer.slice(0, outputLen);
536
+ this.destroy();
537
+ return res;
538
+ }
539
+ _cloneInto(to) {
540
+ to ||= new this.constructor();
541
+ to.set(...this.get());
542
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
543
+ to.destroyed = destroyed;
544
+ to.finished = finished;
545
+ to.length = length;
546
+ to.pos = pos;
547
+ if (length % blockLen)
548
+ to.buffer.set(buffer);
549
+ return to;
550
+ }
551
+ clone() {
552
+ return this._cloneInto();
553
+ }
554
+ };
555
+ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
556
+ 1779033703,
557
+ 3144134277,
558
+ 1013904242,
559
+ 2773480762,
560
+ 1359893119,
561
+ 2600822924,
562
+ 528734635,
563
+ 1541459225
564
+ ]);
565
+
566
+ // node_modules/@noble/hashes/sha2.js
567
+ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
568
+ 1116352408,
569
+ 1899447441,
570
+ 3049323471,
571
+ 3921009573,
572
+ 961987163,
573
+ 1508970993,
574
+ 2453635748,
575
+ 2870763221,
576
+ 3624381080,
577
+ 310598401,
578
+ 607225278,
579
+ 1426881987,
580
+ 1925078388,
581
+ 2162078206,
582
+ 2614888103,
583
+ 3248222580,
584
+ 3835390401,
585
+ 4022224774,
586
+ 264347078,
587
+ 604807628,
588
+ 770255983,
589
+ 1249150122,
590
+ 1555081692,
591
+ 1996064986,
592
+ 2554220882,
593
+ 2821834349,
594
+ 2952996808,
595
+ 3210313671,
596
+ 3336571891,
597
+ 3584528711,
598
+ 113926993,
599
+ 338241895,
600
+ 666307205,
601
+ 773529912,
602
+ 1294757372,
603
+ 1396182291,
604
+ 1695183700,
605
+ 1986661051,
606
+ 2177026350,
607
+ 2456956037,
608
+ 2730485921,
609
+ 2820302411,
610
+ 3259730800,
611
+ 3345764771,
612
+ 3516065817,
613
+ 3600352804,
614
+ 4094571909,
615
+ 275423344,
616
+ 430227734,
617
+ 506948616,
618
+ 659060556,
619
+ 883997877,
620
+ 958139571,
621
+ 1322822218,
622
+ 1537002063,
623
+ 1747873779,
624
+ 1955562222,
625
+ 2024104815,
626
+ 2227730452,
627
+ 2361852424,
628
+ 2428436474,
629
+ 2756734187,
630
+ 3204031479,
631
+ 3329325298
632
+ ]);
633
+ var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
634
+ var SHA2_32B = class extends HashMD {
635
+ constructor(outputLen) {
636
+ super(64, outputLen, 8, false);
637
+ }
638
+ get() {
639
+ const { A, B, C, D, E, F, G, H } = this;
640
+ return [A, B, C, D, E, F, G, H];
641
+ }
642
+ // prettier-ignore
643
+ set(A, B, C, D, E, F, G, H) {
644
+ this.A = A | 0;
645
+ this.B = B | 0;
646
+ this.C = C | 0;
647
+ this.D = D | 0;
648
+ this.E = E | 0;
649
+ this.F = F | 0;
650
+ this.G = G | 0;
651
+ this.H = H | 0;
652
+ }
653
+ process(view, offset) {
654
+ for (let i = 0; i < 16; i++, offset += 4)
655
+ SHA256_W[i] = view.getUint32(offset, false);
656
+ for (let i = 16; i < 64; i++) {
657
+ const W15 = SHA256_W[i - 15];
658
+ const W2 = SHA256_W[i - 2];
659
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
660
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
661
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
662
+ }
663
+ let { A, B, C, D, E, F, G, H } = this;
664
+ for (let i = 0; i < 64; i++) {
665
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
666
+ const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
667
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
668
+ const T2 = sigma0 + Maj(A, B, C) | 0;
669
+ H = G;
670
+ G = F;
671
+ F = E;
672
+ E = D + T1 | 0;
673
+ D = C;
674
+ C = B;
675
+ B = A;
676
+ A = T1 + T2 | 0;
677
+ }
678
+ A = A + this.A | 0;
679
+ B = B + this.B | 0;
680
+ C = C + this.C | 0;
681
+ D = D + this.D | 0;
682
+ E = E + this.E | 0;
683
+ F = F + this.F | 0;
684
+ G = G + this.G | 0;
685
+ H = H + this.H | 0;
686
+ this.set(A, B, C, D, E, F, G, H);
687
+ }
688
+ roundClean() {
689
+ clean(SHA256_W);
690
+ }
691
+ destroy() {
692
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
693
+ clean(this.buffer);
694
+ }
695
+ };
696
+ var _SHA256 = class extends SHA2_32B {
697
+ // We cannot use array here since array allows indexing by variable
698
+ // which means optimizer/compiler cannot use registers.
699
+ A = SHA256_IV[0] | 0;
700
+ B = SHA256_IV[1] | 0;
701
+ C = SHA256_IV[2] | 0;
702
+ D = SHA256_IV[3] | 0;
703
+ E = SHA256_IV[4] | 0;
704
+ F = SHA256_IV[5] | 0;
705
+ G = SHA256_IV[6] | 0;
706
+ H = SHA256_IV[7] | 0;
707
+ constructor() {
708
+ super(32);
709
+ }
710
+ };
711
+ var sha256 = /* @__PURE__ */ createHasher(
712
+ () => new _SHA256(),
713
+ /* @__PURE__ */ oidNist(1)
714
+ );
715
+ function createProgramAddress({
716
+ seeds,
717
+ programId
718
+ }) {
719
+ for (let bump = 255; bump >= 0; bump--) {
720
+ const bumpSeed = new Uint8Array([bump]);
721
+ const allSeeds = [...seeds, bumpSeed];
722
+ const programIdBytes = programId.toBytes();
723
+ const pda_marker = new TextEncoder().encode("ProgramDerivedAddress");
724
+ let totalLength = 0;
725
+ for (const seed of allSeeds) {
726
+ totalLength += seed.length;
727
+ }
728
+ totalLength += programIdBytes.length + pda_marker.length;
729
+ const combined = new Uint8Array(totalLength);
730
+ let offset = 0;
731
+ for (const seed of allSeeds) {
732
+ combined.set(seed, offset);
733
+ offset += seed.length;
734
+ }
735
+ combined.set(programIdBytes, offset);
736
+ offset += programIdBytes.length;
737
+ combined.set(pda_marker, offset);
738
+ const hash = sha256(combined);
739
+ if (!isOnCurve(hash)) {
740
+ return {
741
+ address: PublicKey.fromBytes(hash),
742
+ bump
743
+ };
744
+ }
745
+ }
746
+ return null;
747
+ }
748
+ function findAssociatedTokenAddress({
749
+ wallet,
750
+ mint,
751
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
752
+ }) {
753
+ const associatedTokenProgramId = PublicKey.fromString(ASSOCIATED_TOKEN_PROGRAM_ID);
754
+ const seeds = [wallet.toBytes(), programId.toBytes(), mint.toBytes()];
755
+ const result = createProgramAddress({ seeds, programId: associatedTokenProgramId });
756
+ if (!result) {
757
+ throw SplTokenError.pdaDerivationFailed({
758
+ reason: `Could not find valid PDA for wallet=${wallet.toString()}, mint=${mint.toString()}`
759
+ });
760
+ }
761
+ return result;
762
+ }
763
+ function getAssociatedTokenAddressSync({
764
+ wallet,
765
+ mint,
766
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
767
+ }) {
768
+ return findAssociatedTokenAddress({ wallet, mint, programId }).address;
769
+ }
770
+ function readU64LE({ data, offset }) {
771
+ let value = 0n;
772
+ for (let i = 0; i < 8; i++) {
773
+ value |= BigInt(data[offset + i]) << BigInt(i * 8);
774
+ }
775
+ return value;
776
+ }
777
+ function readU32LE({ data, offset }) {
778
+ return (data[offset] | data[offset + 1] << 8 | data[offset + 2] << 16 | data[offset + 3] << 24) >>> 0;
779
+ }
780
+ function readCOptionPubkey({
781
+ data,
782
+ offset
783
+ }) {
784
+ const tag = readU32LE({ data, offset });
785
+ if (tag === COPTION_SOME) {
786
+ const pubkeyBytes = data.slice(offset + 4, offset + 4 + PUBKEY_SIZE);
787
+ return PublicKey.fromBytes(pubkeyBytes);
788
+ }
789
+ return null;
790
+ }
791
+ function parseMintAccount({ address, data }) {
792
+ if (data.length < MINT_SIZE) {
793
+ throw SplTokenError.invalidMint({
794
+ reason: `Account data too short: expected at least ${MINT_SIZE} bytes, got ${data.length}`
795
+ });
796
+ }
797
+ const mintAuthority = readCOptionPubkey({ data, offset: 0 });
798
+ const supply = readU64LE({ data, offset: MINT_SUPPLY_OFFSET });
799
+ const decimals = data[MINT_DECIMALS_OFFSET];
800
+ const isInitialized = data[MINT_IS_INITIALIZED_OFFSET] !== 0;
801
+ const freezeAuthority = readCOptionPubkey({ data, offset: MINT_FREEZE_AUTHORITY_OFFSET });
802
+ if (!isInitialized) {
803
+ throw SplTokenError.accountNotInitialized({ address: address.toString() });
804
+ }
805
+ return {
806
+ address,
807
+ supply,
808
+ decimals,
809
+ isInitialized,
810
+ mintAuthority,
811
+ freezeAuthority
812
+ };
813
+ }
814
+ function readU64LE2({ data, offset }) {
815
+ let value = 0n;
816
+ for (let i = 0; i < 8; i++) {
817
+ value |= BigInt(data[offset + i]) << BigInt(i * 8);
818
+ }
819
+ return value;
820
+ }
821
+ function readU32LE2({ data, offset }) {
822
+ return (data[offset] | data[offset + 1] << 8 | data[offset + 2] << 16 | data[offset + 3] << 24) >>> 0;
823
+ }
824
+ function readCOptionPubkey2({
825
+ data,
826
+ offset
827
+ }) {
828
+ const tag = readU32LE2({ data, offset });
829
+ if (tag === COPTION_SOME) {
830
+ const pubkeyBytes = data.slice(offset + 4, offset + 4 + PUBKEY_SIZE);
831
+ return PublicKey.fromBytes(pubkeyBytes);
832
+ }
833
+ return null;
834
+ }
835
+ function readCOptionU64({ data, offset }) {
836
+ const tag = readU32LE2({ data, offset });
837
+ if (tag === COPTION_SOME) {
838
+ return readU64LE2({ data, offset: offset + 4 });
839
+ }
840
+ return null;
841
+ }
842
+ function parseTokenAccount({ address, data }) {
843
+ if (data.length < TOKEN_ACCOUNT_SIZE) {
844
+ throw SplTokenError.invalidTokenAccount({
845
+ reason: `Account data too short: expected at least ${TOKEN_ACCOUNT_SIZE} bytes, got ${data.length}`
846
+ });
847
+ }
848
+ const mintBytes = data.slice(TOKEN_ACCOUNT_MINT_OFFSET, TOKEN_ACCOUNT_MINT_OFFSET + PUBKEY_SIZE);
849
+ const mint = PublicKey.fromBytes(mintBytes);
850
+ const ownerBytes = data.slice(
851
+ TOKEN_ACCOUNT_OWNER_OFFSET,
852
+ TOKEN_ACCOUNT_OWNER_OFFSET + PUBKEY_SIZE
853
+ );
854
+ const owner = PublicKey.fromBytes(ownerBytes);
855
+ const amount = readU64LE2({ data, offset: TOKEN_ACCOUNT_AMOUNT_OFFSET });
856
+ const delegate = readCOptionPubkey2({ data, offset: TOKEN_ACCOUNT_DELEGATE_OFFSET });
857
+ const stateValue = data[TOKEN_ACCOUNT_STATE_OFFSET];
858
+ if (stateValue > 2) {
859
+ throw SplTokenError.invalidTokenAccount({ reason: `Invalid account state: ${stateValue}` });
860
+ }
861
+ const state = stateValue;
862
+ if (state === 0 /* Uninitialized */) {
863
+ throw SplTokenError.accountNotInitialized({ address: address.toString() });
864
+ }
865
+ const isNative = readCOptionU64({ data, offset: TOKEN_ACCOUNT_IS_NATIVE_OFFSET });
866
+ const delegatedAmount = readU64LE2({ data, offset: TOKEN_ACCOUNT_DELEGATED_AMOUNT_OFFSET });
867
+ const closeAuthority = readCOptionPubkey2({ data, offset: TOKEN_ACCOUNT_CLOSE_AUTHORITY_OFFSET });
868
+ return {
869
+ address,
870
+ mint,
871
+ owner,
872
+ amount,
873
+ delegate,
874
+ state,
875
+ isNative,
876
+ delegatedAmount,
877
+ closeAuthority
878
+ };
879
+ }
880
+ function readU16LE({ data, offset }) {
881
+ return data[offset] | data[offset + 1] << 8;
882
+ }
883
+ function readU32LE3({ data, offset }) {
884
+ return (data[offset] | data[offset + 1] << 8 | data[offset + 2] << 16 | data[offset + 3] << 24) >>> 0;
885
+ }
886
+ function readCOptionPubkey3({
887
+ data,
888
+ offset
889
+ }) {
890
+ const tag = readU32LE3({ data, offset });
891
+ if (tag === COPTION_SOME) {
892
+ const pubkeyBytes = data.slice(offset + 4, offset + 4 + PUBKEY_SIZE);
893
+ return PublicKey.fromBytes(pubkeyBytes);
894
+ }
895
+ return null;
896
+ }
897
+ function readLengthPrefixedString({
898
+ data,
899
+ offset
900
+ }) {
901
+ if (offset + 4 > data.length) {
902
+ throw SplTokenError.invalidMetadata({ reason: "String length prefix extends beyond data" });
903
+ }
904
+ const length = readU32LE3({ data, offset });
905
+ if (offset + 4 + length > data.length) {
906
+ throw SplTokenError.invalidMetadata({
907
+ reason: `String data extends beyond buffer: need ${length} bytes at offset ${offset + 4}`
908
+ });
909
+ }
910
+ const stringBytes = data.slice(offset + 4, offset + 4 + length);
911
+ try {
912
+ const str = new TextDecoder().decode(stringBytes);
913
+ return [str, 4 + length];
914
+ } catch (error) {
915
+ throw SplTokenError.invalidMetadata({
916
+ reason: `Invalid UTF-8 string at offset ${offset}`
917
+ });
918
+ }
919
+ }
920
+ function parseExtensions({
921
+ data,
922
+ extensionsOffset
923
+ }) {
924
+ const extensions = [];
925
+ let offset = extensionsOffset;
926
+ while (offset + TLV_TYPE_SIZE + TLV_LENGTH_SIZE <= data.length) {
927
+ const type = readU16LE({ data, offset });
928
+ const length = readU16LE({ data, offset: offset + TLV_TYPE_SIZE });
929
+ if (type === 0 && length === 0) {
930
+ break;
931
+ }
932
+ const dataStart = offset + TLV_TYPE_SIZE + TLV_LENGTH_SIZE;
933
+ const dataEnd = dataStart + length;
934
+ if (dataEnd > data.length) {
935
+ throw SplTokenError.invalidExtension({
936
+ reason: `Extension data extends beyond buffer: type=${type}, length=${length}`
937
+ });
938
+ }
939
+ extensions.push({
940
+ type,
941
+ data: data.slice(dataStart, dataEnd)
942
+ });
943
+ offset = dataEnd;
944
+ }
945
+ return extensions;
946
+ }
947
+ function parseMetadataPointer({ data }) {
948
+ if (data.length < 72) {
949
+ throw SplTokenError.invalidExtension({
950
+ reason: `MetadataPointer too short: expected 72 bytes, got ${data.length}`
951
+ });
952
+ }
953
+ const authority = readCOptionPubkey3({ data, offset: 0 });
954
+ const metadataAddress = readCOptionPubkey3({ data, offset: 36 });
955
+ return { authority, metadataAddress };
956
+ }
957
+ function parseTokenMetadataExtension({
958
+ data,
959
+ mint
960
+ }) {
961
+ if (data.length < 64) {
962
+ throw SplTokenError.invalidMetadata({
963
+ reason: `TokenMetadata too short: expected at least 64 bytes, got ${data.length}`
964
+ });
965
+ }
966
+ let offset = 0;
967
+ const updateAuthorityBytes = data.slice(offset, offset + PUBKEY_SIZE);
968
+ const isZeroAuthority = updateAuthorityBytes.every((b) => b === 0);
969
+ const updateAuthority = isZeroAuthority ? null : PublicKey.fromBytes(updateAuthorityBytes);
970
+ offset += PUBKEY_SIZE;
971
+ offset += PUBKEY_SIZE;
972
+ const [name, nameLen] = readLengthPrefixedString({ data, offset });
973
+ offset += nameLen;
974
+ const [symbol, symbolLen] = readLengthPrefixedString({ data, offset });
975
+ offset += symbolLen;
976
+ const [uri, uriLen] = readLengthPrefixedString({ data, offset });
977
+ offset += uriLen;
978
+ const additionalMetadata = [];
979
+ if (offset + 4 <= data.length) {
980
+ const numEntries = readU32LE3({ data, offset });
981
+ offset += 4;
982
+ for (let i = 0; i < numEntries && offset < data.length; i++) {
983
+ const [key, keyLen] = readLengthPrefixedString({ data, offset });
984
+ offset += keyLen;
985
+ const [value, valueLen] = readLengthPrefixedString({ data, offset });
986
+ offset += valueLen;
987
+ additionalMetadata.push([key, value]);
988
+ }
989
+ }
990
+ return {
991
+ updateAuthority,
992
+ mint,
993
+ name,
994
+ symbol,
995
+ uri,
996
+ additionalMetadata
997
+ };
998
+ }
999
+ function parseTokenMetadata({
1000
+ mint,
1001
+ data
1002
+ }) {
1003
+ if (data.length <= MINT_SIZE) {
1004
+ return null;
1005
+ }
1006
+ const accountType = data[MINT_SIZE];
1007
+ if (accountType !== 1 /* Mint */) {
1008
+ return null;
1009
+ }
1010
+ const extensions = parseExtensions({ data, extensionsOffset: MINT_EXTENSIONS_OFFSET });
1011
+ const metadataExt = extensions.find((ext) => ext.type === 19 /* TokenMetadata */);
1012
+ if (!metadataExt) {
1013
+ return null;
1014
+ }
1015
+ return parseTokenMetadataExtension({ data: metadataExt.data, mint });
1016
+ }
1017
+ function parseMetadataPointerExtension({
1018
+ data
1019
+ }) {
1020
+ if (data.length <= MINT_SIZE) {
1021
+ return null;
1022
+ }
1023
+ const accountType = data[MINT_SIZE];
1024
+ if (accountType !== 1 /* Mint */) {
1025
+ return null;
1026
+ }
1027
+ const extensions = parseExtensions({ data, extensionsOffset: MINT_EXTENSIONS_OFFSET });
1028
+ const pointerExt = extensions.find((ext) => ext.type === 18 /* MetadataPointer */);
1029
+ if (!pointerExt) {
1030
+ return null;
1031
+ }
1032
+ return parseMetadataPointer({ data: pointerExt.data });
1033
+ }
1034
+ function getMintExtensions({ data }) {
1035
+ if (data.length <= MINT_SIZE) {
1036
+ return [];
1037
+ }
1038
+ const accountType = data[MINT_SIZE];
1039
+ if (accountType !== 1 /* Mint */) {
1040
+ return [];
1041
+ }
1042
+ return parseExtensions({ data, extensionsOffset: MINT_EXTENSIONS_OFFSET });
1043
+ }
1044
+
1045
+ // src/client/spl-token-client.ts
1046
+ function decodeAccountData(data) {
1047
+ if (data instanceof Uint8Array) return data;
1048
+ const encoded = data[0];
1049
+ const binaryStr = atob(encoded);
1050
+ const bytes = new Uint8Array(binaryStr.length);
1051
+ for (let i = 0; i < binaryStr.length; i++) {
1052
+ bytes[i] = binaryStr.charCodeAt(i);
1053
+ }
1054
+ return bytes;
1055
+ }
1056
+ var SplTokenClient = class {
1057
+ client;
1058
+ programId;
1059
+ /**
1060
+ * Creates a new SplTokenClient.
1061
+ *
1062
+ * @param options - Client configuration options
1063
+ */
1064
+ constructor({
1065
+ client,
1066
+ programId = PublicKey.fromString(TOKEN_2022_PROGRAM_ID)
1067
+ }) {
1068
+ this.client = client;
1069
+ this.programId = programId;
1070
+ }
1071
+ /**
1072
+ * Gets the token program ID this client is configured to use.
1073
+ */
1074
+ getProgramId() {
1075
+ return this.programId;
1076
+ }
1077
+ /**
1078
+ * Retrieves mint account information.
1079
+ *
1080
+ * @param options - Options containing the mint public key
1081
+ * @returns Parsed mint information including supply, decimals, and authorities
1082
+ * @throws {SplTokenError} If the mint account doesn't exist or is invalid
1083
+ *
1084
+ * @example
1085
+ * ```typescript
1086
+ * const mintInfo = await tokenClient.getMintInfo({ mint: mintPubkey });
1087
+ * console.log(`Supply: ${mintInfo.supply}`);
1088
+ * console.log(`Decimals: ${mintInfo.decimals}`);
1089
+ * console.log(`Mint Authority: ${mintInfo.mintAuthority?.toString() ?? 'disabled'}`);
1090
+ * ```
1091
+ */
1092
+ async getMintInfo({ mint }) {
1093
+ const accountInfo = await this.client.getAccountInfo(mint);
1094
+ if (!accountInfo) {
1095
+ throw SplTokenError.mintNotFound({ address: mint.toString() });
1096
+ }
1097
+ return parseMintAccount({ address: mint, data: decodeAccountData(accountInfo.data) });
1098
+ }
1099
+ /**
1100
+ * Retrieves Token-2022 native metadata from a mint.
1101
+ *
1102
+ * @param options - Options containing the mint public key
1103
+ * @returns Parsed token metadata, or null if no metadata extension exists
1104
+ * @throws {SplTokenError} If the mint account doesn't exist
1105
+ *
1106
+ * @example
1107
+ * ```typescript
1108
+ * const metadata = await tokenClient.getTokenMetadata({ mint: mintPubkey });
1109
+ * if (metadata) {
1110
+ * console.log(`Name: ${metadata.name}`);
1111
+ * console.log(`Symbol: ${metadata.symbol}`);
1112
+ * console.log(`URI: ${metadata.uri}`);
1113
+ * }
1114
+ * ```
1115
+ */
1116
+ async getTokenMetadata({ mint }) {
1117
+ const accountInfo = await this.client.getAccountInfo(mint);
1118
+ if (!accountInfo) {
1119
+ throw SplTokenError.mintNotFound({ address: mint.toString() });
1120
+ }
1121
+ return parseTokenMetadata({ mint, data: decodeAccountData(accountInfo.data) });
1122
+ }
1123
+ /**
1124
+ * Retrieves token account information.
1125
+ *
1126
+ * @param options - Options containing the token account public key
1127
+ * @returns Parsed token account information
1128
+ * @throws {SplTokenError} If the account doesn't exist or is invalid
1129
+ */
1130
+ async getTokenAccountInfo({
1131
+ tokenAccount
1132
+ }) {
1133
+ const accountInfo = await this.client.getAccountInfo(tokenAccount);
1134
+ if (!accountInfo) {
1135
+ throw SplTokenError.tokenAccountNotFound({ address: tokenAccount.toString() });
1136
+ }
1137
+ return parseTokenAccount({ address: tokenAccount, data: decodeAccountData(accountInfo.data) });
1138
+ }
1139
+ /**
1140
+ * Gets the token balance for a wallet.
1141
+ *
1142
+ * Automatically derives the Associated Token Address for the wallet/mint
1143
+ * combination and retrieves the balance.
1144
+ *
1145
+ * @param options - Options containing wallet and mint public keys
1146
+ * @returns The token balance in smallest units, or 0n if the ATA doesn't exist
1147
+ *
1148
+ * @example
1149
+ * ```typescript
1150
+ * const balance = await tokenClient.getBalance({ wallet: walletPubkey, mint: mintPubkey });
1151
+ * console.log(`Token balance: ${balance}`);
1152
+ * ```
1153
+ */
1154
+ async getBalance({ wallet, mint }) {
1155
+ const ata = getAssociatedTokenAddressSync({ wallet, mint, programId: this.programId });
1156
+ const accountInfo = await this.client.getAccountInfo(ata);
1157
+ if (!accountInfo) {
1158
+ return 0n;
1159
+ }
1160
+ const tokenAccount = parseTokenAccount({ address: ata, data: decodeAccountData(accountInfo.data) });
1161
+ return tokenAccount.amount;
1162
+ }
1163
+ /**
1164
+ * Derives the Associated Token Address for a wallet and mint.
1165
+ *
1166
+ * @param options - Options containing wallet and mint public keys
1167
+ * @returns The derived ATA address and bump seed
1168
+ *
1169
+ * @example
1170
+ * ```typescript
1171
+ * const { address, bump } = tokenClient.getAssociatedTokenAddress({ wallet: walletPubkey, mint: mintPubkey });
1172
+ * console.log(`ATA: ${address.toString()}`);
1173
+ * ```
1174
+ */
1175
+ getAssociatedTokenAddress({
1176
+ wallet,
1177
+ mint
1178
+ }) {
1179
+ return findAssociatedTokenAddress({ wallet, mint, programId: this.programId });
1180
+ }
1181
+ /**
1182
+ * Checks if an Associated Token Account exists.
1183
+ *
1184
+ * @param options - Options containing wallet and mint public keys
1185
+ * @returns True if the ATA exists, false otherwise
1186
+ */
1187
+ async ataExists({ wallet, mint }) {
1188
+ const ata = getAssociatedTokenAddressSync({ wallet, mint, programId: this.programId });
1189
+ const accountInfo = await this.client.getAccountInfo(ata);
1190
+ return accountInfo !== null;
1191
+ }
1192
+ /**
1193
+ * Creates instructions for a token transfer.
1194
+ *
1195
+ * This builds the necessary instructions for transferring tokens,
1196
+ * optionally creating the destination ATA if it doesn't exist.
1197
+ *
1198
+ * @param params - Transfer parameters
1199
+ * @returns Array of instructions to execute
1200
+ * @throws {SplTokenError} If the mint doesn't exist
1201
+ *
1202
+ * @example
1203
+ * ```typescript
1204
+ * const instructions = await tokenClient.createTransferInstructions({
1205
+ * source: senderWallet,
1206
+ * destination: recipientWallet,
1207
+ * mint: mintPubkey,
1208
+ * amount: 1000000n,
1209
+ * decimals: 6,
1210
+ * createDestinationAta: true,
1211
+ * });
1212
+ * ```
1213
+ */
1214
+ async createTransferInstructions(params) {
1215
+ const { source, destination, mint, amount, decimals, createDestinationAta = true } = params;
1216
+ const instructions = [];
1217
+ const sourceAta = getAssociatedTokenAddressSync({
1218
+ wallet: source,
1219
+ mint,
1220
+ programId: this.programId
1221
+ });
1222
+ const destinationAta = getAssociatedTokenAddressSync({
1223
+ wallet: destination,
1224
+ mint,
1225
+ programId: this.programId
1226
+ });
1227
+ if (createDestinationAta) {
1228
+ const destExists = await this.ataExists({ wallet: destination, mint });
1229
+ if (!destExists) {
1230
+ instructions.push(
1231
+ createAssociatedTokenAccountIdempotentInstruction({
1232
+ payer: source,
1233
+ associatedToken: destinationAta,
1234
+ owner: destination,
1235
+ mint,
1236
+ programId: this.programId
1237
+ })
1238
+ );
1239
+ }
1240
+ }
1241
+ instructions.push(
1242
+ transferCheckedInstruction({
1243
+ source: sourceAta,
1244
+ mint,
1245
+ destination: destinationAta,
1246
+ authority: source,
1247
+ amount,
1248
+ decimals,
1249
+ programId: this.programId
1250
+ })
1251
+ );
1252
+ return instructions;
1253
+ }
1254
+ /**
1255
+ * Options for creating a transfer transaction.
1256
+ */
1257
+ /**
1258
+ * Creates a transaction for a token transfer.
1259
+ *
1260
+ * Builds a complete transaction with all necessary instructions for
1261
+ * transferring tokens, including ATA creation if needed.
1262
+ *
1263
+ * @param options - Options containing params and validFrom
1264
+ * @returns Built transaction ready for signing
1265
+ *
1266
+ * @example
1267
+ * ```typescript
1268
+ * const blockHeight = await rialoClient.getBlockHeight();
1269
+ * const configHashPrefix = await rialoClient.getConfigHashPrefix();
1270
+ * const tx = await tokenClient.createTransferTransaction({
1271
+ * params: {
1272
+ * source: senderWallet,
1273
+ * destination: recipientWallet,
1274
+ * mint: mintPubkey,
1275
+ * amount: 1000000n,
1276
+ * decimals: 6,
1277
+ * },
1278
+ * validFrom: blockHeight,
1279
+ * configHashPrefix,
1280
+ * });
1281
+ *
1282
+ * // Sign and send
1283
+ * const signedTx = tx.sign([signer]);
1284
+ * const signature = await rialoClient.sendTransaction(signedTx.serialize());
1285
+ * ```
1286
+ */
1287
+ async createTransferTransaction({
1288
+ params,
1289
+ validFrom,
1290
+ configHashPrefix
1291
+ }) {
1292
+ const instructions = await this.createTransferInstructions(params);
1293
+ const builder = TransactionBuilder.create().setPayer(params.source).setValidFrom(validFrom).setConfigHashPrefix(configHashPrefix);
1294
+ for (const ix of instructions) {
1295
+ builder.addInstruction(ix);
1296
+ }
1297
+ return builder.build();
1298
+ }
1299
+ /**
1300
+ * Transfers tokens from one wallet to another.
1301
+ *
1302
+ * This is a high-level convenience method that:
1303
+ * 1. Creates the destination ATA if needed
1304
+ * 2. Builds the transfer transaction
1305
+ * 3. Signs and sends the transaction
1306
+ * 4. Waits for confirmation
1307
+ *
1308
+ * @param options - Options containing params, validFrom, and signer
1309
+ * @returns Transaction signature
1310
+ *
1311
+ * @example
1312
+ * ```typescript
1313
+ * const blockHeight = await rialoClient.getBlockHeight();
1314
+ * const configHashPrefix = await rialoClient.getConfigHashPrefix();
1315
+ * const signature = await tokenClient.transfer({
1316
+ * params: {
1317
+ * source: senderWallet,
1318
+ * destination: recipientWallet,
1319
+ * mint: mintPubkey,
1320
+ * amount: 1000000n,
1321
+ * decimals: 6,
1322
+ * },
1323
+ * validFrom: blockHeight,
1324
+ * configHashPrefix,
1325
+ * signer: senderSigner,
1326
+ * });
1327
+ * console.log(`Transfer complete: ${signature}`);
1328
+ * ```
1329
+ */
1330
+ async transfer({
1331
+ params,
1332
+ validFrom,
1333
+ configHashPrefix,
1334
+ signer
1335
+ }) {
1336
+ const tx = await this.createTransferTransaction({ params, validFrom, configHashPrefix });
1337
+ const signedTx = await tx.signWith(signer);
1338
+ const result = await this.client.sendAndConfirmTransaction(signedTx.serialize());
1339
+ return result.signature;
1340
+ }
1341
+ };
1342
+ function createSplTokenClient({
1343
+ client,
1344
+ programId
1345
+ }) {
1346
+ return new SplTokenClient({ client, programId });
1347
+ }
1348
+ /*! Bundled license information:
1349
+
1350
+ @noble/hashes/utils.js:
1351
+ (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
1352
+ */
1353
+
1354
+ export { ASSOCIATED_TOKEN_PROGRAM_ID, AccountType, ExtensionType, MINT_SIZE, SplTokenClient, SplTokenError, SplTokenErrorCode, TOKEN_2022_PROGRAM_ID, TOKEN_ACCOUNT_SIZE, TOKEN_PROGRAM_ID, TokenAccountState, TokenInstruction, createAssociatedTokenAccountIdempotentInstruction, createAssociatedTokenAccountInstruction, createSplTokenClient, findAssociatedTokenAddress, getAssociatedTokenAddressSync, getMintExtensions, initializeMintInstruction, mintToInstruction, parseMetadataPointerExtension, parseMintAccount, parseTokenAccount, parseTokenMetadata, transferCheckedInstruction, transferInstruction };
1355
+ //# sourceMappingURL=index.mjs.map
1356
+ //# sourceMappingURL=index.mjs.map