@buildonspark/issuer-sdk 0.0.84 → 0.0.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,14 @@
1
1
  import {
2
2
  WalletConfig,
3
3
  ConfigOptions,
4
- filterTokenBalanceForTokenPublicKey,
4
+ filterTokenBalanceForTokenIdentifier,
5
5
  } from "@buildonspark/spark-sdk";
6
6
  import { jest } from "@jest/globals";
7
7
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
8
8
  import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
9
+ import { BitcoinFaucet } from "@buildonspark/spark-sdk/test-utils";
10
+ import { bytesToHex } from "@noble/curves/abstract/utils";
11
+ import { IssuerSparkWallet } from "../../issuer-wallet/issuer-spark-wallet.node.js";
9
12
 
10
13
  export const TOKENS_V0_SCHNORR_CONFIG: Required<ConfigOptions> = {
11
14
  ...WalletConfig.LOCAL,
@@ -45,33 +48,99 @@ describe.each(TEST_CONFIGS)(
45
48
  ({ name, config }) => {
46
49
  jest.setTimeout(80000);
47
50
 
48
- it("should fail when minting tokens without creation", async () => {
49
- const tokenAmount: bigint = 1000n;
50
- const { wallet } = await IssuerSparkWalletTesting.initialize({
51
- options: config,
51
+ it("should create a token", async () => {
52
+ const { wallet: issuerWallet } =
53
+ await IssuerSparkWalletTesting.initialize({
54
+ options: config,
55
+ });
56
+
57
+ const tokenName = `${name}Creatable`;
58
+ const tokenTicker = "CRT";
59
+ const maxSupply = 5000n;
60
+ const decimals = 0;
61
+ const txId = await issuerWallet.createToken({
62
+ tokenName,
63
+ tokenTicker,
64
+ decimals,
65
+ isFreezable: false,
66
+ maxSupply,
52
67
  });
53
68
 
54
- await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
69
+ expect(typeof txId).toBe("string");
70
+ expect(txId.length).toBeGreaterThan(0);
71
+
72
+ const metadata = await issuerWallet.getIssuerTokenMetadata();
73
+ expect(metadata.tokenName).toEqual(tokenName);
74
+ expect(metadata.tokenTicker).toEqual(tokenTicker);
75
+ expect(metadata.maxSupply).toEqual(maxSupply);
76
+ expect(metadata.decimals).toEqual(decimals);
55
77
  });
56
78
 
57
- it("should fail when creation decimal is greater than js MAX_SAFE_INTEGER", async () => {
58
- const tokenAmount: bigint = 1000n;
59
- const { wallet } = await IssuerSparkWalletTesting.initialize({
60
- options: config,
79
+ it("should announce a token", async () => {
80
+ const { wallet: issuerWallet } =
81
+ await IssuerSparkWalletTesting.initialize({
82
+ options: config,
83
+ });
84
+
85
+ const tokenName = `${name}Announcable`;
86
+ const tokenTicker = "ANN";
87
+ const maxSupply = 5000n;
88
+ const decimals = 0;
89
+
90
+ await fundAndAnnounce(
91
+ issuerWallet,
92
+ 5000n,
93
+ 0,
94
+ tokenName,
95
+ tokenTicker,
96
+ false,
97
+ );
98
+
99
+ const metadata = await issuerWallet.getIssuerTokenMetadata();
100
+ expect(metadata.tokenName).toEqual(tokenName);
101
+ expect(metadata.tokenTicker).toEqual(tokenTicker);
102
+ expect(metadata.maxSupply).toEqual(maxSupply);
103
+ expect(metadata.decimals).toEqual(decimals);
104
+ });
105
+
106
+ it("should fail on duplicate token creation", async () => {
107
+ const { wallet: issuerWallet } =
108
+ await IssuerSparkWalletTesting.initialize({
109
+ options: config,
110
+ });
111
+
112
+ const tokenName = `${name}Dup`;
113
+ const tokenTicker = `DP${name}`;
114
+
115
+ await issuerWallet.createToken({
116
+ tokenName,
117
+ tokenTicker,
118
+ decimals: 0,
119
+ isFreezable: false,
120
+ maxSupply: 100n,
61
121
  });
62
122
 
63
123
  await expect(
64
- wallet.createToken({
65
- tokenName: "2Pow53Decimal",
66
- tokenTicker: "2P53D",
67
- decimals: 2 ** 53,
124
+ issuerWallet.createToken({
125
+ tokenName,
126
+ tokenTicker,
127
+ decimals: 0,
68
128
  isFreezable: false,
69
- maxSupply: tokenAmount,
129
+ maxSupply: 100n,
70
130
  }),
71
131
  ).rejects.toThrow();
72
132
  });
73
133
 
74
- it("should fail when minting more than max supply", async () => {
134
+ it("should fail when minting tokens without creation", async () => {
135
+ const tokenAmount: bigint = 1000n;
136
+ const { wallet } = await IssuerSparkWalletTesting.initialize({
137
+ options: config,
138
+ });
139
+
140
+ await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
141
+ });
142
+
143
+ it("should create, andfail when minting more than max supply", async () => {
75
144
  const tokenAmount: bigint = 1000n;
76
145
  const { wallet } = await IssuerSparkWalletTesting.initialize({
77
146
  options: config,
@@ -87,7 +156,7 @@ describe.each(TEST_CONFIGS)(
87
156
  await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
88
157
  });
89
158
 
90
- it("should mint tokens successfully", async () => {
159
+ it("should create, and mint tokens successfully", async () => {
91
160
  const tokenAmount: bigint = 1000n;
92
161
 
93
162
  const { wallet: issuerWallet } =
@@ -121,7 +190,7 @@ describe.each(TEST_CONFIGS)(
121
190
  expect(tokenBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
122
191
  });
123
192
 
124
- it("should mint and transfer tokens", async () => {
193
+ it("should create, mint, and transfer tokens", async () => {
125
194
  const tokenAmount: bigint = 1000n;
126
195
 
127
196
  const { wallet: issuerWallet } =
@@ -138,7 +207,6 @@ describe.each(TEST_CONFIGS)(
138
207
  isFreezable: false,
139
208
  maxSupply: 1_000_000n,
140
209
  });
141
- const issuerPublicKey = await issuerWallet.getIdentityPublicKey();
142
210
 
143
211
  await issuerWallet.mintTokens(tokenAmount);
144
212
 
@@ -150,149 +218,14 @@ describe.each(TEST_CONFIGS)(
150
218
  });
151
219
 
152
220
  const balanceObj = await userWallet.getBalance();
153
- const userBalance = filterTokenBalanceForTokenPublicKey(
221
+ const userBalance = filterTokenBalanceForTokenIdentifier(
154
222
  balanceObj?.tokenBalances,
155
- issuerPublicKey,
223
+ tokenIdentifier!,
156
224
  );
157
225
  expect(userBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
158
226
  });
159
227
 
160
- // it("should announce, mint, get list all transactions, and transfer tokens multiple times, get list all transactions again and check difference", async () => {
161
- // const tokenAmount: bigint = 100n;
162
-
163
- // const { wallet: issuerWallet } =
164
- // await IssuerSparkWalletTesting.initialize({
165
- // options: config,
166
- // });
167
-
168
- // const { wallet: destinationWallet } = await SparkWalletTesting.initialize(
169
- // {
170
- // options: config,
171
- // },
172
- // );
173
-
174
- // await fundAndAnnounce(issuerWallet, 100000n, 0, `${name}Transfer`, "TTO");
175
-
176
- // {
177
- // const transactions = await issuerWallet.getIssuerTokenActivity();
178
- // const amount_of_transactions = transactions.transactions.length;
179
- // expect(amount_of_transactions).toEqual(0);
180
- // }
181
-
182
- // await issuerWallet.mintTokens(tokenAmount);
183
-
184
- // {
185
- // const transactions = await issuerWallet.getIssuerTokenActivity();
186
- // const amount_of_transactions = transactions.transactions.length;
187
- // expect(amount_of_transactions).toEqual(1);
188
- // }
189
-
190
- // await issuerWallet.transferTokens({
191
- // tokenAmount,
192
- // tokenPublicKey: await issuerWallet.getIdentityPublicKey(),
193
- // receiverSparkAddress: await destinationWallet.getSparkAddress(),
194
- // });
195
-
196
- // {
197
- // const transactions = await issuerWallet.getIssuerTokenActivity();
198
- // const amount_of_transactions = transactions.transactions.length;
199
- // expect(amount_of_transactions).toEqual(2);
200
- // }
201
-
202
- // for (let index = 0; index < 100; ++index) {
203
- // await issuerWallet.mintTokens(tokenAmount);
204
- // await issuerWallet.transferTokens({
205
- // tokenAmount,
206
- // tokenPublicKey: await issuerWallet.getIdentityPublicKey(),
207
- // receiverSparkAddress: await destinationWallet.getSparkAddress(),
208
- // });
209
- // } // 202 in total
210
-
211
- // let all_transactions = await issuerWallet.getIssuerTokenActivity(250);
212
- // const amount_of_transactions = all_transactions.transactions.length;
213
- // expect(amount_of_transactions).toEqual(202);
214
-
215
- // {
216
- // const transactions = await issuerWallet.getIssuerTokenActivity(10);
217
- // const amount_of_transactions = transactions.transactions.length;
218
- // expect(amount_of_transactions).toEqual(10);
219
- // }
220
-
221
- // {
222
- // let hashset_of_all_transactions: Set<String> = new Set();
223
-
224
- // let transactions = await issuerWallet.getIssuerTokenActivity(10);
225
- // let amount_of_transactions = transactions.transactions.length;
226
- // expect(amount_of_transactions).toEqual(10);
227
- // let page_num = 0;
228
- // for (let index = 0; index < transactions.transactions.length; ++index) {
229
- // const element = transactions.transactions[index];
230
- // if (!(element.transaction === undefined)) {
231
- // let hash: String = "";
232
- // if (element.transaction.$case === "spark") {
233
- // hash = element.transaction.spark.transactionHash;
234
- // } else if (element.transaction.$case === "onChain") {
235
- // hash = element.transaction.onChain.transactionHash;
236
- // }
237
- // if (hashset_of_all_transactions.has(hash)) {
238
- // expect(
239
- // `Dublicate found. Pagination is broken? Index of transaction: ${index} ; page №: ${page_num} ; page size: 10 ; hash_dublicate: ${hash}`,
240
- // ).toEqual("");
241
- // } else {
242
- // hashset_of_all_transactions.add(hash);
243
- // }
244
- // } else {
245
- // expect(
246
- // `Transaction is undefined. Something is really wrong. Index of transaction: ${index} ; page №: ${page_num} ; page size: 10`,
247
- // ).toEqual("");
248
- // }
249
- // }
250
-
251
- // while (!(undefined === transactions.nextCursor)) {
252
- // let transactions_2 = await issuerWallet.getIssuerTokenActivity(10, {
253
- // lastTransactionHash: hexToBytes(
254
- // transactions.nextCursor.lastTransactionHash,
255
- // ),
256
- // layer: transactions.nextCursor.layer,
257
- // });
258
-
259
- // ++page_num;
260
-
261
- // for (
262
- // let index = 0;
263
- // index < transactions_2.transactions.length;
264
- // ++index
265
- // ) {
266
- // const element = transactions_2.transactions[index];
267
- // if (!(element.transaction === undefined)) {
268
- // let hash: String = "";
269
- // if (element.transaction.$case === "spark") {
270
- // hash = element.transaction.spark.transactionHash;
271
- // } else if (element.transaction.$case === "onChain") {
272
- // hash = element.transaction.onChain.transactionHash;
273
- // }
274
- // if (hashset_of_all_transactions.has(hash)) {
275
- // expect(
276
- // `Dublicate found. Pagination is broken? Index of transaction: ${index} ; page №: ${page_num} ; page size: 10 ; hash_dublicate: ${hash}`,
277
- // ).toEqual("");
278
- // } else {
279
- // hashset_of_all_transactions.add(hash);
280
- // }
281
- // } else {
282
- // expect(
283
- // `Transaction is undefined. Something is really wrong. Index of transaction: ${index} ; page №: ${page_num} ; page size: 10`,
284
- // ).toEqual("");
285
- // }
286
- // }
287
-
288
- // transactions = transactions_2;
289
- // }
290
-
291
- // expect(hashset_of_all_transactions.size == 202);
292
- // }
293
- // });
294
-
295
- it("should mint and batchtransfer tokens", async () => {
228
+ it("should create, mint, and batchtransfer tokens", async () => {
296
229
  const tokenAmount: bigint = 999n;
297
230
 
298
231
  const { wallet: issuerWallet } =
@@ -307,8 +240,6 @@ describe.each(TEST_CONFIGS)(
307
240
  maxSupply: 1_000_000n,
308
241
  });
309
242
 
310
- const issuerPublicKey = await issuerWallet.getIdentityPublicKey();
311
-
312
243
  const { wallet: destinationWallet } = await SparkWalletTesting.initialize(
313
244
  {
314
245
  options: config,
@@ -356,64 +287,262 @@ describe.each(TEST_CONFIGS)(
356
287
  expect(sourceBalanceAfter).toEqual(sourceBalanceBefore - tokenAmount);
357
288
 
358
289
  const balanceObj = await destinationWallet.getBalance();
359
- const destinationBalance = filterTokenBalanceForTokenPublicKey(
290
+ const destinationBalance = filterTokenBalanceForTokenIdentifier(
360
291
  balanceObj?.tokenBalances,
361
- issuerPublicKey,
292
+ tokenIdentifier!,
362
293
  );
363
294
  expect(destinationBalance.balance).toEqual(tokenAmount / 3n);
364
295
  const balanceObj2 = await destinationWallet2.getBalance();
365
- const destinationBalance2 = filterTokenBalanceForTokenPublicKey(
296
+ const destinationBalance2 = filterTokenBalanceForTokenIdentifier(
366
297
  balanceObj2?.tokenBalances,
367
- issuerPublicKey,
298
+ tokenIdentifier!,
368
299
  );
369
300
  expect(destinationBalance2.balance).toEqual(tokenAmount / 3n);
370
301
  const balanceObj3 = await destinationWallet3.getBalance();
371
- const destinationBalance3 = filterTokenBalanceForTokenPublicKey(
302
+ const destinationBalance3 = filterTokenBalanceForTokenIdentifier(
372
303
  balanceObj3?.tokenBalances,
373
- issuerPublicKey,
304
+ tokenIdentifier!,
374
305
  );
375
306
  expect(destinationBalance3.balance).toEqual(tokenAmount / 3n);
376
307
  });
377
308
 
378
- // it("should track token operations in monitoring", async () => {
379
- // const tokenAmount: bigint = 1000n;
380
-
381
- // await sharedIssuerWallet.mintTokens(tokenAmount);
382
- // await sharedIssuerWallet.transferTokens({
383
- // tokenAmount,
384
- // tokenPublicKey: sharedTokenPublicKey,
385
- // receiverSparkAddress: await sharedUserWallet.getSparkAddress(),
386
- // });
387
-
388
- // const balanceObj = await sharedUserWallet.getBalance();
389
- // const destinationBalance = filterTokenBalanceForTokenPublicKey(
390
- // balanceObj?.tokenBalances,
391
- // sharedTokenPublicKey,
392
- // );
393
- // expect(destinationBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
394
-
395
- // const issuerOperations =
396
- // await sharedIssuerWallet.getIssuerTokenActivity();
397
- // expect(issuerOperations.transactions.length).toBeGreaterThanOrEqual(2);
398
-
399
- // let mint_operation = 0;
400
- // let transfer_operation = 0;
401
- // issuerOperations.transactions.forEach((transaction) => {
402
- // if (transaction.transaction?.$case === "spark") {
403
- // if (transaction.transaction.spark.operationType === "ISSUER_MINT") {
404
- // mint_operation++;
405
- // } else if (
406
- // transaction.transaction.spark.operationType === "ISSUER_TRANSFER"
407
- // ) {
408
- // transfer_operation++;
409
- // }
410
- // }
411
- // });
412
- // expect(mint_operation).toBeGreaterThanOrEqual(1);
413
- // expect(transfer_operation).toBeGreaterThanOrEqual(1);
414
- // });
415
-
416
- it("it should mint token with 1 max supply without issue", async () => {
309
+ it("should track token operations in monitoring", async () => {
310
+ const tokenAmount: bigint = 1000n;
311
+
312
+ const { wallet: issuerWallet } =
313
+ await IssuerSparkWalletTesting.initialize({
314
+ options: config,
315
+ });
316
+
317
+ const { wallet: userWallet } = await SparkWalletTesting.initialize({
318
+ options: config,
319
+ });
320
+
321
+ await issuerWallet.createToken({
322
+ tokenName: `${name}FRZ`,
323
+ tokenTicker: "FRZ",
324
+ decimals: 0,
325
+ isFreezable: true,
326
+ maxSupply: 100000n,
327
+ });
328
+ await issuerWallet.mintTokens(tokenAmount);
329
+ const tokenIdentifier = await issuerWallet.getIssuerTokenIdentifier();
330
+ const issuerPublicKey = await issuerWallet.getIdentityPublicKey();
331
+
332
+ await issuerWallet.transferTokens({
333
+ tokenAmount,
334
+ tokenIdentifier: tokenIdentifier!,
335
+ receiverSparkAddress: await userWallet.getSparkAddress(),
336
+ });
337
+
338
+ const userBalanceObj = await userWallet.getBalance();
339
+ const userBalance = filterTokenBalanceForTokenIdentifier(
340
+ userBalanceObj?.tokenBalances,
341
+ tokenIdentifier!,
342
+ );
343
+ expect(userBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
344
+
345
+ const transactions = await issuerWallet.queryTokenTransactions({
346
+ tokenIdentifiers: [tokenIdentifier!],
347
+ ownerPublicKeys: [issuerPublicKey],
348
+ });
349
+ expect(transactions.length).toBeGreaterThanOrEqual(2);
350
+
351
+ let mint_operation = 0;
352
+ let transfer_operation = 0;
353
+ transactions.forEach((transaction) => {
354
+ if (transaction.tokenTransaction?.tokenInputs?.$case === "mintInput") {
355
+ mint_operation++;
356
+ } else if (
357
+ transaction.tokenTransaction?.tokenInputs?.$case === "transferInput"
358
+ ) {
359
+ transfer_operation++;
360
+ }
361
+ });
362
+ expect(mint_operation).toBeGreaterThanOrEqual(1);
363
+ expect(transfer_operation).toBeGreaterThanOrEqual(1);
364
+ });
365
+
366
+ it("should correctly assign operation types for complete token lifecycle operations", async () => {
367
+ const tokenAmount = 1000n;
368
+
369
+ const { wallet: issuerWallet } =
370
+ await IssuerSparkWalletTesting.initialize({
371
+ options: config,
372
+ });
373
+
374
+ const { wallet: userWallet } = await SparkWalletTesting.initialize({
375
+ options: config,
376
+ });
377
+
378
+ await issuerWallet.createToken({
379
+ tokenName: `${name}LFC`,
380
+ tokenTicker: "LFC",
381
+ decimals: 0,
382
+ isFreezable: false,
383
+ maxSupply: 1_000_000n,
384
+ });
385
+
386
+ await issuerWallet.mintTokens(tokenAmount);
387
+
388
+ const tokenIdentifier = await issuerWallet.getIssuerTokenIdentifier();
389
+ const issuerPublicKey = await issuerWallet.getIdentityPublicKey();
390
+
391
+ await issuerWallet.transferTokens({
392
+ tokenAmount: 500n,
393
+ tokenIdentifier: tokenIdentifier!,
394
+ receiverSparkAddress: await userWallet.getSparkAddress(),
395
+ });
396
+
397
+ await userWallet.transferTokens({
398
+ tokenAmount: 250n,
399
+ tokenIdentifier: tokenIdentifier!,
400
+ receiverSparkAddress: await issuerWallet.getSparkAddress(),
401
+ });
402
+
403
+ const BURN_ADDRESS = "02".repeat(33);
404
+
405
+ await issuerWallet.burnTokens(250n);
406
+
407
+ const transactions = await issuerWallet.queryTokenTransactions({
408
+ tokenIdentifiers: [tokenIdentifier!],
409
+ ownerPublicKeys: [issuerPublicKey],
410
+ });
411
+
412
+ const mintTransaction = transactions.find(
413
+ (tx) => tx.tokenTransaction?.tokenInputs?.$case === "mintInput",
414
+ );
415
+
416
+ const transferTransaction = transactions.find(
417
+ (tx) => tx.tokenTransaction?.tokenInputs?.$case === "transferInput",
418
+ );
419
+
420
+ const burnTransaction = transactions.find(
421
+ (tx) =>
422
+ tx.tokenTransaction?.tokenInputs?.$case === "transferInput" &&
423
+ bytesToHex(tx.tokenTransaction?.tokenOutputs?.[0]?.ownerPublicKey) ===
424
+ BURN_ADDRESS,
425
+ );
426
+
427
+ expect(mintTransaction).toBeDefined();
428
+ expect(transferTransaction).toBeDefined();
429
+ expect(burnTransaction).toBeDefined();
430
+ });
431
+
432
+ it("should create, mint, get all transactions, transfer tokens multiple times, get all transactions again, and check difference", async () => {
433
+ const tokenAmount: bigint = 100n;
434
+
435
+ const { wallet: issuerWallet } =
436
+ await IssuerSparkWalletTesting.initialize({
437
+ options: config,
438
+ });
439
+
440
+ const { wallet: userWallet } = await SparkWalletTesting.initialize({
441
+ options: config,
442
+ });
443
+
444
+ await issuerWallet.createToken({
445
+ tokenName: `${name}Transfer`,
446
+ tokenTicker: "TTO",
447
+ decimals: 0,
448
+ isFreezable: false,
449
+ maxSupply: 100000n,
450
+ });
451
+
452
+ const tokenIdentifier = await issuerWallet.getIssuerTokenIdentifier();
453
+
454
+ await issuerWallet.mintTokens(tokenAmount);
455
+
456
+ {
457
+ const transactions = await issuerWallet.queryTokenTransactions({
458
+ tokenIdentifiers: [tokenIdentifier!],
459
+ });
460
+ const amount_of_transactions = transactions.length;
461
+ expect(amount_of_transactions).toEqual(1);
462
+ }
463
+
464
+ await issuerWallet.transferTokens({
465
+ tokenAmount,
466
+ tokenIdentifier: tokenIdentifier!,
467
+ receiverSparkAddress: await userWallet.getSparkAddress(),
468
+ });
469
+
470
+ {
471
+ const transactions = await issuerWallet.queryTokenTransactions({
472
+ tokenIdentifiers: [tokenIdentifier!],
473
+ });
474
+ const amount_of_transactions = transactions.length;
475
+ expect(amount_of_transactions).toEqual(2);
476
+ }
477
+
478
+ for (let index = 0; index < 100; ++index) {
479
+ await issuerWallet.mintTokens(tokenAmount);
480
+ await issuerWallet.transferTokens({
481
+ tokenAmount,
482
+ tokenIdentifier: tokenIdentifier!,
483
+ receiverSparkAddress: await userWallet.getSparkAddress(),
484
+ });
485
+ } // 202 in total
486
+
487
+ {
488
+ const transactions = await issuerWallet.queryTokenTransactions({
489
+ tokenIdentifiers: [tokenIdentifier!],
490
+ pageSize: 10,
491
+ });
492
+ const amount_of_transactions = transactions.length;
493
+ expect(amount_of_transactions).toEqual(10);
494
+ }
495
+
496
+ {
497
+ let hashset_of_all_transactions: Set<String> = new Set();
498
+
499
+ let pageSize = 10;
500
+ let offset = 0;
501
+ let page_num = 0;
502
+
503
+ while (true) {
504
+ const transactionsPage = await issuerWallet.queryTokenTransactions({
505
+ tokenIdentifiers: [tokenIdentifier!],
506
+ pageSize,
507
+ offset,
508
+ });
509
+
510
+ if (transactionsPage.length === 0) {
511
+ break;
512
+ }
513
+
514
+ if (offset === 0) {
515
+ expect(transactionsPage.length).toEqual(pageSize);
516
+ }
517
+
518
+ for (let index = 0; index < transactionsPage.length; ++index) {
519
+ const element = transactionsPage[index];
520
+ if (element.tokenTransaction !== undefined) {
521
+ const hash: String = bytesToHex(element.tokenTransactionHash);
522
+ if (hashset_of_all_transactions.has(hash)) {
523
+ expect(
524
+ `Duplicate found. Pagination is broken? Index of transaction: ${index} ; page №: ${page_num} ; page size: ${pageSize} ; hash_duplicate: ${hash}`,
525
+ ).toEqual("");
526
+ } else {
527
+ hashset_of_all_transactions.add(hash);
528
+ }
529
+ } else {
530
+ expect(
531
+ `Transaction is undefined. Something is really wrong. Index of transaction: ${index} ; page №: ${page_num} ; page size: ${pageSize}`,
532
+ ).toEqual("");
533
+ }
534
+ }
535
+
536
+ // Prepare for next iteration.
537
+ offset += transactionsPage.length;
538
+ page_num += 1;
539
+ }
540
+
541
+ expect(hashset_of_all_transactions.size).toEqual(202);
542
+ }
543
+ });
544
+
545
+ it("should mint token with 1 max supply without issue", async () => {
417
546
  const tokenAmount: bigint = 1n;
418
547
  const { wallet: issuerWallet } =
419
548
  await IssuerSparkWalletTesting.initialize({
@@ -433,7 +562,7 @@ describe.each(TEST_CONFIGS)(
433
562
  expect(tokenBalance.balance).toEqual(tokenAmount);
434
563
  });
435
564
 
436
- it("it should be able to create a token with name of size equal to MAX_SYMBOL_SIZE", async () => {
565
+ it("should be able to create a token with name of size equal to MAX_SYMBOL_SIZE", async () => {
437
566
  const { wallet: issuerWallet } =
438
567
  await IssuerSparkWalletTesting.initialize({
439
568
  options: config,
@@ -448,7 +577,16 @@ describe.each(TEST_CONFIGS)(
448
577
  });
449
578
  });
450
579
 
451
- it("it should be able to create a token with symbol of size equal to MAX_NAME_SIZE", async () => {
580
+ it("should be able to anounce a token with name of size equal to MAX_SYMBOL_SIZE", async () => {
581
+ const { wallet: issuerWallet } =
582
+ await IssuerSparkWalletTesting.initialize({
583
+ options: config,
584
+ });
585
+
586
+ await fundAndAnnounce(issuerWallet, 100000n, 0, "MST", "TESTAA", false);
587
+ });
588
+
589
+ it("should be able to create a token with symbol of size equal to MAX_NAME_SIZE", async () => {
452
590
  const { wallet: issuerWallet } =
453
591
  await IssuerSparkWalletTesting.initialize({
454
592
  options: config,
@@ -463,7 +601,23 @@ describe.each(TEST_CONFIGS)(
463
601
  });
464
602
  });
465
603
 
466
- it("should create, mint, freeze and unfreeze tokens", async () => {
604
+ it("should be able to announce a token with symbol of size equal to MAX_NAME_SIZE", async () => {
605
+ const { wallet: issuerWallet } =
606
+ await IssuerSparkWalletTesting.initialize({
607
+ options: config,
608
+ });
609
+
610
+ await fundAndAnnounce(
611
+ issuerWallet,
612
+ 100000n,
613
+ 0,
614
+ "ABCDEFGHIJKLMNOPQ",
615
+ "MQS",
616
+ false,
617
+ );
618
+ });
619
+
620
+ it("should create, mint, freeze, and unfreeze tokens", async () => {
467
621
  const tokenAmount: bigint = 1000n;
468
622
  const { wallet: issuerWallet } =
469
623
  await IssuerSparkWalletTesting.initialize({
@@ -505,11 +659,10 @@ describe.each(TEST_CONFIGS)(
505
659
  ).balance;
506
660
  expect(issuerBalanceAfterTransfer).toEqual(0n);
507
661
 
508
- const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
509
662
  const userBalanceObj = await userWallet.getBalance();
510
- const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
663
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenIdentifier(
511
664
  userBalanceObj?.tokenBalances,
512
- tokenPublicKey,
665
+ tokenIdentifier!,
513
666
  );
514
667
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
515
668
 
@@ -525,7 +678,7 @@ describe.each(TEST_CONFIGS)(
525
678
  expect(unfreezeResponse.impactedTokenAmount).toEqual(tokenAmount);
526
679
  });
527
680
 
528
- it("should mint and burn tokens", async () => {
681
+ it("should create, mint and burn tokens", async () => {
529
682
  const tokenAmount: bigint = 200n;
530
683
 
531
684
  const { wallet: issuerWallet } =
@@ -555,7 +708,7 @@ describe.each(TEST_CONFIGS)(
555
708
  );
556
709
  });
557
710
 
558
- it("should complete full token lifecycle: create, mint, transfer, return, burn", async () => {
711
+ it("should complete a full token lifecycle - create, mint, transfer, return, burn", async () => {
559
712
  const tokenAmount: bigint = 1000n;
560
713
 
561
714
  const { wallet: issuerWallet } =
@@ -569,7 +722,6 @@ describe.each(TEST_CONFIGS)(
569
722
  isFreezable: false,
570
723
  maxSupply: 1_000_000n,
571
724
  });
572
- const issuerPublicKey = await issuerWallet.getIdentityPublicKey();
573
725
 
574
726
  const { wallet: userWallet } = await SparkWalletTesting.initialize({
575
727
  options: config,
@@ -600,9 +752,9 @@ describe.each(TEST_CONFIGS)(
600
752
  expect(issuerBalanceAfterTransfer).toEqual(initialBalance);
601
753
 
602
754
  const userBalanceObj = await userWallet.getBalance();
603
- const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
755
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenIdentifier(
604
756
  userBalanceObj?.tokenBalances,
605
- issuerPublicKey,
757
+ tokenIdentifier!,
606
758
  );
607
759
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
608
760
 
@@ -613,9 +765,9 @@ describe.each(TEST_CONFIGS)(
613
765
  });
614
766
 
615
767
  const userBalanceObjAfterTransferBack = await userWallet.getBalance();
616
- const userBalanceAfterTransferBack = filterTokenBalanceForTokenPublicKey(
768
+ const userBalanceAfterTransferBack = filterTokenBalanceForTokenIdentifier(
617
769
  userBalanceObjAfterTransferBack?.tokenBalances,
618
- issuerPublicKey,
770
+ tokenIdentifier!,
619
771
  );
620
772
 
621
773
  expect(userBalanceAfterTransferBack.balance).toEqual(0n);
@@ -631,111 +783,41 @@ describe.each(TEST_CONFIGS)(
631
783
  ).balance;
632
784
  expect(issuerTokenBalanceAfterBurn).toEqual(initialBalance);
633
785
  });
634
-
635
- // it("should correctly assign operation types for complete token lifecycle operations", async () => {
636
- // const { wallet: userWallet } = await SparkWalletTesting.initialize({
637
- // options: config,
638
- // });
639
-
640
- // const tokenAmount = 1000n;
641
-
642
- // await sharedIssuerWallet.mintTokens(tokenAmount);
643
-
644
- // await sharedIssuerWallet.transferTokens({
645
- // tokenAmount: 500n,
646
- // tokenPublicKey: sharedTokenPublicKey,
647
- // receiverSparkAddress: await userWallet.getSparkAddress(),
648
- // });
649
-
650
- // await userWallet.transferTokens({
651
- // tokenPublicKey: sharedTokenPublicKey,
652
- // tokenAmount: 250n,
653
- // receiverSparkAddress: await sharedIssuerWallet.getSparkAddress(),
654
- // });
655
-
656
- // // as in userWallet we didn't have burnTokens method, we need to transfer tokens to burn address manually
657
- // const BURN_ADDRESS = "02".repeat(33);
658
- // const burnAddress = encodeSparkAddress({
659
- // identityPublicKey: BURN_ADDRESS,
660
- // network: "LOCAL",
661
- // });
662
-
663
- // await userWallet.transferTokens({
664
- // tokenPublicKey: sharedTokenPublicKey,
665
- // tokenAmount: 250n,
666
- // receiverSparkAddress: burnAddress,
667
- // });
668
-
669
- // await sharedIssuerWallet.burnTokens(250n);
670
-
671
- // const activity = await sharedIssuerWallet.getIssuerTokenActivity();
672
-
673
- // const mintTransaction = activity.transactions.find(
674
- // (tx) =>
675
- // tx.transaction?.$case === "spark" &&
676
- // tx.transaction.spark.operationType === "ISSUER_MINT",
677
- // );
678
-
679
- // const transferTransaction = activity.transactions.find(
680
- // (tx) =>
681
- // tx.transaction?.$case === "spark" &&
682
- // tx.transaction.spark.operationType === "ISSUER_TRANSFER",
683
- // );
684
-
685
- // const burnTransaction = activity.transactions.find(
686
- // (tx) =>
687
- // tx.transaction?.$case === "spark" &&
688
- // tx.transaction.spark.operationType === "ISSUER_BURN",
689
- // );
690
-
691
- // const transferBackTransaction = activity.transactions.find(
692
- // (tx) =>
693
- // tx.transaction?.$case === "spark" &&
694
- // tx.transaction.spark.operationType === "USER_TRANSFER",
695
- // );
696
-
697
- // const userBurnTransaction = activity.transactions.find(
698
- // (tx) =>
699
- // tx.transaction?.$case === "spark" &&
700
- // tx.transaction.spark.operationType === "USER_BURN",
701
- // );
702
-
703
- // expect(mintTransaction).toBeDefined();
704
- // expect(transferTransaction).toBeDefined();
705
- // expect(burnTransaction).toBeDefined();
706
- // expect(transferBackTransaction).toBeDefined();
707
- // expect(userBurnTransaction).toBeDefined();
708
- // });
709
-
710
- (config.tokenTransactionVersion === "V0" ? it.skip : it)(
711
- "should create a token using createToken API",
712
- async () => {
713
- const { wallet: issuerWallet } =
714
- await IssuerSparkWalletTesting.initialize({
715
- options: config,
716
- });
717
-
718
- const tokenName = `${name}Creatable`;
719
- const tokenTicker = "CRT";
720
- const maxSupply = 5000n;
721
- const decimals = 0;
722
- const txId = await issuerWallet.createToken({
723
- tokenName,
724
- tokenTicker,
725
- decimals,
726
- isFreezable: false,
727
- maxSupply,
728
- });
729
-
730
- expect(typeof txId).toBe("string");
731
- expect(txId.length).toBeGreaterThan(0);
732
-
733
- const metadata = await issuerWallet.getIssuerTokenMetadata();
734
- expect(metadata.tokenName).toEqual(tokenName);
735
- expect(metadata.tokenTicker).toEqual(tokenTicker);
736
- expect(metadata.maxSupply).toEqual(maxSupply);
737
- expect(metadata.decimals).toEqual(decimals);
738
- },
739
- );
740
786
  },
741
787
  );
788
+
789
+ async function fundAndAnnounce(
790
+ wallet: IssuerSparkWallet,
791
+ maxSupply: bigint = 100000n,
792
+ decimals: number = 0,
793
+ tokenName: string = "TestToken1",
794
+ tokenSymbol: string = "TT1",
795
+ isFreezable: boolean = false,
796
+ ) {
797
+ // Faucet funds to the Issuer wallet because announcing a token
798
+ // requires ownership of an L1 UTXO.
799
+ const faucet = BitcoinFaucet.getInstance();
800
+ const l1WalletPubKey = await wallet.getTokenL1Address();
801
+ await faucet.sendToAddress(l1WalletPubKey, 100_000n);
802
+ await faucet.mineBlocks(6);
803
+
804
+ await new Promise((resolve) => setTimeout(resolve, 3000));
805
+
806
+ try {
807
+ const response = await wallet.announceTokenL1(
808
+ tokenName,
809
+ tokenSymbol,
810
+ decimals,
811
+ maxSupply,
812
+ isFreezable,
813
+ );
814
+ console.log("Announce token response:", response);
815
+ } catch (error: any) {
816
+ console.error("Error when announcing token on L1:", error);
817
+ throw error;
818
+ }
819
+ await faucet.mineBlocks(2);
820
+
821
+ const SECONDS = 1000;
822
+ await new Promise((resolve) => setTimeout(resolve, 3 * SECONDS));
823
+ }