@buildonspark/issuer-sdk 0.0.92 → 0.0.93

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,12 @@
1
1
  # @buildonspark/issuer-sdk
2
2
 
3
+ ## 0.0.93
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @buildonspark/spark-sdk@0.3.0
9
+
3
10
  ## 0.0.92
4
11
 
5
12
  ### Patch Changes
package/README.md CHANGED
@@ -1,2 +1,3 @@
1
1
  # Welcome to Spark!
2
- You can find our official documentation at https://docs.spark.money/issuing/introduction
2
+
3
+ You can find our official documentation at https://docs.spark.money/issuing/introduction
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buildonspark/issuer-sdk",
3
- "version": "0.0.92",
3
+ "version": "0.0.93",
4
4
  "description": "Spark Issuer SDK for token issuance",
5
5
  "license": "Apache-2.0",
6
6
  "module": "./dist/index.js",
@@ -56,8 +56,8 @@
56
56
  "depcheck": "depcheck --ignores=buffer,ts-proto,jest,ts-jest,publint",
57
57
  "dev": "yarn build -- --watch",
58
58
  "docs": "typedoc src",
59
- "format:fix": "prettier src --write",
60
- "format": "prettier src --check",
59
+ "format:fix": "prettier . --write",
60
+ "format": "prettier . --check",
61
61
  "lint:fix": "eslint --fix .",
62
62
  "lint:fix:continue": "eslint --fix . || exit 0",
63
63
  "lint:watch": "esw ./src -w --ext .ts,.tsx,.js --color",
@@ -72,7 +72,7 @@
72
72
  "types": "tsc"
73
73
  },
74
74
  "dependencies": {
75
- "@buildonspark/spark-sdk": "0.2.13",
75
+ "@buildonspark/spark-sdk": "0.3.0",
76
76
  "@noble/curves": "^1.8.0",
77
77
  "@scure/btc-signer": "^1.5.0",
78
78
  "buffer": "^6.0.3"
@@ -86,7 +86,7 @@
86
86
  "jest": "^29.7.0",
87
87
  "madge": "^8.0.0",
88
88
  "node-fetch": "^3.3.2",
89
- "prettier": "^3.5.1",
89
+ "prettier": "^3.6.2",
90
90
  "publint": "^0.3.9",
91
91
  "ts-jest": "^29.2.5",
92
92
  "tsup": "^8.4.0",
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  ConfigOptions,
3
3
  filterTokenBalanceForTokenIdentifier,
4
+ RPCError,
4
5
  WalletConfig,
5
6
  } from "@buildonspark/spark-sdk";
6
7
  import { jest } from "@jest/globals";
7
- import { bytesToHex } from "@noble/curves/utils";
8
+ import { hexToBytes, bytesToHex } from "@noble/curves/utils";
8
9
  import { IssuerSparkWalletTesting } from "../utils/issuer-test-wallet.js";
9
10
  import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
11
+ import { BitcoinFaucet } from "@buildonspark/spark-sdk/test-utils";
10
12
 
11
13
  export const TOKENS_V0_SCHNORR_CONFIG: Required<ConfigOptions> = {
12
14
  ...WalletConfig.LOCAL,
@@ -232,9 +234,12 @@ describe.each(TEST_CONFIGS)(
232
234
  expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
233
235
  });
234
236
 
235
- const txId = await issuerWallet.fulfillSparkInvoice([{ invoice }]);
236
- expect(typeof txId).toBe("string");
237
- expect(txId.length).toBeGreaterThan(0);
237
+ const { tokenTransactionSuccess, tokenTransactionErrors } =
238
+ await issuerWallet.fulfillSparkInvoice([{ invoice }]);
239
+ expect(tokenTransactionErrors.length).toBe(0);
240
+ expect(tokenTransactionSuccess.length).toBe(1);
241
+ expect(tokenTransactionSuccess[0].txid).toBeDefined();
242
+ expect(tokenTransactionSuccess[0].txid.length).toBeGreaterThan(0);
238
243
 
239
244
  const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
240
245
  .balance;
@@ -305,13 +310,16 @@ describe.each(TEST_CONFIGS)(
305
310
  expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
306
311
  });
307
312
 
308
- const txId = await issuerWallet.fulfillSparkInvoice([
309
- { invoice: invoice1 },
310
- { invoice: invoice2 },
311
- { invoice: invoice3 },
312
- ]);
313
- expect(typeof txId).toBe("string");
314
- expect(txId.length).toBeGreaterThan(0);
313
+ const { tokenTransactionSuccess, tokenTransactionErrors } =
314
+ await issuerWallet.fulfillSparkInvoice([
315
+ { invoice: invoice1 },
316
+ { invoice: invoice2 },
317
+ { invoice: invoice3 },
318
+ ]);
319
+ expect(tokenTransactionErrors.length).toBe(0);
320
+ expect(tokenTransactionSuccess.length).toBe(1);
321
+ expect(tokenTransactionSuccess[0].txid).toBeDefined();
322
+ expect(tokenTransactionSuccess[0].txid.length).toBeGreaterThan(0);
315
323
 
316
324
  const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
317
325
  .balance;
@@ -369,9 +377,11 @@ describe.each(TEST_CONFIGS)(
369
377
  expiryTime: new Date(Date.now() - 60_000),
370
378
  });
371
379
 
372
- await expect(
373
- issuerWallet.fulfillSparkInvoice([{ invoice: expiredInvoice }]),
374
- ).rejects.toThrow("expired");
380
+ const { invalidInvoices } = await issuerWallet.fulfillSparkInvoice([
381
+ { invoice: expiredInvoice },
382
+ ]);
383
+ expect(invalidInvoices.length).toBe(1);
384
+ expect(invalidInvoices[0].invoice).toBe(expiredInvoice);
375
385
 
376
386
  const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
377
387
  .balance;
@@ -420,11 +430,14 @@ describe.each(TEST_CONFIGS)(
420
430
  expiryTime: null as unknown as Date,
421
431
  });
422
432
 
423
- const txId = await issuerWallet.fulfillSparkInvoice([
424
- { invoice: nullExpiryInvoice },
425
- ]);
426
- expect(typeof txId).toBe("string");
427
- expect(txId.length).toBeGreaterThan(0);
433
+ const { tokenTransactionSuccess, tokenTransactionErrors } =
434
+ await issuerWallet.fulfillSparkInvoice([
435
+ { invoice: nullExpiryInvoice },
436
+ ]);
437
+ expect(tokenTransactionErrors.length).toBe(0);
438
+ expect(tokenTransactionSuccess.length).toBe(1);
439
+ expect(tokenTransactionSuccess[0].txid).toBeDefined();
440
+ expect(tokenTransactionSuccess[0].txid.length).toBeGreaterThan(0);
428
441
 
429
442
  const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
430
443
  .balance;
@@ -475,11 +488,14 @@ describe.each(TEST_CONFIGS)(
475
488
  expiryTime: new Date(Date.now() + 1000 * 60 * 60 * 24),
476
489
  });
477
490
 
478
- const txId = await (issuerWallet as any).fulfillSparkInvoice([
479
- { invoice: invoiceWithoutAmount, amount: tokenAmount },
480
- ]);
481
- expect(typeof txId).toBe("string");
482
- expect(txId.length).toBeGreaterThan(0);
491
+ const { tokenTransactionSuccess, tokenTransactionErrors } =
492
+ await issuerWallet.fulfillSparkInvoice([
493
+ { invoice: invoiceWithoutAmount, amount: tokenAmount },
494
+ ]);
495
+ expect(tokenTransactionErrors.length).toBe(0);
496
+ expect(tokenTransactionSuccess.length).toBe(1);
497
+ expect(tokenTransactionSuccess[0].txid).toBeDefined();
498
+ expect(tokenTransactionSuccess[0].txid.length).toBeGreaterThan(0);
483
499
 
484
500
  const issuerBalanceAfter = (await issuerWallet.getIssuerTokenBalance())
485
501
  .balance;
@@ -496,6 +512,140 @@ describe.each(TEST_CONFIGS)(
496
512
  },
497
513
  );
498
514
 
515
+ tv1It(
516
+ `fulfillSparkInvoice successfully handles multiple mixed tokens and sats invoices`,
517
+ async () => {
518
+ const faucet = BitcoinFaucet.getInstance();
519
+ const { wallet: sdk } = await IssuerSparkWalletTesting.initialize({
520
+ options: config,
521
+ });
522
+ await sdk.createToken({
523
+ tokenName: `SDKONE`,
524
+ tokenTicker: "SDK1",
525
+ decimals: 0,
526
+ isFreezable: false,
527
+ maxSupply: 1_000_000n,
528
+ });
529
+ const { wallet: sdk2 } = await IssuerSparkWalletTesting.initialize({
530
+ options: config,
531
+ });
532
+ await sdk2.createToken({
533
+ tokenName: `SDKTWO`,
534
+ tokenTicker: "SDK2",
535
+ decimals: 0,
536
+ isFreezable: false,
537
+ maxSupply: 1_000_000n,
538
+ });
539
+
540
+ await sdk.mintTokens(1_000_000n);
541
+ await sdk2.mintTokens(1_000_000n);
542
+
543
+ const sdkOneTokenIdentifier = await sdk.getIssuerTokenIdentifier();
544
+ const sdkTwoTokenIdentifier = await sdk2.getIssuerTokenIdentifier();
545
+
546
+ await sdk2.transferTokens({
547
+ tokenAmount: 1_000_000n,
548
+ tokenIdentifier: sdkTwoTokenIdentifier,
549
+ receiverSparkAddress: await sdk.getSparkAddress(),
550
+ });
551
+
552
+ const depositAddrOne = await sdk.getSingleUseDepositAddress();
553
+ if (!depositAddrOne) {
554
+ throw new RPCError("Deposit address not found", {
555
+ method: "getDepositAddress",
556
+ });
557
+ }
558
+ const depositAddrTwo = await sdk.getSingleUseDepositAddress();
559
+ if (!depositAddrTwo) {
560
+ throw new RPCError("Deposit address not found", {
561
+ method: "getDepositAddress",
562
+ });
563
+ }
564
+ const depositAddrThree = await sdk.getSingleUseDepositAddress();
565
+ if (!depositAddrThree) {
566
+ throw new RPCError("Deposit address not found", {
567
+ method: "getDepositAddress",
568
+ });
569
+ }
570
+
571
+ const oneThousand = await faucet.sendToAddress(depositAddrOne, 1_000n);
572
+ const twoThousand = await faucet.sendToAddress(depositAddrTwo, 2_000n);
573
+ const threeThousand = await faucet.sendToAddress(
574
+ depositAddrThree,
575
+ 3_000n,
576
+ );
577
+
578
+ await sdk.claimDeposit(oneThousand.id);
579
+ await sdk.claimDeposit(twoThousand.id);
580
+ await sdk.claimDeposit(threeThousand.id);
581
+
582
+ const balance = await sdk.getBalance();
583
+ expect(balance.balance).toBe(6_000n);
584
+
585
+ const tomorrow = new Date(Date.now() + 1000 * 60 * 60 * 24);
586
+ const invoice1000 = await sdk2.createSatsInvoice({
587
+ amount: 1_000,
588
+ memo: "Test invoice",
589
+ expiryTime: tomorrow,
590
+ });
591
+ const invoice2000 = await sdk2.createSatsInvoice({
592
+ amount: 2_000,
593
+ memo: "Test invoice",
594
+ expiryTime: tomorrow,
595
+ });
596
+ const invoiceNilAmount = await sdk2.createSatsInvoice({
597
+ memo: "Test invoice",
598
+ expiryTime: tomorrow,
599
+ });
600
+ const sdkOneTokenInvoiceA = await sdk2.createTokensInvoice({
601
+ amount: 1_000n,
602
+ tokenIdentifier: sdkOneTokenIdentifier,
603
+ memo: "Test invoice",
604
+ expiryTime: tomorrow,
605
+ });
606
+ const sdkOneTokenInvoiceB = await sdk2.createTokensInvoice({
607
+ amount: 2_000n,
608
+ tokenIdentifier: sdkOneTokenIdentifier,
609
+ memo: "Test invoice",
610
+ expiryTime: tomorrow,
611
+ });
612
+ const sdkTwoTokenInvoiceA = await sdk2.createTokensInvoice({
613
+ amount: 1_000n,
614
+ tokenIdentifier: sdkTwoTokenIdentifier,
615
+ memo: "Test invoice",
616
+ expiryTime: tomorrow,
617
+ });
618
+ const sdkTwoTokenNilAmountInvoiceB = await sdk2.createTokensInvoice({
619
+ tokenIdentifier: sdkTwoTokenIdentifier,
620
+ memo: "Test invoice",
621
+ expiryTime: tomorrow,
622
+ });
623
+
624
+ const transferResults = await sdk.fulfillSparkInvoice([
625
+ { invoice: invoice1000 },
626
+ { invoice: invoice2000 },
627
+ { invoice: invoiceNilAmount, amount: 3_000n },
628
+ { invoice: sdkOneTokenInvoiceA },
629
+ { invoice: sdkOneTokenInvoiceB },
630
+ { invoice: sdkTwoTokenInvoiceA },
631
+ { invoice: sdkTwoTokenNilAmountInvoiceB, amount: 3_000n },
632
+ ]);
633
+
634
+ const {
635
+ satsTransactionSuccess,
636
+ satsTransactionErrors,
637
+ tokenTransactionSuccess,
638
+ tokenTransactionErrors,
639
+ invalidInvoices,
640
+ } = transferResults;
641
+ expect(satsTransactionErrors.length).toBe(0);
642
+ expect(tokenTransactionErrors.length).toBe(0);
643
+ expect(satsTransactionSuccess.length).toBe(3); // one sats success per invoice
644
+ expect(tokenTransactionSuccess.length).toBe(2); // two token assets - divided into two token transactions
645
+ expect(invalidInvoices.length).toBe(0);
646
+ },
647
+ );
648
+
499
649
  it("should create, mint, and batchtransfer tokens", async () => {
500
650
  const tokenAmount: bigint = 999n;
501
651