@buildonspark/issuer-sdk 0.0.86 → 0.0.88

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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @buildonspark/issuer-sdk
2
2
 
3
+ ## 0.0.88
4
+
5
+ ### Patch Changes
6
+
7
+ - -- return offset from queryTokenTransactions
8
+ - Updated dependencies
9
+ - @buildonspark/spark-sdk@0.2.9
10
+
11
+ ## 0.0.87
12
+
13
+ ### Patch Changes
14
+
15
+ - -- Added spark invoice support for token transfers
16
+ -- Added support for initialization SparkWallet with pre-existing keys
17
+ -- Return bare info in x-client-env
18
+ -- Improved test coverage for multiple coordinators
19
+ -- Improved retry mechanism for transfer claim
20
+ -- Improved error handling for alreaday exists
21
+ - Updated dependencies
22
+ - @buildonspark/spark-sdk@0.2.8
23
+
3
24
  ## 0.0.86
4
25
 
5
26
  ### Patch Changes
@@ -177,7 +177,7 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
177
177
  }
178
178
  async constructMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
179
179
  return {
180
- version: 1,
180
+ version: 2,
181
181
  network: this.config.getNetworkProto(),
182
182
  tokenInputs: {
183
183
  $case: "mintInput",
@@ -195,12 +195,13 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
195
195
  ],
196
196
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
197
197
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
198
- expiryTime: void 0
198
+ expiryTime: void 0,
199
+ invoiceAttachments: []
199
200
  };
200
201
  }
201
202
  async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
202
203
  return {
203
- version: 1,
204
+ version: 2,
204
205
  network: this.config.getNetworkProto(),
205
206
  tokenInputs: {
206
207
  $case: "createInput",
@@ -216,7 +217,8 @@ var IssuerTokenTransactionService = class extends TokenTransactionService {
216
217
  tokenOutputs: [],
217
218
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
218
219
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
219
- expiryTime: void 0
220
+ expiryTime: void 0,
221
+ invoiceAttachments: []
220
222
  };
221
223
  }
222
224
  };
@@ -315,6 +317,12 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends SparkWallet {
315
317
  }) {
316
318
  const wallet = new _IssuerSparkWallet(options, signer);
317
319
  wallet.initializeTracer(wallet);
320
+ if (options && options.signerWithPreExistingKeys) {
321
+ await wallet.initWalletWithoutSeed();
322
+ return {
323
+ wallet
324
+ };
325
+ }
318
326
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
319
327
  return {
320
328
  wallet,
package/dist/index.cjs CHANGED
@@ -199,7 +199,7 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
199
199
  }
200
200
  async constructMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
201
201
  return {
202
- version: 1,
202
+ version: 2,
203
203
  network: this.config.getNetworkProto(),
204
204
  tokenInputs: {
205
205
  $case: "mintInput",
@@ -217,12 +217,13 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
217
217
  ],
218
218
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
219
219
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
220
- expiryTime: void 0
220
+ expiryTime: void 0,
221
+ invoiceAttachments: []
221
222
  };
222
223
  }
223
224
  async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
224
225
  return {
225
- version: 1,
226
+ version: 2,
226
227
  network: this.config.getNetworkProto(),
227
228
  tokenInputs: {
228
229
  $case: "createInput",
@@ -238,7 +239,8 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
238
239
  tokenOutputs: [],
239
240
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
240
241
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
241
- expiryTime: void 0
242
+ expiryTime: void 0,
243
+ invoiceAttachments: []
242
244
  };
243
245
  }
244
246
  };
@@ -335,6 +337,12 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk5.Spark
335
337
  }) {
336
338
  const wallet = new _IssuerSparkWallet(options, signer);
337
339
  wallet.initializeTracer(wallet);
340
+ if (options && options.signerWithPreExistingKeys) {
341
+ await wallet.initWalletWithoutSeed();
342
+ return {
343
+ wallet
344
+ };
345
+ }
338
346
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
339
347
  return {
340
348
  wallet,
@@ -636,6 +644,12 @@ var IssuerSparkWalletBrowser = class _IssuerSparkWalletBrowser extends IssuerSpa
636
644
  }) {
637
645
  const wallet = new _IssuerSparkWalletBrowser(options, signer);
638
646
  wallet.initializeTracer(wallet);
647
+ if (options && options.signerWithPreExistingKeys) {
648
+ await wallet.initWalletWithoutSeed();
649
+ return {
650
+ wallet
651
+ };
652
+ }
639
653
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
640
654
  return {
641
655
  wallet,
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IssuerSparkWallet
3
- } from "./chunk-NRKE2XKD.js";
3
+ } from "./chunk-ZMLVOUPB.js";
4
4
  import "./chunk-7B4B24XF.js";
5
5
 
6
6
  // src/issuer-wallet/issuer-spark-wallet.browser.ts
@@ -16,6 +16,12 @@ var IssuerSparkWalletBrowser = class _IssuerSparkWalletBrowser extends IssuerSpa
16
16
  }) {
17
17
  const wallet = new _IssuerSparkWalletBrowser(options, signer);
18
18
  wallet.initializeTracer(wallet);
19
+ if (options && options.signerWithPreExistingKeys) {
20
+ await wallet.initWalletWithoutSeed();
21
+ return {
22
+ wallet
23
+ };
24
+ }
19
25
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
20
26
  return {
21
27
  wallet,
@@ -199,7 +199,7 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
199
199
  }
200
200
  async constructMintTokenTransaction(rawTokenIdentifierBytes, issuerTokenPublicKey, tokenAmount) {
201
201
  return {
202
- version: 1,
202
+ version: 2,
203
203
  network: this.config.getNetworkProto(),
204
204
  tokenInputs: {
205
205
  $case: "mintInput",
@@ -217,12 +217,13 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
217
217
  ],
218
218
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
219
219
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
220
- expiryTime: void 0
220
+ expiryTime: void 0,
221
+ invoiceAttachments: []
221
222
  };
222
223
  }
223
224
  async constructCreateTokenTransaction(tokenPublicKey, tokenName, tokenTicker, decimals, maxSupply, isFreezable) {
224
225
  return {
225
- version: 1,
226
+ version: 2,
226
227
  network: this.config.getNetworkProto(),
227
228
  tokenInputs: {
228
229
  $case: "createInput",
@@ -238,7 +239,8 @@ var IssuerTokenTransactionService = class extends import_spark_sdk3.TokenTransac
238
239
  tokenOutputs: [],
239
240
  clientCreatedTimestamp: /* @__PURE__ */ new Date(),
240
241
  sparkOperatorIdentityPublicKeys: super.collectOperatorIdentityPublicKeys(),
241
- expiryTime: void 0
242
+ expiryTime: void 0,
243
+ invoiceAttachments: []
242
244
  };
243
245
  }
244
246
  };
@@ -335,6 +337,12 @@ var IssuerSparkWallet = class _IssuerSparkWallet extends import_spark_sdk5.Spark
335
337
  }) {
336
338
  const wallet = new _IssuerSparkWallet(options, signer);
337
339
  wallet.initializeTracer(wallet);
340
+ if (options && options.signerWithPreExistingKeys) {
341
+ await wallet.initWalletWithoutSeed();
342
+ return {
343
+ wallet
344
+ };
345
+ }
338
346
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
339
347
  return {
340
348
  wallet,
@@ -636,6 +644,12 @@ var IssuerSparkWalletNodeJS = class _IssuerSparkWalletNodeJS extends IssuerSpark
636
644
  }) {
637
645
  const wallet = new _IssuerSparkWalletNodeJS(options, signer);
638
646
  wallet.initializeTracer(wallet);
647
+ if (options && options.signerWithPreExistingKeys) {
648
+ await wallet.initWalletWithoutSeed();
649
+ return {
650
+ wallet
651
+ };
652
+ }
639
653
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
640
654
  return {
641
655
  wallet,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IssuerSparkWallet
3
- } from "./chunk-NRKE2XKD.js";
3
+ } from "./chunk-ZMLVOUPB.js";
4
4
  import "./chunk-7B4B24XF.js";
5
5
 
6
6
  // src/issuer-wallet/issuer-spark-wallet.node.ts
@@ -16,6 +16,12 @@ var IssuerSparkWalletNodeJS = class _IssuerSparkWalletNodeJS extends IssuerSpark
16
16
  }) {
17
17
  const wallet = new _IssuerSparkWalletNodeJS(options, signer);
18
18
  wallet.initializeTracer(wallet);
19
+ if (options && options.signerWithPreExistingKeys) {
20
+ await wallet.initWalletWithoutSeed();
21
+ return {
22
+ wallet
23
+ };
24
+ }
19
25
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
20
26
  return {
21
27
  wallet,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildonspark/issuer-sdk",
3
- "version": "0.0.86",
3
+ "version": "0.0.88",
4
4
  "description": "Spark Issuer SDK for token issuance",
5
5
  "license": "Apache-2.0",
6
6
  "module": "./dist/index.js",
@@ -72,12 +72,10 @@
72
72
  "types": "tsc"
73
73
  },
74
74
  "dependencies": {
75
- "@buildonspark/spark-sdk": "0.2.7",
76
- "@lightsparkdev/core": "^1.4.3",
75
+ "@buildonspark/spark-sdk": "0.2.9",
77
76
  "@noble/curves": "^1.8.0",
78
77
  "@scure/btc-signer": "^1.5.0",
79
- "buffer": "^6.0.3",
80
- "ts-proto": "^2.6.1"
78
+ "buffer": "^6.0.3"
81
79
  },
82
80
  "devDependencies": {
83
81
  "@arethetypeswrong/cli": "^0.17.4",
@@ -14,6 +14,14 @@ export class IssuerSparkWalletBrowser extends BaseIssuerSparkWallet {
14
14
  const wallet = new IssuerSparkWalletBrowser(options, signer);
15
15
  wallet.initializeTracer(wallet);
16
16
 
17
+ if (options && options.signerWithPreExistingKeys) {
18
+ await wallet.initWalletWithoutSeed();
19
+
20
+ return {
21
+ wallet,
22
+ };
23
+ }
24
+
17
25
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
18
26
 
19
27
  return {
@@ -14,6 +14,14 @@ export class IssuerSparkWalletNodeJS extends BaseIssuerSparkWallet {
14
14
  const wallet = new IssuerSparkWalletNodeJS(options, signer);
15
15
  wallet.initializeTracer(wallet);
16
16
 
17
+ if (options && options.signerWithPreExistingKeys) {
18
+ await wallet.initWalletWithoutSeed();
19
+
20
+ return {
21
+ wallet,
22
+ };
23
+ }
24
+
17
25
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
18
26
 
19
27
  return {
@@ -4,7 +4,6 @@ import {
4
4
  SparkWalletProps,
5
5
  ValidationError,
6
6
  } from "@buildonspark/spark-sdk";
7
- import { isNode } from "@lightsparkdev/core";
8
7
  import {
9
8
  decodeSparkAddress,
10
9
  encodeSparkAddress,
@@ -58,6 +57,14 @@ export class IssuerSparkWallet extends SparkWallet {
58
57
  const wallet = new IssuerSparkWallet(options, signer);
59
58
  wallet.initializeTracer(wallet);
60
59
 
60
+ if (options && options.signerWithPreExistingKeys) {
61
+ await wallet.initWalletWithoutSeed();
62
+
63
+ return {
64
+ wallet,
65
+ };
66
+ }
67
+
61
68
  const initResponse = await wallet.initWallet(mnemonicOrSeed, accountNumber);
62
69
 
63
70
  return {
@@ -44,7 +44,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
44
44
  tokenAmount: bigint,
45
45
  ): Promise<TokenTransaction> {
46
46
  return {
47
- version: 1,
47
+ version: 2,
48
48
  network: this.config.getNetworkProto(),
49
49
  tokenInputs: {
50
50
  $case: "mintInput",
@@ -64,6 +64,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
64
64
  sparkOperatorIdentityPublicKeys:
65
65
  super.collectOperatorIdentityPublicKeys(),
66
66
  expiryTime: undefined,
67
+ invoiceAttachments: [],
67
68
  };
68
69
  }
69
70
 
@@ -76,7 +77,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
76
77
  isFreezable: boolean,
77
78
  ): Promise<TokenTransaction> {
78
79
  return {
79
- version: 1,
80
+ version: 2,
80
81
  network: this.config.getNetworkProto(),
81
82
  tokenInputs: {
82
83
  $case: "createInput",
@@ -94,6 +95,7 @@ export class IssuerTokenTransactionService extends TokenTransactionService {
94
95
  sparkOperatorIdentityPublicKeys:
95
96
  super.collectOperatorIdentityPublicKeys(),
96
97
  expiryTime: undefined,
98
+ invoiceAttachments: [],
97
99
  };
98
100
  }
99
101
  }
@@ -113,7 +113,7 @@ describe.each(TEST_CONFIGS)(
113
113
  await expect(wallet.mintTokens(tokenAmount)).rejects.toThrow();
114
114
  });
115
115
 
116
- it("should create, andfail when minting more than max supply", async () => {
116
+ it("should create, and fail when minting more than max supply", async () => {
117
117
  const tokenAmount: bigint = 1000n;
118
118
  const { wallet } = await IssuerSparkWalletTesting.initialize({
119
119
  options: config,
@@ -198,6 +198,306 @@ describe.each(TEST_CONFIGS)(
198
198
  expect(userBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
199
199
  });
200
200
 
201
+ const tv1It = name.startsWith("TV1") ? it : it.skip;
202
+ tv1It("should transfer tokens using spark invoices", async () => {
203
+ const tokenAmount: bigint = 777n;
204
+ const initialIssuerBalance = 100000n;
205
+
206
+ const { wallet: issuerWallet } =
207
+ await IssuerSparkWalletTesting.initialize({
208
+ options: config,
209
+ });
210
+ const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
211
+ options: config,
212
+ });
213
+
214
+ await issuerWallet.createToken({
215
+ tokenName: `${name}INV`,
216
+ tokenTicker: "INV",
217
+ decimals: 0,
218
+ isFreezable: false,
219
+ maxSupply: 1_000_000n,
220
+ });
221
+
222
+ await issuerWallet.mintTokens(initialIssuerBalance);
223
+
224
+ const issuerBalanceAfterMint = await issuerWallet.getIssuerTokenBalance();
225
+ expect(issuerBalanceAfterMint).toBeDefined();
226
+ expect(issuerBalanceAfterMint.balance).toBe(initialIssuerBalance);
227
+ const tokenIdentifier = issuerBalanceAfterMint.tokenIdentifier!;
228
+ const issuerBalanceBeforeTransfer = issuerBalanceAfterMint.balance;
229
+
230
+ const invoice = await receiverWallet.createTokensInvoice({
231
+ amount: tokenAmount,
232
+ tokenIdentifier,
233
+ memo: "Invoice test",
234
+ expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
235
+ });
236
+
237
+ const txId = await issuerWallet.fulfillSparkInvoice([{ invoice }]);
238
+ expect(typeof txId).toBe("string");
239
+ expect(txId.length).toBeGreaterThan(0);
240
+
241
+ const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
242
+ .balance;
243
+ expect(issuerBalanceAfter).toEqual(
244
+ issuerBalanceBeforeTransfer - tokenAmount,
245
+ );
246
+
247
+ const receiverBalanceObj = await receiverWallet.getBalance();
248
+ const receiverBalance = filterTokenBalanceForTokenIdentifier(
249
+ receiverBalanceObj?.tokenBalances,
250
+ tokenIdentifier!,
251
+ );
252
+ expect(receiverBalance.balance).toEqual(tokenAmount);
253
+ });
254
+
255
+ tv1It("should transfer tokens using multiple spark invoices", async () => {
256
+ const amount1: bigint = 111n;
257
+ const amount2: bigint = 222n;
258
+ const amount3: bigint = 333n;
259
+ const totalAmount: bigint = amount1 + amount2 + amount3;
260
+ const initialIssuerBalance = 100000n;
261
+
262
+ const { wallet: issuerWallet } =
263
+ await IssuerSparkWalletTesting.initialize({
264
+ options: config,
265
+ });
266
+ const { wallet: receiverWallet1 } = await SparkWalletTesting.initialize({
267
+ options: config,
268
+ });
269
+ const { wallet: receiverWallet2 } = await SparkWalletTesting.initialize({
270
+ options: config,
271
+ });
272
+
273
+ await issuerWallet.createToken({
274
+ tokenName: `${name}INVM`,
275
+ tokenTicker: "INM",
276
+ decimals: 0,
277
+ isFreezable: false,
278
+ maxSupply: 1_000_000n,
279
+ });
280
+
281
+ await issuerWallet.mintTokens(initialIssuerBalance);
282
+
283
+ const issuerBalanceAfterMint = await issuerWallet.getIssuerTokenBalance();
284
+ expect(issuerBalanceAfterMint).toBeDefined();
285
+ expect(issuerBalanceAfterMint.balance).toBe(initialIssuerBalance);
286
+ const tokenIdentifier = issuerBalanceAfterMint.tokenIdentifier!;
287
+ const issuerBalanceBeforeTransfer = issuerBalanceAfterMint.balance;
288
+
289
+ const invoice1 = await receiverWallet1.createTokensInvoice({
290
+ amount: amount1,
291
+ tokenIdentifier,
292
+ memo: "Invoice #1",
293
+ expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
294
+ });
295
+
296
+ const invoice2 = await receiverWallet1.createTokensInvoice({
297
+ amount: amount2,
298
+ tokenIdentifier,
299
+ memo: "Invoice #2",
300
+ expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
301
+ });
302
+
303
+ const invoice3 = await receiverWallet2.createTokensInvoice({
304
+ amount: amount3,
305
+ tokenIdentifier,
306
+ memo: "Invoice #3",
307
+ expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
308
+ });
309
+
310
+ const txId = await issuerWallet.fulfillSparkInvoice([
311
+ { invoice: invoice1 },
312
+ { invoice: invoice2 },
313
+ { invoice: invoice3 },
314
+ ]);
315
+ expect(typeof txId).toBe("string");
316
+ expect(txId.length).toBeGreaterThan(0);
317
+
318
+ const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
319
+ .balance;
320
+ expect(issuerBalanceAfter).toEqual(
321
+ issuerBalanceBeforeTransfer - totalAmount,
322
+ );
323
+
324
+ const receiver1BalanceObj = await receiverWallet1.getBalance();
325
+ const receiver1Balance = filterTokenBalanceForTokenIdentifier(
326
+ receiver1BalanceObj?.tokenBalances,
327
+ tokenIdentifier!,
328
+ );
329
+ expect(receiver1Balance.balance).toEqual(amount1 + amount2);
330
+
331
+ const receiver2BalanceObj = await receiverWallet2.getBalance();
332
+ const receiver2Balance = filterTokenBalanceForTokenIdentifier(
333
+ receiver2BalanceObj?.tokenBalances,
334
+ tokenIdentifier!,
335
+ );
336
+ expect(receiver2Balance.balance).toEqual(amount3);
337
+ });
338
+
339
+ tv1It("should fail to fulfill an expired spark invoice", async () => {
340
+ const tokenAmount: bigint = 123n;
341
+ const initialIssuerBalance = 100000n;
342
+
343
+ const { wallet: issuerWallet } =
344
+ await IssuerSparkWalletTesting.initialize({
345
+ options: config,
346
+ });
347
+ const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
348
+ options: config,
349
+ });
350
+
351
+ await issuerWallet.createToken({
352
+ tokenName: `${name}INVEXP`,
353
+ tokenTicker: "INVX",
354
+ decimals: 0,
355
+ isFreezable: false,
356
+ maxSupply: 1_000_000n,
357
+ });
358
+
359
+ await issuerWallet.mintTokens(initialIssuerBalance);
360
+
361
+ const issuerBalanceAfterMint = await issuerWallet.getIssuerTokenBalance();
362
+ expect(issuerBalanceAfterMint).toBeDefined();
363
+ expect(issuerBalanceAfterMint.balance).toBe(initialIssuerBalance);
364
+ const tokenIdentifier = issuerBalanceAfterMint.tokenIdentifier!;
365
+ const issuerBalanceBefore = issuerBalanceAfterMint.balance;
366
+
367
+ const expiredInvoice = await receiverWallet.createTokensInvoice({
368
+ amount: tokenAmount,
369
+ tokenIdentifier,
370
+ memo: "Expired invoice",
371
+ expiryTime: new Date(Date.now() - 60_000),
372
+ });
373
+
374
+ await expect(
375
+ issuerWallet.fulfillSparkInvoice([{ invoice: expiredInvoice }]),
376
+ ).rejects.toThrow("expired");
377
+
378
+ const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
379
+ .balance;
380
+ expect(issuerBalanceAfter).toEqual(issuerBalanceBefore);
381
+
382
+ const receiverBalanceObj = await receiverWallet.getBalance();
383
+ const receiverBalance = filterTokenBalanceForTokenIdentifier(
384
+ receiverBalanceObj?.tokenBalances,
385
+ tokenIdentifier!,
386
+ );
387
+ expect(receiverBalance.balance).toEqual(0n);
388
+ });
389
+
390
+ tv1It("should fulfill a spark invoice with null expiry", async () => {
391
+ const tokenAmount: bigint = 321n;
392
+ const initialIssuerBalance = 100000n;
393
+
394
+ const { wallet: issuerWallet } =
395
+ await IssuerSparkWalletTesting.initialize({
396
+ options: config,
397
+ });
398
+ const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
399
+ options: config,
400
+ });
401
+
402
+ await issuerWallet.createToken({
403
+ tokenName: `${name}INVNULL`,
404
+ tokenTicker: "INVN",
405
+ decimals: 0,
406
+ isFreezable: false,
407
+ maxSupply: 1_000_000n,
408
+ });
409
+
410
+ await issuerWallet.mintTokens(initialIssuerBalance);
411
+
412
+ const issuerBalanceAfterMint = await issuerWallet.getIssuerTokenBalance();
413
+ expect(issuerBalanceAfterMint).toBeDefined();
414
+ expect(issuerBalanceAfterMint.balance).toBe(initialIssuerBalance);
415
+ const tokenIdentifier = issuerBalanceAfterMint.tokenIdentifier!;
416
+ const issuerBalanceBefore = issuerBalanceAfterMint.balance;
417
+
418
+ const nullExpiryInvoice = await receiverWallet.createTokensInvoice({
419
+ amount: tokenAmount,
420
+ tokenIdentifier,
421
+ memo: "Null expiry invoice",
422
+ expiryTime: null as unknown as Date,
423
+ });
424
+
425
+ const txId = await issuerWallet.fulfillSparkInvoice([
426
+ { invoice: nullExpiryInvoice },
427
+ ]);
428
+ expect(typeof txId).toBe("string");
429
+ expect(txId.length).toBeGreaterThan(0);
430
+
431
+ const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
432
+ .balance;
433
+ expect(issuerBalanceAfter).toEqual(issuerBalanceBefore - tokenAmount);
434
+
435
+ const receiverBalanceObj = await receiverWallet.getBalance();
436
+ const receiverBalance = filterTokenBalanceForTokenIdentifier(
437
+ receiverBalanceObj?.tokenBalances,
438
+ tokenIdentifier!,
439
+ );
440
+ expect(receiverBalance.balance).toEqual(tokenAmount);
441
+ });
442
+
443
+ tv1It(
444
+ "should fulfill a tokens invoice without amount by passing amount parameter",
445
+ async () => {
446
+ const tokenAmount: bigint = 555n;
447
+ const initialIssuerBalance = 100000n;
448
+
449
+ const { wallet: issuerWallet } =
450
+ await IssuerSparkWalletTesting.initialize({
451
+ options: config,
452
+ });
453
+ const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
454
+ options: config,
455
+ });
456
+
457
+ await issuerWallet.createToken({
458
+ tokenName: `${name}INVAOPT`,
459
+ tokenTicker: "INO",
460
+ decimals: 0,
461
+ isFreezable: false,
462
+ maxSupply: 1_000_000n,
463
+ });
464
+
465
+ await issuerWallet.mintTokens(initialIssuerBalance);
466
+
467
+ const issuerBalanceAfterMint =
468
+ await issuerWallet.getIssuerTokenBalance();
469
+ expect(issuerBalanceAfterMint).toBeDefined();
470
+ expect(issuerBalanceAfterMint.balance).toBe(initialIssuerBalance);
471
+ const tokenIdentifier = issuerBalanceAfterMint.tokenIdentifier!;
472
+ const issuerBalanceBeforeTransfer = issuerBalanceAfterMint.balance;
473
+
474
+ const invoiceWithoutAmount = await receiverWallet.createTokensInvoice({
475
+ tokenIdentifier,
476
+ memo: "Invoice without preset amount",
477
+ expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
478
+ });
479
+
480
+ const txId = await (issuerWallet as any).fulfillSparkInvoice([
481
+ { invoice: invoiceWithoutAmount, amount: tokenAmount },
482
+ ]);
483
+ expect(typeof txId).toBe("string");
484
+ expect(txId.length).toBeGreaterThan(0);
485
+
486
+ const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
487
+ .balance;
488
+ expect(issuerBalanceAfter).toEqual(
489
+ issuerBalanceBeforeTransfer - tokenAmount,
490
+ );
491
+
492
+ const receiverBalanceObj = await receiverWallet.getBalance();
493
+ const receiverBalance = filterTokenBalanceForTokenIdentifier(
494
+ receiverBalanceObj?.tokenBalances,
495
+ tokenIdentifier!,
496
+ );
497
+ expect(receiverBalance.balance).toEqual(tokenAmount);
498
+ },
499
+ );
500
+
201
501
  it("should create, mint, and batchtransfer tokens", async () => {
202
502
  const tokenAmount: bigint = 999n;
203
503
 
@@ -315,10 +615,11 @@ describe.each(TEST_CONFIGS)(
315
615
  );
316
616
  expect(userBalance.balance).toBeGreaterThanOrEqual(tokenAmount);
317
617
 
318
- const transactions = await issuerWallet.queryTokenTransactions({
618
+ const response = await issuerWallet.queryTokenTransactions({
319
619
  tokenIdentifiers: [tokenIdentifier!],
320
620
  ownerPublicKeys: [issuerPublicKey],
321
621
  });
622
+ const transactions = response.tokenTransactionsWithStatus;
322
623
  expect(transactions.length).toBeGreaterThanOrEqual(2);
323
624
 
324
625
  let mint_operation = 0;
@@ -377,10 +678,11 @@ describe.each(TEST_CONFIGS)(
377
678
 
378
679
  await issuerWallet.burnTokens(250n);
379
680
 
380
- const transactions = await issuerWallet.queryTokenTransactions({
681
+ const res = await issuerWallet.queryTokenTransactions({
381
682
  tokenIdentifiers: [tokenIdentifier!],
382
683
  ownerPublicKeys: [issuerPublicKey],
383
684
  });
685
+ const transactions = res.tokenTransactionsWithStatus;
384
686
 
385
687
  const mintTransaction = transactions.find(
386
688
  (tx) => tx.tokenTransaction?.tokenInputs?.$case === "mintInput",
@@ -427,9 +729,10 @@ describe.each(TEST_CONFIGS)(
427
729
  await issuerWallet.mintTokens(tokenAmount);
428
730
 
429
731
  {
430
- const transactions = await issuerWallet.queryTokenTransactions({
732
+ const res = await issuerWallet.queryTokenTransactions({
431
733
  tokenIdentifiers: [tokenIdentifier!],
432
734
  });
735
+ const transactions = res.tokenTransactionsWithStatus;
433
736
  const amount_of_transactions = transactions.length;
434
737
  expect(amount_of_transactions).toEqual(1);
435
738
  }
@@ -441,9 +744,10 @@ describe.each(TEST_CONFIGS)(
441
744
  });
442
745
 
443
746
  {
444
- const transactions = await issuerWallet.queryTokenTransactions({
747
+ const res = await issuerWallet.queryTokenTransactions({
445
748
  tokenIdentifiers: [tokenIdentifier!],
446
749
  });
750
+ const transactions = res.tokenTransactionsWithStatus;
447
751
  const amount_of_transactions = transactions.length;
448
752
  expect(amount_of_transactions).toEqual(2);
449
753
  }
@@ -458,10 +762,11 @@ describe.each(TEST_CONFIGS)(
458
762
  } // 202 in total
459
763
 
460
764
  {
461
- const transactions = await issuerWallet.queryTokenTransactions({
765
+ const res = await issuerWallet.queryTokenTransactions({
462
766
  tokenIdentifiers: [tokenIdentifier!],
463
767
  pageSize: 10,
464
768
  });
769
+ const transactions = res.tokenTransactionsWithStatus;
465
770
  const amount_of_transactions = transactions.length;
466
771
  expect(amount_of_transactions).toEqual(10);
467
772
  }
@@ -474,22 +779,23 @@ describe.each(TEST_CONFIGS)(
474
779
  let page_num = 0;
475
780
 
476
781
  while (true) {
477
- const transactionsPage = await issuerWallet.queryTokenTransactions({
782
+ const res = await issuerWallet.queryTokenTransactions({
478
783
  tokenIdentifiers: [tokenIdentifier!],
479
784
  pageSize,
480
785
  offset,
481
786
  });
787
+ const transactions = res.tokenTransactionsWithStatus;
482
788
 
483
- if (transactionsPage.length === 0) {
789
+ if (transactions.length === 0) {
484
790
  break;
485
791
  }
486
792
 
487
793
  if (offset === 0) {
488
- expect(transactionsPage.length).toEqual(pageSize);
794
+ expect(transactions.length).toEqual(pageSize);
489
795
  }
490
796
 
491
- for (let index = 0; index < transactionsPage.length; ++index) {
492
- const element = transactionsPage[index];
797
+ for (let index = 0; index < transactions.length; ++index) {
798
+ const element = transactions[index];
493
799
  if (element.tokenTransaction !== undefined) {
494
800
  const hash: String = bytesToHex(element.tokenTransactionHash);
495
801
  if (hashset_of_all_transactions.has(hash)) {
@@ -507,7 +813,7 @@ describe.each(TEST_CONFIGS)(
507
813
  }
508
814
 
509
815
  // Prepare for next iteration.
510
- offset += transactionsPage.length;
816
+ offset += transactions.length;
511
817
  page_num += 1;
512
818
  }
513
819