@buildonspark/spark-sdk 0.1.43 → 0.1.45

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.
Files changed (153) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/{RequestLightningSendInput-D7fZdT4A.d.ts → RequestLightningSendInput-DEPd_fPO.d.ts} +43 -4
  3. package/dist/{RequestLightningSendInput-Na1mHdWg.d.cts → RequestLightningSendInput-Du0z7Om7.d.cts} +43 -4
  4. package/dist/address/index.cjs +2 -2
  5. package/dist/address/index.d.cts +2 -2
  6. package/dist/address/index.d.ts +2 -2
  7. package/dist/address/index.js +2 -2
  8. package/dist/{chunk-IRW5TWMH.js → chunk-5FUB65LX.js} +7 -9
  9. package/dist/{chunk-BUTZWYBW.js → chunk-6264CGDM.js} +4 -4
  10. package/dist/{chunk-VFJQNBFX.js → chunk-7V6N75CC.js} +5 -2
  11. package/dist/{chunk-M6A4KFIG.js → chunk-BGGEVUJK.js} +1505 -445
  12. package/dist/{chunk-DQYKQJRZ.js → chunk-C2S227QR.js} +675 -52
  13. package/dist/{chunk-GYQR4B4P.js → chunk-GZ5IPPJ2.js} +2 -2
  14. package/dist/{chunk-6AFUC5M2.js → chunk-HWJWKEIU.js} +8 -2
  15. package/dist/{chunk-TOSP3INR.js → chunk-I54FARY2.js} +4 -2
  16. package/dist/{chunk-WWOTVNPP.js → chunk-J2IE4Z7Y.js} +544 -431
  17. package/dist/{chunk-O4RYNJNB.js → chunk-KMUMFYFX.js} +3 -3
  18. package/dist/chunk-LHRD2WT6.js +2374 -0
  19. package/dist/{chunk-ABZA6R5S.js → chunk-NTFKFRQ2.js} +1 -1
  20. package/dist/{chunk-MIVX3GHD.js → chunk-OBFKIEMP.js} +1 -1
  21. package/dist/{chunk-HRQRRDSS.js → chunk-PQN3C2MF.js} +15 -15
  22. package/dist/{chunk-DOA6QXYQ.js → chunk-R5PXJZQS.js} +3 -1
  23. package/dist/{chunk-TIUBYNN5.js → chunk-YUPMXTCJ.js} +4 -4
  24. package/dist/graphql/objects/index.d.cts +6 -43
  25. package/dist/graphql/objects/index.d.ts +6 -43
  26. package/dist/graphql/objects/index.js +1 -1
  27. package/dist/index-B2AwKW5J.d.cts +214 -0
  28. package/dist/index-CJDi1HWc.d.ts +214 -0
  29. package/dist/index.cjs +4150 -1026
  30. package/dist/index.d.cts +764 -19
  31. package/dist/index.d.ts +764 -19
  32. package/dist/index.js +17 -21
  33. package/dist/index.node.cjs +4153 -1033
  34. package/dist/index.node.d.cts +10 -8
  35. package/dist/index.node.d.ts +10 -8
  36. package/dist/index.node.js +20 -28
  37. package/dist/native/index.cjs +4166 -1042
  38. package/dist/native/index.d.cts +369 -108
  39. package/dist/native/index.d.ts +369 -108
  40. package/dist/native/index.js +4138 -1015
  41. package/dist/{network-xkBSpaTn.d.ts → network-BTJl-Sul.d.ts} +1 -1
  42. package/dist/{network-D5lKssVl.d.cts → network-CqgsdUF2.d.cts} +1 -1
  43. package/dist/proto/lrc20.cjs +222 -19
  44. package/dist/proto/lrc20.d.cts +1 -1
  45. package/dist/proto/lrc20.d.ts +1 -1
  46. package/dist/proto/lrc20.js +2 -2
  47. package/dist/proto/spark.cjs +1502 -442
  48. package/dist/proto/spark.d.cts +1 -1
  49. package/dist/proto/spark.d.ts +1 -1
  50. package/dist/proto/spark.js +5 -5
  51. package/dist/proto/spark_token.cjs +1515 -56
  52. package/dist/proto/spark_token.d.cts +153 -15
  53. package/dist/proto/spark_token.d.ts +153 -15
  54. package/dist/proto/spark_token.js +40 -4
  55. package/dist/{sdk-types-B-q9py_P.d.cts → sdk-types-B0SwjolI.d.cts} +1 -1
  56. package/dist/{sdk-types-BPoPgzda.d.ts → sdk-types-Cc4l4kb1.d.ts} +1 -1
  57. package/dist/services/config.cjs +7 -3
  58. package/dist/services/config.d.cts +5 -4
  59. package/dist/services/config.d.ts +5 -4
  60. package/dist/services/config.js +6 -6
  61. package/dist/services/connection.cjs +2938 -646
  62. package/dist/services/connection.d.cts +5 -4
  63. package/dist/services/connection.d.ts +5 -4
  64. package/dist/services/connection.js +4 -4
  65. package/dist/services/index.cjs +6381 -3461
  66. package/dist/services/index.d.cts +7 -6
  67. package/dist/services/index.d.ts +7 -6
  68. package/dist/services/index.js +15 -13
  69. package/dist/services/lrc-connection.cjs +227 -21
  70. package/dist/services/lrc-connection.d.cts +5 -4
  71. package/dist/services/lrc-connection.d.ts +5 -4
  72. package/dist/services/lrc-connection.js +4 -4
  73. package/dist/services/token-transactions.cjs +868 -244
  74. package/dist/services/token-transactions.d.cts +25 -7
  75. package/dist/services/token-transactions.d.ts +25 -7
  76. package/dist/services/token-transactions.js +5 -4
  77. package/dist/services/wallet-config.cjs +4 -1
  78. package/dist/services/wallet-config.d.cts +7 -5
  79. package/dist/services/wallet-config.d.ts +7 -5
  80. package/dist/services/wallet-config.js +3 -1
  81. package/dist/signer/signer.cjs +5 -2
  82. package/dist/signer/signer.d.cts +3 -2
  83. package/dist/signer/signer.d.ts +3 -2
  84. package/dist/signer/signer.js +2 -2
  85. package/dist/{signer-wqesWifN.d.ts → signer-BocS_J6B.d.ts} +2 -6
  86. package/dist/{signer-IO3oMRNj.d.cts → signer-DKS0AJkw.d.cts} +2 -6
  87. package/dist/{spark-CDm4gqS6.d.cts → spark-dM7EYXYQ.d.cts} +138 -42
  88. package/dist/{spark-CDm4gqS6.d.ts → spark-dM7EYXYQ.d.ts} +138 -42
  89. package/dist/spark_bindings/native/index.cjs +183 -0
  90. package/dist/spark_bindings/native/index.d.cts +14 -0
  91. package/dist/spark_bindings/native/index.d.ts +14 -0
  92. package/dist/spark_bindings/native/index.js +141 -0
  93. package/dist/spark_bindings/wasm/index.cjs +1093 -0
  94. package/dist/spark_bindings/wasm/index.d.cts +47 -0
  95. package/dist/spark_bindings/wasm/index.d.ts +47 -0
  96. package/dist/{chunk-K4C4W5FC.js → spark_bindings/wasm/index.js} +7 -6
  97. package/dist/types/index.cjs +1503 -443
  98. package/dist/types/index.d.cts +6 -5
  99. package/dist/types/index.d.ts +6 -5
  100. package/dist/types/index.js +3 -3
  101. package/dist/types-C-Rp0Oo7.d.cts +46 -0
  102. package/dist/types-C-Rp0Oo7.d.ts +46 -0
  103. package/dist/utils/index.cjs +358 -36
  104. package/dist/utils/index.d.cts +14 -134
  105. package/dist/utils/index.d.ts +14 -134
  106. package/dist/utils/index.js +8 -8
  107. package/package.json +21 -1
  108. package/src/constants.ts +5 -1
  109. package/src/graphql/client.ts +28 -0
  110. package/src/graphql/mutations/RequestCoopExit.ts +6 -0
  111. package/src/graphql/mutations/RequestSwapLeaves.ts +2 -0
  112. package/src/graphql/queries/GetCoopExitFeeQuote.ts +20 -0
  113. package/src/index.node.ts +0 -1
  114. package/src/index.ts +0 -1
  115. package/src/native/index.ts +1 -2
  116. package/src/proto/common.ts +5 -5
  117. package/src/proto/google/protobuf/descriptor.ts +34 -34
  118. package/src/proto/google/protobuf/duration.ts +2 -2
  119. package/src/proto/google/protobuf/empty.ts +2 -2
  120. package/src/proto/google/protobuf/timestamp.ts +2 -2
  121. package/src/proto/mock.ts +4 -4
  122. package/src/proto/spark.ts +1924 -525
  123. package/src/proto/spark_authn.ts +7 -7
  124. package/src/proto/spark_token.ts +1668 -105
  125. package/src/proto/validate/validate.ts +24 -24
  126. package/src/services/bolt11-spark.ts +62 -187
  127. package/src/services/coop-exit.ts +3 -0
  128. package/src/services/lrc20.ts +1 -1
  129. package/src/services/token-transactions.ts +209 -9
  130. package/src/services/transfer.ts +22 -3
  131. package/src/services/tree-creation.ts +13 -0
  132. package/src/services/wallet-config.ts +2 -1
  133. package/src/spark-wallet/spark-wallet.node.ts +3 -7
  134. package/src/spark-wallet/spark-wallet.ts +376 -232
  135. package/src/spark-wallet/types.ts +39 -3
  136. package/src/tests/bolt11-spark.test.ts +7 -15
  137. package/src/tests/integration/deposit.test.ts +16 -0
  138. package/src/tests/integration/ssp/coop-exit.test.ts +85 -21
  139. package/src/tests/integration/ssp/swap.test.ts +47 -0
  140. package/src/tests/integration/swap.test.ts +453 -433
  141. package/src/tests/integration/transfer.test.ts +261 -248
  142. package/src/tests/token-identifier.test.ts +54 -0
  143. package/src/tests/tokens.test.ts +218 -22
  144. package/src/utils/token-hashing.ts +346 -52
  145. package/src/utils/token-identifier.ts +88 -0
  146. package/src/utils/token-transaction-validation.ts +350 -5
  147. package/src/utils/token-transactions.ts +12 -8
  148. package/src/utils/transaction.ts +2 -8
  149. package/dist/chunk-VA7MV4MZ.js +0 -1073
  150. package/dist/index-7RYRH5wc.d.ts +0 -815
  151. package/dist/index-BJOc8Ur-.d.cts +0 -815
  152. package/dist/wasm-7OWFHDMS.js +0 -21
  153. package/src/logger.ts +0 -3
@@ -1,6 +1,7 @@
1
1
  import type { Transaction } from "@scure/btc-signer";
2
2
  import { ConfigOptions } from "../services/wallet-config.js";
3
3
  import type { SparkSigner } from "../signer/signer.js";
4
+ import { HumanReadableTokenIdentifier } from "../utils/token-identifier.js";
4
5
 
5
6
  export type CreateLightningInvoiceParams = {
6
7
  amountSats: number;
@@ -30,14 +31,49 @@ export type DepositParams = {
30
31
  vout: number;
31
32
  };
32
33
 
33
- export type TokenInfo = {
34
+ /**
35
+ * Token metadata containing essential information about a token.
36
+ * This is the wallet's internal representation with JavaScript-friendly types.
37
+ *
38
+ * rawTokenIdentifier: This is the raw binary token identifier - This is used to encode the human readable token identifier.
39
+ *
40
+ * tokenPublicKey: This is the hex-encoded public key of the token issuer - Same as issuerPublicKey.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const tokenMetadata: TokenMetadata = {
45
+ * rawTokenIdentifier: new Uint8Array([1, 2, 3]),
46
+ * tokenPublicKey: "0348fbb...",
47
+ * tokenName: "SparkToken",
48
+ * tokenTicker: "SPK",
49
+ * decimals: 8,
50
+ * maxSupply: 1000000n
51
+ * };
52
+ * ```
53
+ */
54
+ export type TokenMetadata = {
55
+ /** Raw binary token identifier - This is used to encode the human readable token identifier */
56
+ rawTokenIdentifier: Uint8Array;
57
+ /** Hex-encoded public key of the token issuer - Same as issuerPublicKey */
34
58
  tokenPublicKey: string;
59
+ /** Human-readable name of the token (e.g., SparkToken)*/
35
60
  tokenName: string;
36
- tokenSymbol: string;
37
- tokenDecimals: number;
61
+ /** Short ticker symbol for the token (e.g., "SPK") */
62
+ tokenTicker: string;
63
+ /** Number of decimal places for token amounts */
64
+ decimals: number;
65
+ /** Maximum supply of tokens that can ever be minted */
38
66
  maxSupply: bigint;
39
67
  };
40
68
 
69
+ export type TokenBalanceMap = Map<
70
+ HumanReadableTokenIdentifier,
71
+ {
72
+ balance: bigint;
73
+ tokenMetadata: TokenMetadata;
74
+ }
75
+ >;
76
+
41
77
  export type InitWalletResponse = {
42
78
  mnemonic?: string | undefined;
43
79
  };
@@ -62,7 +62,7 @@ describe("spark bolt11 invoice decoding", () => {
62
62
  "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny";
63
63
  expect(() => {
64
64
  decodeInvoice(invoice);
65
- }).toThrow('Letter "1" must be present between prefix and data only');
65
+ }).toThrow("Not a proper lightning payment request");
66
66
  });
67
67
 
68
68
  it("fails to decode malformed Bolt11 invoice - mixed case", () => {
@@ -73,20 +73,12 @@ describe("spark bolt11 invoice decoding", () => {
73
73
  }).toThrow("String must be lowercase or uppercase");
74
74
  });
75
75
 
76
- it("fails to decode bolt11 invoice with invalid signature", () => {
77
- const invoice =
78
- "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqwgt7mcn5yqw3yx0w94pswkpq6j9uh6xfqqqtsk4tnarugeektd4hg5975x9am52rz4qskukxdmjemg92vvqz8nvmsye63r5ykel43pgz7zq0g2";
79
- expect(() => {
80
- decodeInvoice(invoice);
81
- }).toThrow("Invalid BOLT11 signature");
82
- });
83
-
84
76
  it("fails to decode bolt11 invoice with invalid multiplier", () => {
85
77
  const invoice =
86
78
  "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgqrrzc4cvfue4zp3hggxp47ag7xnrlr8vgcmkjxk3j5jqethnumgkpqp23z9jclu3v0a7e0aruz366e9wqdykw6dxhdzcjjhldxq0w6wgqcnu43j";
87
79
  expect(() => {
88
80
  decodeInvoice(invoice);
89
- }).toThrow("Invalid multiplier: x");
81
+ }).toThrow("Not a valid multiplier for the amount");
90
82
  });
91
83
 
92
84
  it("fails to decode bolt11 invoice with invalid submillisatoshi precision", () => {
@@ -94,7 +86,7 @@ describe("spark bolt11 invoice decoding", () => {
94
86
  "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpusp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9qrsgq0lzc236j96a95uv0m3umg28gclm5lqxtqqwk32uuk4k6673k6n5kfvx3d2h8s295fad45fdhmusm8sjudfhlf6dcsxmfvkeywmjdkxcp99202x";
95
87
  expect(() => {
96
88
  decodeInvoice(invoice);
97
- }).toThrow("Invalid submillisatoshi precision");
89
+ }).toThrow("Amount is outside of valid range");
98
90
  });
99
91
 
100
92
  it("fails to decode bolt11 invoice with invalid payment secret", () => {
@@ -107,17 +99,17 @@ describe("spark bolt11 invoice decoding", () => {
107
99
 
108
100
  it("decodes a bolt11 invoice with spark address embedded", () => {
109
101
  const invoice =
110
- "lnbc1pvjluezsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6twvus8g6rfwvs8qun0dfjkxaq9qrsgqfpml2dgykqjsjj0vxkcz9cuftlfhw5qs9720aqf4y0azyqggx29gz7gt7eadu5h5wqmn7ns8rju0ps0tk8jx70eg8jxek3usgsehql0ztdxmfjj58nqjky6w9wp324ctcnj9vnrgc8j9dpujfqjrc8lv9z4twr2pur2cgqujn2dx";
102
+ "lnbc13u1p5xalmkpp5z79uwgne7znz76plf0q4zxmh8t3wke6gsnm5kn67h4satpgflkmssp5azht5ywc5s4m40jf9h0nwlr959a34n72pns50lfm93zz8lvs7nqsxq9z0rgqnp4q0p92sfan5vj2a4f8q3gsfsy8qp60maeuxz858c5x0hvt5u0p0h9jr9yqtqd37k2ya0pv8pqeyjs4lklcexjyw600g9qqp62r4j0ph8fcmlfwqqqqzfv7u6g85qqqqqqqqqqthqq9qpz9cat0ndmwmfx036y9fxfhdufta3mn95ta9xw34ynlwg7euxjck85ysq0gfqqqqq7u6egqrhxk2qqn3qqcqzpgdq2w3jhxap3xv9qyyssqfahd64hu0lffl7cw2e4evu400s09yeupypvnfjvjjyq8rh05y9gzd3dqnmkvuyd9jszyhmdey75dujz8xaufgahsxkqktf3wxny8ghsqpk4mg8";
111
103
 
112
104
  const { amountMSats, fallbackAddress, paymentHash } =
113
105
  decodeInvoice(invoice);
114
106
 
115
- expect(amountMSats).toBe(null);
107
+ expect(amountMSats).toBe(1300000n);
116
108
  expect(fallbackAddress).toBe(
117
- "53504b0250949ec35b022e3895fd37750102f94fe813523fa220108328a81790bf67ade5",
109
+ "0222e3ab7cdbb76d267c7442a4c9bb7895f63b9968be94ce8d493fb91ecf0d2c58",
118
110
  );
119
111
  expect(paymentHash).toBe(
120
- "0001020304050607080900010203040506070809000102030405060708090102",
112
+ "178bc72279f0a62f683f4bc1511b773ae2eb674884f74b4f5ebd61d58509fdb7",
121
113
  );
122
114
  });
123
115
  });
@@ -19,6 +19,22 @@ describe("deposit", () => {
19
19
  expect(depositAddress).toBeDefined();
20
20
  }, 30000);
21
21
 
22
+ it("should should query multiple deposit addresses", async () => {
23
+ const { wallet: sdk } = await SparkWalletTesting.initialize({
24
+ options: {
25
+ network: "LOCAL",
26
+ },
27
+ });
28
+
29
+ for (let i = 0; i < 105; i++) {
30
+ await sdk.getSingleUseDepositAddress();
31
+ }
32
+
33
+ const depositAddresses = await sdk.getUnusedDepositAddresses();
34
+
35
+ expect(depositAddresses).toHaveLength(105);
36
+ }, 30000);
37
+
22
38
  it("should generate a staticdeposit address", async () => {
23
39
  const { wallet: sdk } = await SparkWalletTesting.initialize({
24
40
  options: {
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, it } from "@jest/globals";
2
+ import { ExitSpeed } from "../../../types/index.js";
2
3
  import { SparkWalletTesting } from "../../utils/spark-testing-wallet.js";
3
4
  import { BitcoinFaucet } from "../../utils/test-faucet.js";
4
5
 
@@ -33,31 +34,94 @@ describe("SSP coop exit integration", () => {
33
34
 
34
35
  const withdrawalAddress = await faucet.getNewAddress();
35
36
 
36
- const feeEstimate = await userWallet.getWithdrawalFeeEstimate({
37
+ const feeEstimate = await userWallet.getWithdrawalFeeQuote({
37
38
  amountSats: Number(DEPOSIT_AMOUNT),
38
39
  withdrawalAddress,
39
40
  });
40
41
 
41
42
  expect(feeEstimate).toBeDefined();
42
- expect(feeEstimate?.speedFast?.l1BroadcastFee).toBeDefined();
43
- expect(
44
- feeEstimate?.speedFast?.l1BroadcastFee.originalValue,
45
- ).toBeGreaterThan(0);
46
- expect(feeEstimate?.speedFast?.userFee).toBeDefined();
47
- expect(feeEstimate?.speedFast?.userFee.originalValue).toBeGreaterThan(0);
48
-
49
- expect(feeEstimate?.speedMedium?.l1BroadcastFee).toBeDefined();
50
- expect(
51
- feeEstimate?.speedMedium?.l1BroadcastFee.originalValue,
52
- ).toBeGreaterThan(0);
53
- expect(feeEstimate?.speedMedium?.userFee).toBeDefined();
54
- expect(feeEstimate?.speedMedium?.userFee.originalValue).toBeGreaterThan(0);
55
-
56
- expect(feeEstimate?.speedSlow?.l1BroadcastFee).toBeDefined();
57
- expect(
58
- feeEstimate?.speedSlow?.l1BroadcastFee.originalValue,
59
- ).toBeGreaterThan(0);
60
- expect(feeEstimate?.speedSlow?.userFee).toBeDefined();
61
- expect(feeEstimate?.speedSlow?.userFee.originalValue).toBeGreaterThan(0);
43
+ expect(feeEstimate?.l1BroadcastFeeFast).toBeDefined();
44
+ expect(feeEstimate?.l1BroadcastFeeFast.originalValue).toBeGreaterThan(0);
45
+ expect(feeEstimate?.userFeeFast).toBeDefined();
46
+ expect(feeEstimate?.userFeeFast.originalValue).toBeGreaterThan(0);
47
+
48
+ expect(feeEstimate?.l1BroadcastFeeMedium).toBeDefined();
49
+ expect(feeEstimate?.l1BroadcastFeeMedium.originalValue).toBeGreaterThan(0);
50
+ expect(feeEstimate?.userFeeMedium).toBeDefined();
51
+ expect(feeEstimate?.userFeeMedium.originalValue).toBeGreaterThan(0);
52
+
53
+ expect(feeEstimate?.l1BroadcastFeeSlow).toBeDefined();
54
+ expect(feeEstimate?.l1BroadcastFeeSlow.originalValue).toBeGreaterThan(0);
55
+ expect(feeEstimate?.userFeeSlow).toBeDefined();
56
+ expect(feeEstimate?.userFeeSlow.originalValue).toBeGreaterThan(0);
57
+ }, 60000);
58
+
59
+ it.skip("should complete coop exit without deducting fees from withdrawal amount", async () => {
60
+ const faucet = BitcoinFaucet.getInstance();
61
+
62
+ const { wallet: userWallet } = await SparkWalletTesting.initialize(
63
+ {
64
+ options: {
65
+ network: "LOCAL",
66
+ },
67
+ },
68
+ false,
69
+ );
70
+
71
+ const depositAddress = await userWallet.getSingleUseDepositAddress();
72
+ expect(depositAddress).toBeDefined();
73
+
74
+ const signedTx = await faucet.sendToAddress(depositAddress, DEPOSIT_AMOUNT);
75
+ expect(signedTx).toBeDefined();
76
+ await faucet.mineBlocks(6);
77
+
78
+ await userWallet.claimDeposit(signedTx.id);
79
+
80
+ await new Promise((resolve) => setTimeout(resolve, 1000));
81
+
82
+ const { balance } = await userWallet.getBalance();
83
+ expect(balance).toBe(DEPOSIT_AMOUNT);
84
+
85
+ const withdrawalAddress = await faucet.getNewAddress();
86
+
87
+ const feeQuote = await userWallet.getWithdrawalFeeQuote({
88
+ amountSats: 5000,
89
+ withdrawalAddress,
90
+ });
91
+
92
+ expect(feeQuote).toBeDefined();
93
+
94
+ const coopExit = await userWallet.withdraw({
95
+ amountSats: 5000,
96
+ onchainAddress: withdrawalAddress,
97
+ feeQuote: feeQuote!,
98
+ exitSpeed: ExitSpeed.FAST,
99
+ deductFeeFromWithdrawalAmount: false,
100
+ });
101
+
102
+ const fee =
103
+ (coopExit?.l1BroadcastFee?.originalValue ?? 0) +
104
+ (coopExit?.fee?.originalValue ?? 0);
105
+
106
+ expect(fee).toBeGreaterThan(0);
107
+
108
+ const { balance: balanceAfter } = await userWallet.getBalance();
109
+
110
+ expect(balanceAfter).toBe(DEPOSIT_AMOUNT - 5000n - BigInt(fee));
111
+ expect(coopExit).toBeDefined();
112
+ expect(coopExit?.coopExitTxid).toBeDefined();
113
+
114
+ await faucet.mineBlocks(6);
115
+
116
+ const deposit = await userWallet.claimDeposit(coopExit!.coopExitTxid);
117
+
118
+ await new Promise((resolve) => setTimeout(resolve, 1000));
119
+
120
+ expect(deposit).toBeDefined();
121
+ expect(deposit?.reduce((acc, leaf) => acc + leaf.value, 0)).toBe(5000);
122
+
123
+ const { balance: balance2 } = await userWallet.getBalance();
124
+
125
+ expect(balance2).toBe(DEPOSIT_AMOUNT - BigInt(fee));
62
126
  }, 60000);
63
127
  });
@@ -0,0 +1,47 @@
1
+ import { describe, expect, it } from "@jest/globals";
2
+ import { SparkWalletTesting } from "../../utils/spark-testing-wallet.js";
3
+ import { BitcoinFaucet } from "../../utils/test-faucet.js";
4
+
5
+ const DEPOSIT_AMOUNT = 10000n;
6
+
7
+ describe("SSP swap", () => {
8
+ it("it should swap with the SSP before sending a transfer if the user does not have exact leaf amount", async () => {
9
+ const faucet = BitcoinFaucet.getInstance();
10
+
11
+ const { wallet: userWallet } = await SparkWalletTesting.initialize(
12
+ {
13
+ options: {
14
+ network: "LOCAL",
15
+ },
16
+ },
17
+ false,
18
+ );
19
+
20
+ const depositAddress = await userWallet.getSingleUseDepositAddress();
21
+ expect(depositAddress).toBeDefined();
22
+
23
+ const signedTx = await faucet.sendToAddress(depositAddress, DEPOSIT_AMOUNT);
24
+
25
+ // Wait for the transaction to be mined
26
+ await faucet.mineBlocks(6);
27
+
28
+ expect(signedTx).toBeDefined();
29
+
30
+ const transactionId = signedTx.id;
31
+
32
+ await userWallet.claimDeposit(transactionId);
33
+
34
+ const { balance } = await userWallet.getBalance();
35
+ expect(balance).toBe(DEPOSIT_AMOUNT);
36
+
37
+ const sparkAddress = await userWallet.getSparkAddress();
38
+
39
+ await userWallet.transfer({
40
+ amountSats: 8191,
41
+ receiverSparkAddress: sparkAddress,
42
+ });
43
+
44
+ const { balance: receiverBalance } = await userWallet.getBalance();
45
+ expect(receiverBalance).toBe(balance);
46
+ }, 60000);
47
+ });