@buildonspark/issuer-sdk 0.0.83 → 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,12 +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 { IssuerSparkWallet } from "../../index.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";
10
12
 
11
13
  export const TOKENS_V0_SCHNORR_CONFIG: Required<ConfigOptions> = {
12
14
  ...WalletConfig.LOCAL,
@@ -46,41 +48,99 @@ describe.each(TEST_CONFIGS)(
46
48
  ({ name, config }) => {
47
49
  jest.setTimeout(80000);
48
50
 
49
- let sharedIssuerWallet: IssuerSparkWallet;
50
- let sharedUserWallet: any;
51
- let sharedTokenPublicKey: string;
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,
67
+ });
52
68
 
53
- afterEach(async () => {
54
- await new Promise((resolve) => setTimeout(resolve, 1000));
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 minting tokens without creation", async () => {
58
- const tokenAmount: bigint = 1000n;
59
- const { wallet } = await IssuerSparkWalletTesting.initialize({
60
- options: config,
61
- });
79
+ it("should announce a token", async () => {
80
+ const { wallet: issuerWallet } =
81
+ await IssuerSparkWalletTesting.initialize({
82
+ options: config,
83
+ });
62
84
 
63
- await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
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);
64
104
  });
65
105
 
66
- it("should fail when creation decimal is greater than js MAX_SAFE_INTEGER", async () => {
67
- const tokenAmount: bigint = 1000n;
68
- const { wallet } = await IssuerSparkWalletTesting.initialize({
69
- options: config,
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,
70
121
  });
71
122
 
72
123
  await expect(
73
- wallet.createToken({
74
- tokenName: "2Pow53Decimal",
75
- tokenTicker: "2P53D",
76
- decimals: 2 ** 53,
124
+ issuerWallet.createToken({
125
+ tokenName,
126
+ tokenTicker,
127
+ decimals: 0,
77
128
  isFreezable: false,
78
- maxSupply: tokenAmount,
129
+ maxSupply: 100n,
79
130
  }),
80
131
  ).rejects.toThrow();
81
132
  });
82
133
 
83
- 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 () => {
84
144
  const tokenAmount: bigint = 1000n;
85
145
  const { wallet } = await IssuerSparkWalletTesting.initialize({
86
146
  options: config,
@@ -96,7 +156,7 @@ describe.each(TEST_CONFIGS)(
96
156
  await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
97
157
  });
98
158
 
99
- it("should mint tokens successfully", async () => {
159
+ it("should create, and mint tokens successfully", async () => {
100
160
  const tokenAmount: bigint = 1000n;
101
161
 
102
162
  const { wallet: issuerWallet } =
@@ -110,12 +170,10 @@ describe.each(TEST_CONFIGS)(
110
170
  isFreezable: false,
111
171
  maxSupply: 1_000_000n,
112
172
  });
113
- sharedIssuerWallet = issuerWallet;
114
- sharedTokenPublicKey = await issuerWallet.getIdentityPublicKey();
115
173
 
116
- const tokenMetadata = await sharedIssuerWallet.getIssuerTokenMetadata();
174
+ const tokenMetadata = await issuerWallet.getIssuerTokenMetadata();
117
175
 
118
- const identityPublicKey = await sharedIssuerWallet.getIdentityPublicKey();
176
+ const identityPublicKey = await issuerWallet.getIdentityPublicKey();
119
177
  expect(tokenMetadata?.tokenName).toEqual(`${name}M`);
120
178
  expect(tokenMetadata?.tokenTicker).toEqual("MIN");
121
179
  expect(tokenMetadata?.decimals).toEqual(0);
@@ -126,13 +184,13 @@ describe.each(TEST_CONFIGS)(
126
184
  const metadataPubkey = tokenMetadata?.tokenPublicKey;
127
185
  expect(metadataPubkey).toEqual(identityPublicKey);
128
186
 
129
- await sharedIssuerWallet.mintTokens(tokenAmount);
187
+ await issuerWallet.mintTokens(tokenAmount);
130
188
 
131
- const tokenBalance = await sharedIssuerWallet.getIssuerTokenBalance();
189
+ const tokenBalance = await issuerWallet.getIssuerTokenBalance();
132
190
  expect(tokenBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
133
191
  });
134
192
 
135
- it("should mint and transfer tokens", async () => {
193
+ it("should create, mint, and transfer tokens", async () => {
136
194
  const tokenAmount: bigint = 1000n;
137
195
 
138
196
  const { wallet: issuerWallet } =
@@ -149,166 +207,25 @@ describe.each(TEST_CONFIGS)(
149
207
  isFreezable: false,
150
208
  maxSupply: 1_000_000n,
151
209
  });
152
- sharedIssuerWallet = issuerWallet;
153
- sharedUserWallet = userWallet;
154
- sharedTokenPublicKey = await issuerWallet.getIdentityPublicKey();
155
210
 
156
- await sharedIssuerWallet.mintTokens(tokenAmount);
211
+ await issuerWallet.mintTokens(tokenAmount);
157
212
 
158
- const sharedIssuerBalance =
159
- await sharedIssuerWallet.getIssuerTokenBalance();
160
- expect(sharedIssuerBalance).toBeDefined();
161
- expect(sharedIssuerBalance.tokenIdentifier).toBeDefined();
162
- await sharedIssuerWallet.transferTokens({
213
+ const tokenIdentifier = await issuerWallet.getIssuerTokenIdentifier();
214
+ await issuerWallet.transferTokens({
163
215
  tokenAmount,
164
- tokenIdentifier: sharedIssuerBalance.tokenIdentifier!,
165
- receiverSparkAddress: await sharedUserWallet.getSparkAddress(),
216
+ tokenIdentifier: tokenIdentifier!,
217
+ receiverSparkAddress: await userWallet.getSparkAddress(),
166
218
  });
167
219
 
168
- const balanceObj = await sharedUserWallet.getBalance();
169
- const destinationBalance = filterTokenBalanceForTokenPublicKey(
220
+ const balanceObj = await userWallet.getBalance();
221
+ const userBalance = filterTokenBalanceForTokenIdentifier(
170
222
  balanceObj?.tokenBalances,
171
- sharedTokenPublicKey,
223
+ tokenIdentifier!,
172
224
  );
173
- expect(destinationBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
225
+ expect(userBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
174
226
  });
175
227
 
176
- // it("should announce, mint, get list all transactions, and transfer tokens multiple times, get list all transactions again and check difference", async () => {
177
- // const tokenAmount: bigint = 100n;
178
-
179
- // const { wallet: issuerWallet } =
180
- // await IssuerSparkWalletTesting.initialize({
181
- // options: config,
182
- // });
183
-
184
- // const { wallet: destinationWallet } = await SparkWalletTesting.initialize(
185
- // {
186
- // options: config,
187
- // },
188
- // );
189
-
190
- // await fundAndAnnounce(issuerWallet, 100000n, 0, `${name}Transfer`, "TTO");
191
-
192
- // {
193
- // const transactions = await issuerWallet.getIssuerTokenActivity();
194
- // const amount_of_transactions = transactions.transactions.length;
195
- // expect(amount_of_transactions).toEqual(0);
196
- // }
197
-
198
- // await issuerWallet.mintTokens(tokenAmount);
199
-
200
- // {
201
- // const transactions = await issuerWallet.getIssuerTokenActivity();
202
- // const amount_of_transactions = transactions.transactions.length;
203
- // expect(amount_of_transactions).toEqual(1);
204
- // }
205
-
206
- // await issuerWallet.transferTokens({
207
- // tokenAmount,
208
- // tokenPublicKey: await issuerWallet.getIdentityPublicKey(),
209
- // receiverSparkAddress: await destinationWallet.getSparkAddress(),
210
- // });
211
-
212
- // {
213
- // const transactions = await issuerWallet.getIssuerTokenActivity();
214
- // const amount_of_transactions = transactions.transactions.length;
215
- // expect(amount_of_transactions).toEqual(2);
216
- // }
217
-
218
- // for (let index = 0; index < 100; ++index) {
219
- // await issuerWallet.mintTokens(tokenAmount);
220
- // await issuerWallet.transferTokens({
221
- // tokenAmount,
222
- // tokenPublicKey: await issuerWallet.getIdentityPublicKey(),
223
- // receiverSparkAddress: await destinationWallet.getSparkAddress(),
224
- // });
225
- // } // 202 in total
226
-
227
- // let all_transactions = await issuerWallet.getIssuerTokenActivity(250);
228
- // const amount_of_transactions = all_transactions.transactions.length;
229
- // expect(amount_of_transactions).toEqual(202);
230
-
231
- // {
232
- // const transactions = await issuerWallet.getIssuerTokenActivity(10);
233
- // const amount_of_transactions = transactions.transactions.length;
234
- // expect(amount_of_transactions).toEqual(10);
235
- // }
236
-
237
- // {
238
- // let hashset_of_all_transactions: Set<String> = new Set();
239
-
240
- // let transactions = await issuerWallet.getIssuerTokenActivity(10);
241
- // let amount_of_transactions = transactions.transactions.length;
242
- // expect(amount_of_transactions).toEqual(10);
243
- // let page_num = 0;
244
- // for (let index = 0; index < transactions.transactions.length; ++index) {
245
- // const element = transactions.transactions[index];
246
- // if (!(element.transaction === undefined)) {
247
- // let hash: String = "";
248
- // if (element.transaction.$case === "spark") {
249
- // hash = element.transaction.spark.transactionHash;
250
- // } else if (element.transaction.$case === "onChain") {
251
- // hash = element.transaction.onChain.transactionHash;
252
- // }
253
- // if (hashset_of_all_transactions.has(hash)) {
254
- // expect(
255
- // `Dublicate found. Pagination is broken? Index of transaction: ${index} ; page №: ${page_num} ; page size: 10 ; hash_dublicate: ${hash}`,
256
- // ).toEqual("");
257
- // } else {
258
- // hashset_of_all_transactions.add(hash);
259
- // }
260
- // } else {
261
- // expect(
262
- // `Transaction is undefined. Something is really wrong. Index of transaction: ${index} ; page №: ${page_num} ; page size: 10`,
263
- // ).toEqual("");
264
- // }
265
- // }
266
-
267
- // while (!(undefined === transactions.nextCursor)) {
268
- // let transactions_2 = await issuerWallet.getIssuerTokenActivity(10, {
269
- // lastTransactionHash: hexToBytes(
270
- // transactions.nextCursor.lastTransactionHash,
271
- // ),
272
- // layer: transactions.nextCursor.layer,
273
- // });
274
-
275
- // ++page_num;
276
-
277
- // for (
278
- // let index = 0;
279
- // index < transactions_2.transactions.length;
280
- // ++index
281
- // ) {
282
- // const element = transactions_2.transactions[index];
283
- // if (!(element.transaction === undefined)) {
284
- // let hash: String = "";
285
- // if (element.transaction.$case === "spark") {
286
- // hash = element.transaction.spark.transactionHash;
287
- // } else if (element.transaction.$case === "onChain") {
288
- // hash = element.transaction.onChain.transactionHash;
289
- // }
290
- // if (hashset_of_all_transactions.has(hash)) {
291
- // expect(
292
- // `Dublicate found. Pagination is broken? Index of transaction: ${index} ; page №: ${page_num} ; page size: 10 ; hash_dublicate: ${hash}`,
293
- // ).toEqual("");
294
- // } else {
295
- // hashset_of_all_transactions.add(hash);
296
- // }
297
- // } else {
298
- // expect(
299
- // `Transaction is undefined. Something is really wrong. Index of transaction: ${index} ; page №: ${page_num} ; page size: 10`,
300
- // ).toEqual("");
301
- // }
302
- // }
303
-
304
- // transactions = transactions_2;
305
- // }
306
-
307
- // expect(hashset_of_all_transactions.size == 202);
308
- // }
309
- // });
310
-
311
- it("should mint and batchtransfer tokens", async () => {
228
+ it("should create, mint, and batchtransfer tokens", async () => {
312
229
  const tokenAmount: bigint = 999n;
313
230
 
314
231
  const { wallet: issuerWallet } =
@@ -322,8 +239,6 @@ describe.each(TEST_CONFIGS)(
322
239
  isFreezable: false,
323
240
  maxSupply: 1_000_000n,
324
241
  });
325
- sharedIssuerWallet = issuerWallet;
326
- sharedTokenPublicKey = await issuerWallet.getIdentityPublicKey();
327
242
 
328
243
  const { wallet: destinationWallet } = await SparkWalletTesting.initialize(
329
244
  {
@@ -341,16 +256,15 @@ describe.each(TEST_CONFIGS)(
341
256
  options: config,
342
257
  });
343
258
 
344
- await sharedIssuerWallet.mintTokens(tokenAmount);
345
- const sharedIssuerBalance =
346
- await sharedIssuerWallet.getIssuerTokenBalance();
259
+ await issuerWallet.mintTokens(tokenAmount);
260
+ const sharedIssuerBalance = await issuerWallet.getIssuerTokenBalance();
347
261
  expect(sharedIssuerBalance).toBeDefined();
348
262
  expect(sharedIssuerBalance.tokenIdentifier).toBeDefined();
349
263
 
350
264
  const tokenIdentifier = sharedIssuerBalance.tokenIdentifier!;
351
265
  const sourceBalanceBefore = sharedIssuerBalance.balance;
352
266
 
353
- await sharedIssuerWallet.batchTransferTokens([
267
+ await issuerWallet.batchTransferTokens([
354
268
  {
355
269
  tokenAmount: tokenAmount / 3n,
356
270
  tokenIdentifier,
@@ -368,70 +282,267 @@ describe.each(TEST_CONFIGS)(
368
282
  },
369
283
  ]);
370
284
 
371
- const sourceBalanceAfter = (
372
- await sharedIssuerWallet.getIssuerTokenBalance()
373
- ).balance;
285
+ const sourceBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
286
+ .balance;
374
287
  expect(sourceBalanceAfter).toEqual(sourceBalanceBefore - tokenAmount);
375
288
 
376
289
  const balanceObj = await destinationWallet.getBalance();
377
- const destinationBalance = filterTokenBalanceForTokenPublicKey(
290
+ const destinationBalance = filterTokenBalanceForTokenIdentifier(
378
291
  balanceObj?.tokenBalances,
379
- sharedTokenPublicKey,
292
+ tokenIdentifier!,
380
293
  );
381
294
  expect(destinationBalance.balance).toEqual(tokenAmount / 3n);
382
295
  const balanceObj2 = await destinationWallet2.getBalance();
383
- const destinationBalance2 = filterTokenBalanceForTokenPublicKey(
296
+ const destinationBalance2 = filterTokenBalanceForTokenIdentifier(
384
297
  balanceObj2?.tokenBalances,
385
- sharedTokenPublicKey,
298
+ tokenIdentifier!,
386
299
  );
387
300
  expect(destinationBalance2.balance).toEqual(tokenAmount / 3n);
388
301
  const balanceObj3 = await destinationWallet3.getBalance();
389
- const destinationBalance3 = filterTokenBalanceForTokenPublicKey(
302
+ const destinationBalance3 = filterTokenBalanceForTokenIdentifier(
390
303
  balanceObj3?.tokenBalances,
391
- sharedTokenPublicKey,
304
+ tokenIdentifier!,
392
305
  );
393
306
  expect(destinationBalance3.balance).toEqual(tokenAmount / 3n);
394
307
  });
395
308
 
396
- // it("should track token operations in monitoring", async () => {
397
- // const tokenAmount: bigint = 1000n;
398
-
399
- // await sharedIssuerWallet.mintTokens(tokenAmount);
400
- // await sharedIssuerWallet.transferTokens({
401
- // tokenAmount,
402
- // tokenPublicKey: sharedTokenPublicKey,
403
- // receiverSparkAddress: await sharedUserWallet.getSparkAddress(),
404
- // });
405
-
406
- // const balanceObj = await sharedUserWallet.getBalance();
407
- // const destinationBalance = filterTokenBalanceForTokenPublicKey(
408
- // balanceObj?.tokenBalances,
409
- // sharedTokenPublicKey,
410
- // );
411
- // expect(destinationBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
412
-
413
- // const issuerOperations =
414
- // await sharedIssuerWallet.getIssuerTokenActivity();
415
- // expect(issuerOperations.transactions.length).toBeGreaterThanOrEqual(2);
416
-
417
- // let mint_operation = 0;
418
- // let transfer_operation = 0;
419
- // issuerOperations.transactions.forEach((transaction) => {
420
- // if (transaction.transaction?.$case === "spark") {
421
- // if (transaction.transaction.spark.operationType === "ISSUER_MINT") {
422
- // mint_operation++;
423
- // } else if (
424
- // transaction.transaction.spark.operationType === "ISSUER_TRANSFER"
425
- // ) {
426
- // transfer_operation++;
427
- // }
428
- // }
429
- // });
430
- // expect(mint_operation).toBeGreaterThanOrEqual(1);
431
- // expect(transfer_operation).toBeGreaterThanOrEqual(1);
432
- // });
433
-
434
- 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 () => {
435
546
  const tokenAmount: bigint = 1n;
436
547
  const { wallet: issuerWallet } =
437
548
  await IssuerSparkWalletTesting.initialize({
@@ -451,7 +562,7 @@ describe.each(TEST_CONFIGS)(
451
562
  expect(tokenBalance.balance).toEqual(tokenAmount);
452
563
  });
453
564
 
454
- 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 () => {
455
566
  const { wallet: issuerWallet } =
456
567
  await IssuerSparkWalletTesting.initialize({
457
568
  options: config,
@@ -466,7 +577,16 @@ describe.each(TEST_CONFIGS)(
466
577
  });
467
578
  });
468
579
 
469
- 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 () => {
470
590
  const { wallet: issuerWallet } =
471
591
  await IssuerSparkWalletTesting.initialize({
472
592
  options: config,
@@ -481,7 +601,23 @@ describe.each(TEST_CONFIGS)(
481
601
  });
482
602
  });
483
603
 
484
- 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 () => {
485
621
  const tokenAmount: bigint = 1000n;
486
622
  const { wallet: issuerWallet } =
487
623
  await IssuerSparkWalletTesting.initialize({
@@ -523,11 +659,10 @@ describe.each(TEST_CONFIGS)(
523
659
  ).balance;
524
660
  expect(issuerBalanceAfterTransfer).toEqual(0n);
525
661
 
526
- const tokenPublicKey = await issuerWallet.getIdentityPublicKey();
527
662
  const userBalanceObj = await userWallet.getBalance();
528
- const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
663
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenIdentifier(
529
664
  userBalanceObj?.tokenBalances,
530
- tokenPublicKey,
665
+ tokenIdentifier!,
531
666
  );
532
667
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
533
668
 
@@ -543,7 +678,7 @@ describe.each(TEST_CONFIGS)(
543
678
  expect(unfreezeResponse.impactedTokenAmount).toEqual(tokenAmount);
544
679
  });
545
680
 
546
- it("should mint and burn tokens", async () => {
681
+ it("should create, mint and burn tokens", async () => {
547
682
  const tokenAmount: bigint = 200n;
548
683
 
549
684
  const { wallet: issuerWallet } =
@@ -557,26 +692,23 @@ describe.each(TEST_CONFIGS)(
557
692
  isFreezable: false,
558
693
  maxSupply: 1_000_000n,
559
694
  });
560
- sharedIssuerWallet = issuerWallet;
561
- sharedTokenPublicKey = await issuerWallet.getIdentityPublicKey();
562
695
 
563
- await sharedIssuerWallet.mintTokens(tokenAmount);
564
- const issuerTokenBalance = (
565
- await sharedIssuerWallet.getIssuerTokenBalance()
566
- ).balance;
696
+ await issuerWallet.mintTokens(tokenAmount);
697
+ const issuerTokenBalance = (await issuerWallet.getIssuerTokenBalance())
698
+ .balance;
567
699
  expect(issuerTokenBalance).toBeGreaterThanOrEqual(tokenAmount);
568
700
 
569
- await sharedIssuerWallet.burnTokens(tokenAmount);
701
+ await issuerWallet.burnTokens(tokenAmount);
570
702
 
571
703
  const issuerTokenBalanceAfterBurn = (
572
- await sharedIssuerWallet.getIssuerTokenBalance()
704
+ await issuerWallet.getIssuerTokenBalance()
573
705
  ).balance;
574
706
  expect(issuerTokenBalanceAfterBurn).toEqual(
575
707
  issuerTokenBalance - tokenAmount,
576
708
  );
577
709
  });
578
710
 
579
- 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 () => {
580
712
  const tokenAmount: bigint = 1000n;
581
713
 
582
714
  const { wallet: issuerWallet } =
@@ -590,19 +722,17 @@ describe.each(TEST_CONFIGS)(
590
722
  isFreezable: false,
591
723
  maxSupply: 1_000_000n,
592
724
  });
593
- sharedIssuerWallet = issuerWallet;
594
- sharedTokenPublicKey = await issuerWallet.getIdentityPublicKey();
595
725
 
596
726
  const { wallet: userWallet } = await SparkWalletTesting.initialize({
597
727
  options: config,
598
728
  });
599
729
 
600
- const initialBalance = (await sharedIssuerWallet.getIssuerTokenBalance())
730
+ const initialBalance = (await issuerWallet.getIssuerTokenBalance())
601
731
  .balance;
602
732
 
603
- await sharedIssuerWallet.mintTokens(tokenAmount);
733
+ await issuerWallet.mintTokens(tokenAmount);
604
734
  const issuerBalanceObjAfterMint =
605
- await sharedIssuerWallet.getIssuerTokenBalance();
735
+ await issuerWallet.getIssuerTokenBalance();
606
736
  expect(issuerBalanceObjAfterMint).toBeDefined();
607
737
  const issuerBalanceAfterMint = issuerBalanceObjAfterMint.balance;
608
738
  expect(issuerBalanceAfterMint).toEqual(initialBalance + tokenAmount);
@@ -610,155 +740,84 @@ describe.each(TEST_CONFIGS)(
610
740
  const tokenIdentifier = issuerBalanceObjAfterMint.tokenIdentifier!;
611
741
  const userSparkAddress = await userWallet.getSparkAddress();
612
742
 
613
- await sharedIssuerWallet.transferTokens({
743
+ await issuerWallet.transferTokens({
614
744
  tokenAmount,
615
745
  tokenIdentifier,
616
746
  receiverSparkAddress: userSparkAddress,
617
747
  });
618
748
 
619
749
  const issuerBalanceAfterTransfer = (
620
- await sharedIssuerWallet.getIssuerTokenBalance()
750
+ await issuerWallet.getIssuerTokenBalance()
621
751
  ).balance;
622
752
  expect(issuerBalanceAfterTransfer).toEqual(initialBalance);
623
753
 
624
754
  const userBalanceObj = await userWallet.getBalance();
625
- const userBalanceAfterTransfer = filterTokenBalanceForTokenPublicKey(
755
+ const userBalanceAfterTransfer = filterTokenBalanceForTokenIdentifier(
626
756
  userBalanceObj?.tokenBalances,
627
- sharedTokenPublicKey,
757
+ tokenIdentifier!,
628
758
  );
629
759
  expect(userBalanceAfterTransfer.balance).toEqual(tokenAmount);
630
760
 
631
761
  await userWallet.transferTokens({
632
762
  tokenIdentifier,
633
763
  tokenAmount,
634
- receiverSparkAddress: await sharedIssuerWallet.getSparkAddress(),
764
+ receiverSparkAddress: await issuerWallet.getSparkAddress(),
635
765
  });
636
766
 
637
767
  const userBalanceObjAfterTransferBack = await userWallet.getBalance();
638
- const userBalanceAfterTransferBack = filterTokenBalanceForTokenPublicKey(
768
+ const userBalanceAfterTransferBack = filterTokenBalanceForTokenIdentifier(
639
769
  userBalanceObjAfterTransferBack?.tokenBalances,
640
- sharedTokenPublicKey,
770
+ tokenIdentifier!,
641
771
  );
642
772
 
643
773
  expect(userBalanceAfterTransferBack.balance).toEqual(0n);
644
774
 
645
- const issuerTokenBalance = (
646
- await sharedIssuerWallet.getIssuerTokenBalance()
647
- ).balance;
775
+ const issuerTokenBalance = (await issuerWallet.getIssuerTokenBalance())
776
+ .balance;
648
777
  expect(issuerTokenBalance).toEqual(initialBalance + tokenAmount);
649
778
 
650
- await sharedIssuerWallet.burnTokens(tokenAmount);
779
+ await issuerWallet.burnTokens(tokenAmount);
651
780
 
652
781
  const issuerTokenBalanceAfterBurn = (
653
- await sharedIssuerWallet.getIssuerTokenBalance()
782
+ await issuerWallet.getIssuerTokenBalance()
654
783
  ).balance;
655
784
  expect(issuerTokenBalanceAfterBurn).toEqual(initialBalance);
656
785
  });
657
-
658
- // it("should correctly assign operation types for complete token lifecycle operations", async () => {
659
- // const { wallet: userWallet } = await SparkWalletTesting.initialize({
660
- // options: config,
661
- // });
662
-
663
- // const tokenAmount = 1000n;
664
-
665
- // await sharedIssuerWallet.mintTokens(tokenAmount);
666
-
667
- // await sharedIssuerWallet.transferTokens({
668
- // tokenAmount: 500n,
669
- // tokenPublicKey: sharedTokenPublicKey,
670
- // receiverSparkAddress: await userWallet.getSparkAddress(),
671
- // });
672
-
673
- // await userWallet.transferTokens({
674
- // tokenPublicKey: sharedTokenPublicKey,
675
- // tokenAmount: 250n,
676
- // receiverSparkAddress: await sharedIssuerWallet.getSparkAddress(),
677
- // });
678
-
679
- // // as in userWallet we didn't have burnTokens method, we need to transfer tokens to burn address manually
680
- // const BURN_ADDRESS = "02".repeat(33);
681
- // const burnAddress = encodeSparkAddress({
682
- // identityPublicKey: BURN_ADDRESS,
683
- // network: "LOCAL",
684
- // });
685
-
686
- // await userWallet.transferTokens({
687
- // tokenPublicKey: sharedTokenPublicKey,
688
- // tokenAmount: 250n,
689
- // receiverSparkAddress: burnAddress,
690
- // });
691
-
692
- // await sharedIssuerWallet.burnTokens(250n);
693
-
694
- // const activity = await sharedIssuerWallet.getIssuerTokenActivity();
695
-
696
- // const mintTransaction = activity.transactions.find(
697
- // (tx) =>
698
- // tx.transaction?.$case === "spark" &&
699
- // tx.transaction.spark.operationType === "ISSUER_MINT",
700
- // );
701
-
702
- // const transferTransaction = activity.transactions.find(
703
- // (tx) =>
704
- // tx.transaction?.$case === "spark" &&
705
- // tx.transaction.spark.operationType === "ISSUER_TRANSFER",
706
- // );
707
-
708
- // const burnTransaction = activity.transactions.find(
709
- // (tx) =>
710
- // tx.transaction?.$case === "spark" &&
711
- // tx.transaction.spark.operationType === "ISSUER_BURN",
712
- // );
713
-
714
- // const transferBackTransaction = activity.transactions.find(
715
- // (tx) =>
716
- // tx.transaction?.$case === "spark" &&
717
- // tx.transaction.spark.operationType === "USER_TRANSFER",
718
- // );
719
-
720
- // const userBurnTransaction = activity.transactions.find(
721
- // (tx) =>
722
- // tx.transaction?.$case === "spark" &&
723
- // tx.transaction.spark.operationType === "USER_BURN",
724
- // );
725
-
726
- // expect(mintTransaction).toBeDefined();
727
- // expect(transferTransaction).toBeDefined();
728
- // expect(burnTransaction).toBeDefined();
729
- // expect(transferBackTransaction).toBeDefined();
730
- // expect(userBurnTransaction).toBeDefined();
731
- // });
732
-
733
- (config.tokenTransactionVersion === "V0" ? it.skip : it)(
734
- "should create a token using createToken API",
735
- async () => {
736
- const { wallet: issuerWallet } =
737
- await IssuerSparkWalletTesting.initialize({
738
- options: config,
739
- });
740
-
741
- const tokenName = `${name}Creatable`;
742
- const tokenTicker = "CRT";
743
- const maxSupply = 5000n;
744
- const decimals = 0;
745
- const txId = await issuerWallet.createToken({
746
- tokenName,
747
- tokenTicker,
748
- decimals,
749
- isFreezable: false,
750
- maxSupply,
751
- });
752
-
753
- expect(typeof txId).toBe("string");
754
- expect(txId.length).toBeGreaterThan(0);
755
-
756
- const metadata = await issuerWallet.getIssuerTokenMetadata();
757
- expect(metadata.tokenName).toEqual(tokenName);
758
- expect(metadata.tokenTicker).toEqual(tokenTicker);
759
- expect(metadata.maxSupply).toEqual(maxSupply);
760
- expect(metadata.decimals).toEqual(decimals);
761
- },
762
- );
763
786
  },
764
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
+ }