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