@buildonspark/spark-sdk 0.2.3 → 0.2.5

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 (91) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{chunk-3SEOTO43.js → chunk-3SPMJMUX.js} +3 -2
  3. package/dist/{chunk-CDLETEDT.js → chunk-CQY5ML2A.js} +16 -3
  4. package/dist/{chunk-PTRXJS7Q.js → chunk-LQZL2D3Y.js} +1 -1
  5. package/dist/{chunk-PLLJIZC3.js → chunk-U7LRIWTF.js} +2471 -822
  6. package/dist/{client-CcYzmpmj.d.cts → client-C88GCTPB.d.cts} +211 -104
  7. package/dist/{client-CGTRS23n.d.ts → client-Dg6vS_2I.d.ts} +211 -104
  8. package/dist/debug.cjs +2511 -831
  9. package/dist/debug.d.cts +19 -6
  10. package/dist/debug.d.ts +19 -6
  11. package/dist/debug.js +3 -3
  12. package/dist/graphql/objects/index.cjs +13 -1
  13. package/dist/graphql/objects/index.d.cts +6 -51
  14. package/dist/graphql/objects/index.d.ts +6 -51
  15. package/dist/graphql/objects/index.js +1 -1
  16. package/dist/index.cjs +2491 -797
  17. package/dist/index.d.cts +189 -9
  18. package/dist/index.d.ts +189 -9
  19. package/dist/index.js +32 -4
  20. package/dist/index.node.cjs +2596 -799
  21. package/dist/index.node.d.cts +9 -190
  22. package/dist/index.node.d.ts +9 -190
  23. package/dist/index.node.js +134 -4
  24. package/dist/native/index.cjs +2491 -797
  25. package/dist/native/index.d.cts +309 -174
  26. package/dist/native/index.d.ts +309 -174
  27. package/dist/native/index.js +2495 -814
  28. package/dist/proto/lrc20.d.cts +1 -1
  29. package/dist/proto/lrc20.d.ts +1 -1
  30. package/dist/proto/spark.d.cts +1 -1
  31. package/dist/proto/spark.d.ts +1 -1
  32. package/dist/proto/spark_token.d.cts +1 -1
  33. package/dist/proto/spark_token.d.ts +1 -1
  34. package/dist/{spark-B_7nZx6T.d.cts → spark-ESAfZARg.d.cts} +1 -1
  35. package/dist/{spark-B_7nZx6T.d.ts → spark-ESAfZARg.d.ts} +1 -1
  36. package/dist/{spark-wallet-CxcGPXRB.d.ts → spark-wallet-B2WwKN8W.d.ts} +57 -35
  37. package/dist/{spark-wallet-DJJm19BP.d.cts → spark-wallet-Di65w0Us.d.cts} +57 -35
  38. package/dist/spark-wallet.node-7R0Rxyj9.d.cts +13 -0
  39. package/dist/spark-wallet.node-CSPWOWRu.d.ts +13 -0
  40. package/dist/tests/test-utils.cjs +578 -77
  41. package/dist/tests/test-utils.d.cts +12 -13
  42. package/dist/tests/test-utils.d.ts +12 -13
  43. package/dist/tests/test-utils.js +54 -17
  44. package/dist/types/index.cjs +16 -3
  45. package/dist/types/index.d.cts +3 -4
  46. package/dist/types/index.d.ts +3 -4
  47. package/dist/types/index.js +2 -2
  48. package/dist/{xchain-address-Bh9w1SeC.d.ts → xchain-address-BsveIy5l.d.ts} +56 -8
  49. package/dist/{xchain-address-SZ7dkVUE.d.cts → xchain-address-CqRu3F21.d.cts} +56 -8
  50. package/package.json +1 -1
  51. package/src/graphql/client.ts +57 -8
  52. package/src/graphql/mutations/CompleteLeavesSwap.ts +9 -1
  53. package/src/graphql/mutations/RequestSwapLeaves.ts +4 -0
  54. package/src/graphql/objects/CompleteLeavesSwapInput.ts +34 -34
  55. package/src/graphql/objects/LeavesSwapRequest.ts +4 -0
  56. package/src/graphql/objects/RequestLeavesSwapInput.ts +48 -47
  57. package/src/graphql/objects/SparkWalletUser.ts +1 -1
  58. package/src/graphql/objects/SwapLeaf.ts +40 -32
  59. package/src/graphql/objects/UserLeafInput.ts +24 -0
  60. package/src/graphql/objects/UserRequest.ts +4 -0
  61. package/src/graphql/queries/Transfers.ts +15 -0
  62. package/src/index.node.ts +1 -1
  63. package/src/native/index.ts +4 -5
  64. package/src/services/coop-exit.ts +171 -36
  65. package/src/services/deposit.ts +471 -74
  66. package/src/services/lightning.ts +18 -5
  67. package/src/services/signing.ts +162 -50
  68. package/src/services/transfer.ts +950 -384
  69. package/src/services/tree-creation.ts +342 -121
  70. package/src/spark-wallet/spark-wallet.node.ts +71 -66
  71. package/src/spark-wallet/spark-wallet.ts +561 -192
  72. package/src/tests/integration/coop-exit.test.ts +3 -8
  73. package/src/tests/integration/deposit.test.ts +3 -3
  74. package/src/tests/integration/lightning.test.ts +521 -466
  75. package/src/tests/integration/ssp/static_deposit.test.ts +83 -1
  76. package/src/tests/integration/ssp/transfers.test.ts +97 -0
  77. package/src/tests/integration/swap.test.ts +559 -307
  78. package/src/tests/integration/transfer.test.ts +625 -623
  79. package/src/tests/integration/wallet.test.ts +2 -2
  80. package/src/tests/integration/watchtower.test.ts +211 -0
  81. package/src/tests/test-utils.ts +63 -14
  82. package/src/tests/utils/test-faucet.ts +4 -2
  83. package/src/types/sdk-types.ts +15 -0
  84. package/src/utils/adaptor-signature.ts +15 -5
  85. package/src/utils/bitcoin.ts +13 -0
  86. package/src/utils/fetch.ts +75 -0
  87. package/src/utils/mempool.ts +9 -4
  88. package/src/utils/transaction.ts +388 -26
  89. package/dist/sdk-types-CB9HrW5O.d.cts +0 -44
  90. package/dist/sdk-types-CkRNraXT.d.ts +0 -44
  91. package/src/graphql/queries/Transfer.ts +0 -10
@@ -1,9 +1,9 @@
1
1
  import { describe, expect, it } from "@jest/globals";
2
- import { equalBytes, hexToBytes } from "@noble/curves/abstract/utils";
2
+ import { hexToBytes } from "@noble/curves/abstract/utils";
3
3
  import { secp256k1 } from "@noble/curves/secp256k1";
4
4
  import { uuidv7 } from "uuidv7";
5
5
  import { ValidationError } from "../../errors/types.js";
6
- import { KeyDerivation, KeyDerivationType } from "../../index.js";
6
+ import { KeyDerivationType } from "../../index.js";
7
7
  import { WalletConfigService } from "../../services/config.js";
8
8
  import { ConnectionManager } from "../../services/connection.js";
9
9
  import { SigningService } from "../../services/signing.js";
@@ -12,146 +12,249 @@ import { TransferService } from "../../services/transfer.js";
12
12
  import {
13
13
  applyAdaptorToSignature,
14
14
  generateAdaptorFromSignature,
15
+ validateOutboundAdaptorSignature,
15
16
  } from "../../utils/adaptor-signature.js";
16
17
  import {
17
18
  computeTaprootKeyNoScript,
18
19
  getSigHashFromTx,
19
20
  } from "../../utils/bitcoin.js";
20
- import { createNewTree, signerTypes } from "../test-utils.js";
21
+ import { walletTypes } from "../test-utils.js";
21
22
  import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
22
23
  import { BitcoinFaucet } from "../utils/test-faucet.js";
23
24
 
24
25
  const testLocalOnly = process.env.GITHUB_ACTIONS ? it.skip : it;
25
26
 
26
- describe.each(signerTypes)("swap", ({ name, Signer }) => {
27
+ describe.each(walletTypes)("swap", ({ name, Signer, createTree }) => {
28
+ let aliceWallet: SparkWalletTesting;
29
+ let aliceTransferService: TransferService;
30
+
31
+ let bobWallet: SparkWalletTesting;
32
+ let bobTransferService: TransferService;
33
+
34
+ beforeAll(async () => {
35
+ const { wallet: alice } = await SparkWalletTesting.initialize({
36
+ options: {
37
+ network: "LOCAL",
38
+ },
39
+ signer: new Signer(),
40
+ });
41
+ aliceWallet = alice;
42
+ const aliceConfig = new WalletConfigService(
43
+ {
44
+ network: "LOCAL",
45
+ },
46
+ alice.getSigner(),
47
+ );
48
+ const aliceConnectionManager = new ConnectionManager(aliceConfig);
49
+ const aliceSigningService = new SigningService(aliceConfig);
50
+ aliceTransferService = new TransferService(
51
+ aliceConfig,
52
+ aliceConnectionManager,
53
+ aliceSigningService,
54
+ );
55
+
56
+ const { wallet: bob } = await SparkWalletTesting.initialize({
57
+ options: {
58
+ network: "LOCAL",
59
+ },
60
+ signer: new Signer(),
61
+ });
62
+ bobWallet = bob;
63
+ const bobConfig = new WalletConfigService(
64
+ {
65
+ network: "LOCAL",
66
+ },
67
+ bobWallet.getSigner(),
68
+ );
69
+ const bobConnectionManager = new ConnectionManager(bobConfig);
70
+ const bobSigningService = new SigningService(bobConfig);
71
+ bobTransferService = new TransferService(
72
+ bobConfig,
73
+ bobConnectionManager,
74
+ bobSigningService,
75
+ );
76
+ });
77
+
27
78
  testLocalOnly(
28
- `${name} - test swap`,
79
+ `${name} - test swap v1`,
29
80
  async () => {
30
81
  const faucet = BitcoinFaucet.getInstance();
31
- // Initiate sender
32
- const { wallet: senderWallet } = await SparkWalletTesting.initialize({
33
- options: {
34
- network: "LOCAL",
35
- },
36
- signer: new Signer(),
37
- });
38
- const senderPubkey = await senderWallet.getIdentityPublicKey();
39
82
 
40
- const senderConfig = new WalletConfigService(
41
- {
42
- network: "LOCAL",
43
- },
44
- senderWallet.getSigner(),
45
- );
46
- const senderConnectionManager = new ConnectionManager(senderConfig);
47
- const senderSigningService = new SigningService(senderConfig);
48
- const senderTransferService = new TransferService(
49
- senderConfig,
50
- senderConnectionManager,
51
- senderSigningService,
52
- );
53
-
54
- // Initiate receiver
55
- const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
56
- options: {
57
- network: "LOCAL",
58
- },
59
- signer: new Signer(),
60
- });
61
- const receiverPubkey = await receiverWallet.getIdentityPublicKey();
62
-
63
- const receiverConfig = new WalletConfigService(
64
- {
65
- network: "LOCAL",
66
- },
67
- receiverWallet.getSigner(),
68
- );
69
- const receiverConnectionManager = new ConnectionManager(receiverConfig);
70
- const receiverSigningService = new SigningService(receiverConfig);
71
- const receiverTransferService = new TransferService(
72
- receiverConfig,
73
- receiverConnectionManager,
74
- receiverSigningService,
75
- );
76
-
77
- const senderLeafId = uuidv7();
78
- const senderRootNode = await createNewTree(
79
- senderWallet,
80
- senderLeafId,
81
- faucet,
82
- );
83
+ const aliceLeafId = uuidv7();
84
+ const aliceRootNode = await createTree(aliceWallet!, aliceLeafId, faucet);
83
85
 
84
- const receiverLeafId = uuidv7();
85
- const receiverRootNode = await createNewTree(
86
- receiverWallet,
87
- receiverLeafId,
88
- faucet,
89
- );
86
+ const bobLeafId = uuidv7();
87
+ const bobRootNode = await createTree(bobWallet!, bobLeafId, faucet);
90
88
 
91
- // Sender initiates transfer
92
- const senderNewLeafId = uuidv7();
93
- const senderTransferNode: LeafKeyTweak = {
94
- leaf: senderRootNode,
89
+ const aliceTransferNode: LeafKeyTweak = {
90
+ leaf: aliceRootNode,
95
91
  keyDerivation: {
96
92
  type: KeyDerivationType.LEAF,
97
- path: senderLeafId,
93
+ path: aliceLeafId,
98
94
  },
99
95
  newKeyDerivation: {
100
- type: KeyDerivationType.LEAF,
101
- path: senderNewLeafId,
96
+ type: KeyDerivationType.RANDOM,
102
97
  },
103
98
  };
104
- const senderLeavesToTransfer = [senderTransferNode];
99
+ const aliceLeavesToTransfer = [aliceTransferNode];
105
100
 
106
- // Get signature for refunds (normal flow)
107
101
  const {
108
- transfer: senderTransfer,
109
- signatureMap: senderRefundSignatureMap,
110
- leafDataMap: senderLeafDataMap,
111
- } = await senderTransferService.startSwapSignRefund(
112
- senderLeavesToTransfer,
113
- hexToBytes(receiverPubkey),
102
+ transfer: aliceTransfer,
103
+ signatureMap: aliceRefundSignatureMap,
104
+ leafDataMap: aliceLeafDataMap,
105
+ directSignatureMap: aliceDirectRefundSignatureMap,
106
+ directFromCpfpSignatureMap: aliceDirectFromCpfpSignatureMap,
107
+ } = await aliceTransferService!.startSwapSignRefund(
108
+ aliceLeavesToTransfer,
109
+ hexToBytes(await bobWallet.getIdentityPublicKey()),
114
110
  new Date(Date.now() + 10 * 60 * 1000),
115
111
  );
116
112
 
117
- expect(senderRefundSignatureMap.size).toBe(1);
118
- const senderSignature = senderRefundSignatureMap.get(senderRootNode.id);
119
- expect(senderSignature).toBeDefined();
120
- expect(senderLeafDataMap.size).toBe(1);
113
+ expect(aliceRefundSignatureMap.size).toBe(1);
114
+ const aliceSignature = aliceRefundSignatureMap.get(aliceRootNode.id);
121
115
 
122
- const { adaptorPrivateKey, adaptorSignature } =
123
- generateAdaptorFromSignature(senderSignature!);
124
- const adaptorPubKey = secp256k1.getPublicKey(adaptorPrivateKey);
116
+ expect(aliceSignature).toBeDefined();
117
+ expect(aliceDirectRefundSignatureMap.size).toBe(1);
118
+ const aliceDirectSignature = aliceDirectRefundSignatureMap.get(
119
+ aliceRootNode.id,
120
+ );
121
+ expect(aliceDirectSignature).toBeDefined();
122
+ expect(aliceDirectFromCpfpSignatureMap.size).toBe(1);
123
+ const aliceDirectFromCpfpSignature = aliceDirectFromCpfpSignatureMap.get(
124
+ aliceRootNode.id,
125
+ );
126
+ expect(aliceDirectFromCpfpSignature).toBeDefined();
127
+ expect(aliceLeafDataMap.size).toBe(1);
128
+ const aliceLeafData = aliceLeafDataMap.get(aliceRootNode.id);
129
+ expect(aliceLeafData).toBeDefined();
130
+
131
+ const aliceRefundSighash = getSigHashFromTx(
132
+ aliceLeafData!.refundTx!,
133
+ 0,
134
+ aliceLeafData!.tx.getOutput(aliceLeafData!.vout),
135
+ );
136
+
137
+ let aliceDirectSighash: Uint8Array | undefined;
138
+ let aliceDirectFromCpfpSighash: Uint8Array | undefined;
139
+ if (aliceLeafData!.directRefundTx) {
140
+ aliceDirectSighash = getSigHashFromTx(
141
+ aliceLeafData!.directRefundTx,
142
+ 0,
143
+ aliceLeafData!.directTx!.getOutput(aliceLeafData!.vout),
144
+ );
145
+ }
146
+ if (aliceLeafData!.directFromCpfpRefundTx) {
147
+ aliceDirectFromCpfpSighash = getSigHashFromTx(
148
+ aliceLeafData!.directFromCpfpRefundTx,
149
+ 0,
150
+ aliceLeafData!.tx.getOutput(aliceLeafData!.vout),
151
+ );
152
+ }
153
+
154
+ const {
155
+ adaptorSignature: cpfpAdaptorSignature,
156
+ adaptorPrivateKey: cpfpAdaptorPrivateKey,
157
+ } = generateAdaptorFromSignature(aliceSignature!);
158
+
159
+ let directAdaptorPrivateKey: Uint8Array | undefined;
160
+ let directFromCpfpAdaptorPrivateKey: Uint8Array | undefined;
161
+ let directAdaptorSignature: Uint8Array | undefined;
162
+ let directFromCpfpAdaptorSignature: Uint8Array | undefined;
163
+ if (aliceDirectSignature && aliceDirectSignature.length > 0) {
164
+ const { adaptorSignature, adaptorPrivateKey } =
165
+ generateAdaptorFromSignature(aliceDirectSignature);
166
+ directAdaptorPrivateKey = adaptorPrivateKey;
167
+ directAdaptorSignature = adaptorSignature;
168
+ }
169
+ if (
170
+ aliceDirectFromCpfpSignature &&
171
+ aliceDirectFromCpfpSignature.length > 0
172
+ ) {
173
+ const { adaptorSignature, adaptorPrivateKey } =
174
+ generateAdaptorFromSignature(aliceDirectFromCpfpSignature);
175
+ directFromCpfpAdaptorPrivateKey = adaptorPrivateKey;
176
+ directFromCpfpAdaptorSignature = adaptorSignature;
177
+ }
178
+
179
+ const cpfpAdaptorPubKey = secp256k1.getPublicKey(cpfpAdaptorPrivateKey);
180
+
181
+ let directAdaptorPubKey: Uint8Array | undefined;
182
+ let directFromCpfpAdaptorPubKey: Uint8Array | undefined;
183
+ if (directAdaptorPrivateKey) {
184
+ directAdaptorPubKey = secp256k1.getPublicKey(directAdaptorPrivateKey);
185
+ }
186
+ if (directFromCpfpAdaptorPrivateKey) {
187
+ directFromCpfpAdaptorPubKey = secp256k1.getPublicKey(
188
+ directFromCpfpAdaptorPrivateKey,
189
+ );
190
+ }
191
+
192
+ const taprootKey = computeTaprootKeyNoScript(
193
+ aliceRootNode.verifyingPublicKey.slice(1, 33),
194
+ );
195
+
196
+ validateOutboundAdaptorSignature(
197
+ taprootKey.slice(1, 33),
198
+ aliceRefundSighash,
199
+ cpfpAdaptorSignature,
200
+ cpfpAdaptorPubKey,
201
+ );
202
+
203
+ if (aliceDirectSighash) {
204
+ validateOutboundAdaptorSignature(
205
+ taprootKey.slice(1, 33),
206
+ aliceDirectSighash,
207
+ directAdaptorSignature!,
208
+ directAdaptorPubKey!,
209
+ );
210
+ }
211
+
212
+ if (aliceDirectFromCpfpSighash) {
213
+ validateOutboundAdaptorSignature(
214
+ taprootKey.slice(1, 33),
215
+ aliceDirectFromCpfpSighash,
216
+ directFromCpfpAdaptorSignature!,
217
+ directFromCpfpAdaptorPubKey!,
218
+ );
219
+ }
125
220
 
126
- const receiverNewLeafDerivation: KeyDerivation = {
127
- type: KeyDerivationType.LEAF,
128
- path: uuidv7(),
129
- };
130
221
  const receiverTransferNode: LeafKeyTweak = {
131
- leaf: receiverRootNode,
222
+ leaf: bobRootNode,
132
223
  keyDerivation: {
133
224
  type: KeyDerivationType.LEAF,
134
- path: receiverLeafId,
225
+ path: bobLeafId,
226
+ },
227
+ newKeyDerivation: {
228
+ type: KeyDerivationType.RANDOM,
135
229
  },
136
- newKeyDerivation: receiverNewLeafDerivation,
137
230
  };
138
231
  const receiverLeavesToTransfer = [receiverTransferNode];
139
232
 
140
233
  const {
141
- transfer: receiverTransfer,
142
- signatureMap: receiverRefundSignatureMap,
143
- leafDataMap: receiverLeafDataMap,
144
- signingResults: operatorSigningResults,
145
- } = await receiverTransferService.counterSwapSignRefund(
234
+ transfer: bobTransfer,
235
+ signatureMap: bobRefundSignatureMap,
236
+ directSignatureMap: bobDirectRefundSignatureMap,
237
+ directFromCpfpSignatureMap: bobDirectFromCpfpSignatureMap,
238
+ leafDataMap: bobLeafDataMap,
239
+ signingResults: bobSigningResults,
240
+ } = await bobTransferService.counterSwapSignRefund(
146
241
  receiverLeavesToTransfer,
147
- hexToBytes(senderPubkey),
242
+ hexToBytes(await aliceWallet.getIdentityPublicKey()),
148
243
  new Date(Date.now() + 10 * 60 * 1000),
149
- adaptorPubKey,
244
+ cpfpAdaptorPubKey,
245
+ directAdaptorPubKey,
246
+ directFromCpfpAdaptorPubKey,
150
247
  );
151
248
 
152
249
  const newReceiverRefundSignatureMap = new Map<string, Uint8Array>();
153
- for (const [nodeId, signature] of receiverRefundSignatureMap.entries()) {
154
- const leafData = receiverLeafDataMap.get(nodeId);
250
+ const newReceiverDirectRefundSignatureMap = new Map<string, Uint8Array>();
251
+ const newReceiverDirectFromCpfpRefundSignatureMap = new Map<
252
+ string,
253
+ Uint8Array
254
+ >();
255
+
256
+ for (const [nodeId, signature] of bobRefundSignatureMap.entries()) {
257
+ const leafData = bobLeafDataMap.get(nodeId);
155
258
  if (!leafData?.refundTx) {
156
259
  throw new ValidationError("Refund transaction not found", {
157
260
  field: "refundTx",
@@ -164,7 +267,7 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
164
267
  leafData.tx.getOutput(leafData.vout),
165
268
  );
166
269
  let verifyingPubkey: Uint8Array | undefined;
167
- for (const signingResult of operatorSigningResults) {
270
+ for (const signingResult of bobSigningResults) {
168
271
  if (signingResult.leafId === nodeId) {
169
272
  verifyingPubkey = signingResult.verifyingKey;
170
273
  }
@@ -177,89 +280,137 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
177
280
  taprootKey.slice(1, 33),
178
281
  sighash,
179
282
  signature,
180
- adaptorPrivateKey,
283
+ cpfpAdaptorPrivateKey,
181
284
  );
182
285
  newReceiverRefundSignatureMap.set(nodeId, adaptorSig);
183
286
  }
184
- const senderTransferTweakKey =
185
- await senderTransferService.sendTransferTweakKey(
186
- senderTransfer,
187
- senderLeavesToTransfer,
188
- senderRefundSignatureMap,
287
+
288
+ for (const [nodeId, signature] of bobDirectRefundSignatureMap.entries()) {
289
+ const leafData = bobLeafDataMap.get(nodeId);
290
+ if (!leafData?.directRefundTx) {
291
+ continue;
292
+ }
293
+ const sighash = getSigHashFromTx(
294
+ leafData.directRefundTx,
295
+ 0,
296
+ leafData.directTx!.getOutput(leafData.vout),
297
+ );
298
+ let verifyingPubkey: Uint8Array | undefined;
299
+ for (const signingResult of bobSigningResults) {
300
+ if (signingResult.leafId === nodeId) {
301
+ verifyingPubkey = signingResult.verifyingKey;
302
+ }
303
+ }
304
+ expect(verifyingPubkey).toBeDefined();
305
+ const taprootKey = computeTaprootKeyNoScript(
306
+ verifyingPubkey!.slice(1, 33),
307
+ );
308
+ const adaptorSig = applyAdaptorToSignature(
309
+ taprootKey.slice(1, 33),
310
+ sighash,
311
+ signature,
312
+ directAdaptorPrivateKey ?? new Uint8Array(),
189
313
  );
314
+ newReceiverDirectRefundSignatureMap.set(nodeId, adaptorSig);
315
+ }
190
316
 
191
- const pendingTransfer =
192
- await receiverTransferService.queryPendingTransfers();
193
- expect(pendingTransfer.transfers.length).toBe(1);
194
- const receiverPendingTransfer = pendingTransfer.transfers[0];
195
- expect(receiverPendingTransfer!.id).toBe(senderTransferTweakKey.id);
317
+ for (const [
318
+ nodeId,
319
+ signature,
320
+ ] of bobDirectFromCpfpSignatureMap.entries()) {
321
+ const leafData = bobLeafDataMap.get(nodeId);
322
+ if (!leafData?.directFromCpfpRefundTx) {
323
+ continue;
324
+ }
325
+ const sighash = getSigHashFromTx(
326
+ leafData.directFromCpfpRefundTx,
327
+ 0,
328
+ leafData.tx.getOutput(leafData.vout),
329
+ );
330
+ let verifyingPubkey: Uint8Array | undefined;
331
+ for (const signingResult of bobSigningResults) {
332
+ if (signingResult.leafId === nodeId) {
333
+ verifyingPubkey = signingResult.verifyingKey;
334
+ }
335
+ }
336
+ expect(verifyingPubkey).toBeDefined();
337
+ const taprootKey = computeTaprootKeyNoScript(
338
+ verifyingPubkey!.slice(1, 33),
339
+ );
340
+ const adaptorSig = applyAdaptorToSignature(
341
+ taprootKey.slice(1, 33),
342
+ sighash,
343
+ signature,
344
+ directFromCpfpAdaptorPrivateKey ?? new Uint8Array(),
345
+ );
346
+ newReceiverDirectFromCpfpRefundSignatureMap.set(nodeId, adaptorSig);
347
+ }
196
348
 
197
- const leafPrivKeyMap =
198
- await receiverTransferService.verifyPendingTransfer(
199
- receiverPendingTransfer!,
349
+ const senderTransferTweakKey =
350
+ await aliceTransferService.sendTransferTweakKey(
351
+ aliceTransfer,
352
+ aliceLeavesToTransfer,
353
+ aliceRefundSignatureMap,
354
+ aliceDirectRefundSignatureMap,
355
+ aliceDirectFromCpfpSignatureMap,
200
356
  );
201
357
 
202
- expect(leafPrivKeyMap.size).toBe(1);
203
- expect(leafPrivKeyMap.get(senderRootNode.id)).toBeDefined();
204
- const bytesEqual = equalBytes(
205
- leafPrivKeyMap.get(senderRootNode.id)!,
206
- await senderWallet
207
- .getSigner()
208
- .getPublicKeyFromDerivation(senderTransferNode.newKeyDerivation),
358
+ const pendingTransfer = await bobTransferService.queryPendingTransfers();
359
+ expect(pendingTransfer.transfers.length).toBe(1);
360
+ const bobPendingTransfer = pendingTransfer.transfers[0];
361
+ expect(bobPendingTransfer!.id).toBe(senderTransferTweakKey.id);
362
+
363
+ const leafPrivKeyMap = await bobTransferService.verifyPendingTransfer(
364
+ bobPendingTransfer!,
209
365
  );
210
- expect(bytesEqual).toBe(true);
211
- expect(receiverPendingTransfer!.leaves[0]!.leaf).toBeDefined();
366
+ expect(leafPrivKeyMap.size).toBe(1);
367
+ expect(leafPrivKeyMap.get(aliceRootNode.id)).toBeDefined();
212
368
 
213
- const claimingNodes: LeafKeyTweak[] = receiverPendingTransfer!.leaves.map(
369
+ const claimingNodes: LeafKeyTweak[] = bobPendingTransfer!.leaves.map(
214
370
  (leaf) => ({
215
371
  leaf: leaf.leaf!,
216
372
  keyDerivation: {
217
373
  type: KeyDerivationType.ECIES,
218
- path: leaf.secretCipher,
374
+ path: leaf.secretCipher!,
219
375
  },
220
376
  newKeyDerivation: {
221
377
  type: KeyDerivationType.LEAF,
222
- path: senderNewLeafId,
378
+ path: leaf.leaf!.id,
223
379
  },
224
380
  }),
225
381
  );
226
- await receiverTransferService.claimTransfer(
227
- receiverPendingTransfer!,
382
+
383
+ await bobTransferService.claimTransfer(
384
+ bobPendingTransfer!,
228
385
  claimingNodes,
229
386
  );
230
- await receiverTransferService.sendTransferTweakKey(
231
- receiverTransfer,
232
- receiverLeavesToTransfer,
233
- newReceiverRefundSignatureMap,
234
- );
235
-
236
- const sPendingTransfer =
237
- await senderTransferService.queryPendingTransfers();
238
- expect(sPendingTransfer.transfers.length).toBe(1);
239
- const senderPendingTransfer = sPendingTransfer.transfers[0];
240
- expect(senderPendingTransfer!.id).toBe(receiverTransfer.id);
241
387
 
242
- const senderLeafPrivKeyMap =
243
- await senderTransferService.verifyPendingTransfer(
244
- senderPendingTransfer!,
388
+ const senderTransferTweakKey2 =
389
+ await bobTransferService.sendTransferTweakKey(
390
+ bobTransfer,
391
+ receiverLeavesToTransfer,
392
+ newReceiverRefundSignatureMap,
393
+ newReceiverDirectRefundSignatureMap,
394
+ newReceiverDirectFromCpfpRefundSignatureMap,
245
395
  );
246
- expect(senderLeafPrivKeyMap.size).toBe(1);
247
- expect(senderLeafPrivKeyMap.get(receiverRootNode.id)).toBeDefined();
248
- const bytesEqual_1 = equalBytes(
249
- senderLeafPrivKeyMap.get(receiverRootNode.id)!,
250
- await receiverWallet
251
- .getSigner()
252
- .getPublicKeyFromDerivation(receiverNewLeafDerivation),
396
+
397
+ const pendingTransfer2 =
398
+ await aliceTransferService.queryPendingTransfers();
399
+ expect(pendingTransfer2.transfers.length).toBe(1);
400
+ const alicePendingTransfer2 = pendingTransfer2.transfers[0];
401
+ expect(alicePendingTransfer2!.id).toBe(senderTransferTweakKey2.id);
402
+
403
+ const leafPrivKeyMap2 = await aliceTransferService.verifyPendingTransfer(
404
+ alicePendingTransfer2!,
253
405
  );
254
- expect(bytesEqual_1).toBe(true);
255
- expect(senderPendingTransfer!.leaves[0]!.leaf).toBeDefined();
406
+ expect(leafPrivKeyMap2.size).toBe(1);
256
407
 
257
- const claimingNodes_1: LeafKeyTweak[] = senderPendingTransfer!.leaves.map(
408
+ const claimingNodes2: LeafKeyTweak[] = alicePendingTransfer2!.leaves.map(
258
409
  (leaf) => ({
259
410
  leaf: leaf.leaf!,
260
411
  keyDerivation: {
261
412
  type: KeyDerivationType.ECIES,
262
- path: leaf.secretCipher,
413
+ path: leaf.secretCipher!,
263
414
  },
264
415
  newKeyDerivation: {
265
416
  type: KeyDerivationType.LEAF,
@@ -267,143 +418,196 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
267
418
  },
268
419
  }),
269
420
  );
270
- await senderTransferService.claimTransfer(
271
- senderPendingTransfer!,
272
- claimingNodes_1,
421
+
422
+ await aliceTransferService.claimTransfer(
423
+ alicePendingTransfer2!,
424
+ claimingNodes2,
273
425
  );
274
426
  },
275
- 30000,
427
+ 30_000,
276
428
  );
277
429
 
278
430
  testLocalOnly(
279
431
  `${name} - test swap v2`,
280
432
  async () => {
281
433
  const faucet = BitcoinFaucet.getInstance();
282
- // Initiate sender
283
- const { wallet: senderWallet } = await SparkWalletTesting.initialize({
284
- options: {
285
- network: "LOCAL",
286
- },
287
- signer: new Signer(),
288
- });
289
- const senderPubkey = await senderWallet.getIdentityPublicKey();
290
434
 
291
- const senderConfig = new WalletConfigService(
292
- {
293
- network: "LOCAL",
294
- },
295
- senderWallet.getSigner(),
296
- );
297
- const senderConnectionManager = new ConnectionManager(senderConfig);
298
- const senderSigningService = new SigningService(senderConfig);
299
- const senderTransferService = new TransferService(
300
- senderConfig,
301
- senderConnectionManager,
302
- senderSigningService,
303
- );
435
+ const aliceLeafId = uuidv7();
436
+ const aliceRootNode = await createTree(aliceWallet!, aliceLeafId, faucet);
304
437
 
305
- // Initiate receiver
306
- const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
307
- options: {
308
- network: "LOCAL",
309
- },
310
- signer: new Signer(),
311
- });
312
- const receiverPubkey = await receiverWallet.getIdentityPublicKey();
438
+ const bobLeafId = uuidv7();
439
+ const bobRootNode = await createTree(bobWallet!, bobLeafId, faucet);
313
440
 
314
- const receiverConfig = new WalletConfigService(
315
- {
316
- network: "LOCAL",
441
+ const aliceTransferNode: LeafKeyTweak = {
442
+ leaf: aliceRootNode,
443
+ keyDerivation: {
444
+ type: KeyDerivationType.LEAF,
445
+ path: aliceLeafId,
446
+ },
447
+ newKeyDerivation: {
448
+ type: KeyDerivationType.RANDOM,
317
449
  },
318
- receiverWallet.getSigner(),
450
+ };
451
+ const aliceLeavesToTransfer = [aliceTransferNode];
452
+
453
+ const {
454
+ transfer: aliceTransfer,
455
+ signatureMap: aliceRefundSignatureMap,
456
+ directSignatureMap: aliceDirectRefundSignatureMap,
457
+ directFromCpfpSignatureMap: aliceDirectFromCpfpSignatureMap,
458
+ leafDataMap: aliceLeafDataMap,
459
+ } = await aliceTransferService.startSwapSignRefund(
460
+ aliceLeavesToTransfer,
461
+ hexToBytes(await bobWallet.getIdentityPublicKey()),
462
+ new Date(Date.now() + 10 * 60 * 1000),
319
463
  );
320
- const receiverConnectionManager = new ConnectionManager(receiverConfig);
321
- const receiverSigningService = new SigningService(receiverConfig);
322
- const receiverTransferService = new TransferService(
323
- receiverConfig,
324
- receiverConnectionManager,
325
- receiverSigningService,
464
+
465
+ expect(aliceRefundSignatureMap.size).toBe(1);
466
+ const aliceSignature = aliceRefundSignatureMap.get(aliceRootNode.id);
467
+ expect(aliceSignature).toBeDefined();
468
+
469
+ expect(aliceDirectRefundSignatureMap.size).toBe(1);
470
+ const aliceDirectSignature = aliceDirectRefundSignatureMap.get(
471
+ aliceRootNode.id,
326
472
  );
473
+ expect(aliceDirectSignature).toBeDefined();
327
474
 
328
- const senderLeafId = uuidv7();
329
- const senderRootNode = await createNewTree(
330
- senderWallet,
331
- senderLeafId,
332
- faucet,
475
+ expect(aliceDirectFromCpfpSignatureMap.size).toBe(1);
476
+ const aliceDirectFromCpfpSignature = aliceDirectFromCpfpSignatureMap.get(
477
+ aliceRootNode.id,
333
478
  );
479
+ expect(aliceDirectFromCpfpSignature).toBeDefined();
334
480
 
335
- const receiverLeafId = uuidv7();
336
- const receiverRootNode = await createNewTree(
337
- receiverWallet,
338
- receiverLeafId,
339
- faucet,
481
+ expect(aliceLeafDataMap.size).toBe(1);
482
+ const aliceLeafData = aliceLeafDataMap.get(aliceRootNode.id);
483
+ expect(aliceLeafData).toBeDefined();
484
+
485
+ const aliceRefundSighash = getSigHashFromTx(
486
+ aliceLeafData!.refundTx!,
487
+ 0,
488
+ aliceLeafData!.tx.getOutput(aliceLeafData!.vout),
340
489
  );
341
490
 
342
- // Sender initiates transfer
343
- const senderNewLeafDerivation: KeyDerivation = {
344
- type: KeyDerivationType.LEAF,
345
- path: uuidv7(),
346
- };
347
- const senderTransferNode: LeafKeyTweak = {
348
- leaf: senderRootNode,
349
- keyDerivation: {
350
- type: KeyDerivationType.LEAF,
351
- path: senderLeafId,
352
- },
353
- newKeyDerivation: senderNewLeafDerivation,
354
- };
355
- const senderLeavesToTransfer = [senderTransferNode];
491
+ let aliceDirectSighash: Uint8Array | undefined;
492
+ let aliceDirectFromCpfpSighash: Uint8Array | undefined;
493
+ if (aliceLeafData!.directRefundTx) {
494
+ aliceDirectSighash = getSigHashFromTx(
495
+ aliceLeafData!.directRefundTx,
496
+ 0,
497
+ aliceLeafData!.directTx!.getOutput(aliceLeafData!.vout),
498
+ );
499
+ }
500
+ if (aliceLeafData!.directFromCpfpRefundTx) {
501
+ aliceDirectFromCpfpSighash = getSigHashFromTx(
502
+ aliceLeafData!.directFromCpfpRefundTx,
503
+ 0,
504
+ aliceLeafData!.tx.getOutput(aliceLeafData!.vout),
505
+ );
506
+ }
356
507
 
357
- // Get signature for refunds (normal flow)
358
508
  const {
359
- transfer: senderTransfer,
360
- signatureMap: senderRefundSignatureMap,
361
- leafDataMap: senderLeafDataMap,
362
- } = await senderTransferService.startSwapSignRefund(
363
- senderLeavesToTransfer,
364
- hexToBytes(receiverPubkey),
365
- new Date(Date.now() + 10 * 60 * 1000),
366
- );
509
+ adaptorSignature: cpfpAdaptorSignature,
510
+ adaptorPrivateKey: cpfpAdaptorPrivateKey,
511
+ } = generateAdaptorFromSignature(aliceSignature!);
512
+
513
+ let directAdaptorPrivateKey: Uint8Array | undefined;
514
+ let directFromCpfpAdaptorPrivateKey: Uint8Array | undefined;
515
+ let directAdaptorSignature: Uint8Array | undefined;
516
+ let directFromCpfpAdaptorSignature: Uint8Array | undefined;
517
+ if (aliceDirectSignature && aliceDirectSignature.length > 0) {
518
+ const { adaptorSignature, adaptorPrivateKey } =
519
+ generateAdaptorFromSignature(aliceDirectSignature);
520
+ directAdaptorPrivateKey = adaptorPrivateKey;
521
+ directAdaptorSignature = adaptorSignature;
522
+ }
523
+ if (
524
+ aliceDirectFromCpfpSignature &&
525
+ aliceDirectFromCpfpSignature.length > 0
526
+ ) {
527
+ const { adaptorSignature, adaptorPrivateKey } =
528
+ generateAdaptorFromSignature(aliceDirectFromCpfpSignature);
529
+ directFromCpfpAdaptorPrivateKey = adaptorPrivateKey;
530
+ directFromCpfpAdaptorSignature = adaptorSignature;
531
+ }
367
532
 
368
- expect(senderRefundSignatureMap.size).toBe(1);
369
- const senderSignature = senderRefundSignatureMap.get(senderRootNode.id);
370
- expect(senderSignature).toBeDefined();
371
- expect(senderLeafDataMap.size).toBe(1);
533
+ const cpfpAdaptorPubKey = secp256k1.getPublicKey(cpfpAdaptorPrivateKey);
372
534
 
373
- const { adaptorPrivateKey } = generateAdaptorFromSignature(
374
- senderSignature!,
535
+ let directAdaptorPubKey: Uint8Array | undefined;
536
+ let directFromCpfpAdaptorPubKey: Uint8Array | undefined;
537
+ if (directAdaptorPrivateKey) {
538
+ directAdaptorPubKey = secp256k1.getPublicKey(directAdaptorPrivateKey);
539
+ }
540
+ if (directFromCpfpAdaptorPrivateKey) {
541
+ directFromCpfpAdaptorPubKey = secp256k1.getPublicKey(
542
+ directFromCpfpAdaptorPrivateKey,
543
+ );
544
+ }
545
+
546
+ const taprootKey = computeTaprootKeyNoScript(
547
+ aliceRootNode.verifyingPublicKey.slice(1, 33),
375
548
  );
376
- const adaptorPubKey = secp256k1.getPublicKey(adaptorPrivateKey);
377
549
 
378
- const receiverNewLeafDerivation: KeyDerivation = {
379
- type: KeyDerivationType.LEAF,
380
- path: uuidv7(),
381
- };
550
+ validateOutboundAdaptorSignature(
551
+ taprootKey.slice(1, 33),
552
+ aliceRefundSighash,
553
+ cpfpAdaptorSignature,
554
+ cpfpAdaptorPubKey,
555
+ );
556
+
557
+ if (aliceDirectSighash) {
558
+ validateOutboundAdaptorSignature(
559
+ taprootKey.slice(1, 33),
560
+ aliceDirectSighash,
561
+ directAdaptorSignature!,
562
+ directAdaptorPubKey!,
563
+ );
564
+ }
565
+
566
+ if (aliceDirectFromCpfpSighash) {
567
+ validateOutboundAdaptorSignature(
568
+ taprootKey.slice(1, 33),
569
+ aliceDirectFromCpfpSighash,
570
+ directFromCpfpAdaptorSignature!,
571
+ directFromCpfpAdaptorPubKey!,
572
+ );
573
+ }
574
+
382
575
  const receiverTransferNode: LeafKeyTweak = {
383
- leaf: receiverRootNode,
576
+ leaf: bobRootNode,
384
577
  keyDerivation: {
385
578
  type: KeyDerivationType.LEAF,
386
- path: receiverLeafId,
579
+ path: bobLeafId,
580
+ },
581
+ newKeyDerivation: {
582
+ type: KeyDerivationType.RANDOM,
387
583
  },
388
- newKeyDerivation: receiverNewLeafDerivation,
389
584
  };
390
585
  const receiverLeavesToTransfer = [receiverTransferNode];
391
586
 
392
587
  const {
393
- transfer: receiverTransfer,
394
- signatureMap: receiverRefundSignatureMap,
395
- leafDataMap: receiverLeafDataMap,
396
- signingResults: operatorSigningResults,
397
- } = await receiverTransferService.counterSwapSignRefund(
588
+ transfer: bobTransfer,
589
+ signatureMap: bobRefundSignatureMap,
590
+ directSignatureMap: bobDirectRefundSignatureMap,
591
+ directFromCpfpSignatureMap: bobDirectFromCpfpSignatureMap,
592
+ leafDataMap: bobLeafDataMap,
593
+ signingResults: bobSigningResults,
594
+ } = await bobTransferService.counterSwapSignRefund(
398
595
  receiverLeavesToTransfer,
399
- hexToBytes(senderPubkey),
596
+ hexToBytes(await aliceWallet.getIdentityPublicKey()),
400
597
  new Date(Date.now() + 10 * 60 * 1000),
401
- adaptorPubKey,
598
+ cpfpAdaptorPubKey,
599
+ directAdaptorPubKey,
600
+ directFromCpfpAdaptorPubKey,
402
601
  );
403
602
 
404
603
  const newReceiverRefundSignatureMap = new Map<string, Uint8Array>();
405
- for (const [nodeId, signature] of receiverRefundSignatureMap.entries()) {
406
- const leafData = receiverLeafDataMap.get(nodeId);
604
+ const newReceiverDirectRefundSignatureMap = new Map<string, Uint8Array>();
605
+ const newReceiverDirectFromCpfpRefundSignatureMap = new Map<
606
+ string,
607
+ Uint8Array
608
+ >();
609
+ for (const [nodeId, signature] of bobRefundSignatureMap.entries()) {
610
+ const leafData = bobLeafDataMap.get(nodeId);
407
611
  if (!leafData?.refundTx) {
408
612
  throw new ValidationError("Refund transaction not found", {
409
613
  field: "refundTx",
@@ -416,7 +620,7 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
416
620
  leafData.tx.getOutput(leafData.vout),
417
621
  );
418
622
  let verifyingPubkey: Uint8Array | undefined;
419
- for (const signingResult of operatorSigningResults) {
623
+ for (const signingResult of bobSigningResults) {
420
624
  if (signingResult.leafId === nodeId) {
421
625
  verifyingPubkey = signingResult.verifyingKey;
422
626
  }
@@ -429,44 +633,97 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
429
633
  taprootKey.slice(1, 33),
430
634
  sighash,
431
635
  signature,
432
- adaptorPrivateKey,
636
+ cpfpAdaptorPrivateKey,
433
637
  );
434
638
  newReceiverRefundSignatureMap.set(nodeId, adaptorSig);
435
639
  }
436
- const senderTransferTweakKey =
437
- await senderTransferService.deliverTransferPackage(
438
- senderTransfer,
439
- senderLeavesToTransfer,
440
- senderRefundSignatureMap,
640
+
641
+ for (const [nodeId, signature] of bobDirectRefundSignatureMap.entries()) {
642
+ const leafData = bobLeafDataMap.get(nodeId);
643
+ if (!leafData?.directRefundTx) {
644
+ continue;
645
+ }
646
+ const sighash = getSigHashFromTx(
647
+ leafData.directRefundTx,
648
+ 0,
649
+ leafData.directTx!.getOutput(leafData.vout),
650
+ );
651
+ let verifyingPubkey: Uint8Array | undefined;
652
+ for (const signingResult of bobSigningResults) {
653
+ if (signingResult.leafId === nodeId) {
654
+ verifyingPubkey = signingResult.verifyingKey;
655
+ }
656
+ }
657
+ expect(verifyingPubkey).toBeDefined();
658
+ const taprootKey = computeTaprootKeyNoScript(
659
+ verifyingPubkey!.slice(1, 33),
441
660
  );
661
+ const adaptorSig = applyAdaptorToSignature(
662
+ taprootKey.slice(1, 33),
663
+ sighash,
664
+ signature,
665
+ directAdaptorPrivateKey ?? new Uint8Array(),
666
+ );
667
+ newReceiverDirectRefundSignatureMap.set(nodeId, adaptorSig);
668
+ }
442
669
 
443
- const pendingTransfer =
444
- await receiverTransferService.queryPendingTransfers();
445
- expect(pendingTransfer.transfers.length).toBe(1);
446
- const receiverPendingTransfer = pendingTransfer.transfers[0];
447
- expect(receiverPendingTransfer!.id).toBe(senderTransferTweakKey.id);
670
+ for (const [
671
+ nodeId,
672
+ signature,
673
+ ] of bobDirectFromCpfpSignatureMap.entries()) {
674
+ const leafData = bobLeafDataMap.get(nodeId);
675
+ if (!leafData?.directFromCpfpRefundTx) {
676
+ continue;
677
+ }
678
+ const sighash = getSigHashFromTx(
679
+ leafData.directFromCpfpRefundTx,
680
+ 0,
681
+ leafData.tx.getOutput(leafData.vout),
682
+ );
683
+ let verifyingPubkey: Uint8Array | undefined;
684
+ for (const signingResult of bobSigningResults) {
685
+ if (signingResult.leafId === nodeId) {
686
+ verifyingPubkey = signingResult.verifyingKey;
687
+ }
688
+ }
689
+ expect(verifyingPubkey).toBeDefined();
690
+ const taprootKey = computeTaprootKeyNoScript(
691
+ verifyingPubkey!.slice(1, 33),
692
+ );
693
+ const adaptorSig = applyAdaptorToSignature(
694
+ taprootKey.slice(1, 33),
695
+ sighash,
696
+ signature,
697
+ directFromCpfpAdaptorPrivateKey ?? new Uint8Array(),
698
+ );
699
+ newReceiverDirectFromCpfpRefundSignatureMap.set(nodeId, adaptorSig);
700
+ }
448
701
 
449
- const leafPrivKeyMap =
450
- await receiverTransferService.verifyPendingTransfer(
451
- receiverPendingTransfer!,
702
+ const senderTransferTweakKey =
703
+ await aliceTransferService.deliverTransferPackage(
704
+ aliceTransfer,
705
+ aliceLeavesToTransfer,
706
+ aliceRefundSignatureMap,
707
+ aliceDirectRefundSignatureMap,
708
+ aliceDirectFromCpfpSignatureMap,
452
709
  );
453
710
 
454
- expect(leafPrivKeyMap.size).toBe(1);
455
- expect(leafPrivKeyMap.get(senderRootNode.id)).toBeDefined();
456
- const bytesEqual = equalBytes(
457
- leafPrivKeyMap.get(senderRootNode.id)!,
458
- await senderWallet
459
- .getSigner()
460
- .getPublicKeyFromDerivation(senderNewLeafDerivation),
711
+ const pendingTransfer = await bobTransferService.queryPendingTransfers();
712
+ expect(pendingTransfer.transfers.length).toBe(1);
713
+ const bobPendingTransfer = pendingTransfer.transfers[0];
714
+ expect(bobPendingTransfer!.id).toBe(senderTransferTweakKey.id);
715
+
716
+ const leafPrivKeyMap = await bobTransferService.verifyPendingTransfer(
717
+ bobPendingTransfer!,
461
718
  );
462
- expect(bytesEqual).toBe(true);
463
- expect(receiverPendingTransfer!.leaves[0]!.leaf).toBeDefined();
464
- const claimingNodes: LeafKeyTweak[] = receiverPendingTransfer!.leaves.map(
719
+ expect(leafPrivKeyMap.size).toBe(1);
720
+
721
+ const claimingNodes: LeafKeyTweak[] = bobPendingTransfer!.leaves.map(
465
722
  (leaf) => ({
466
723
  leaf: leaf.leaf!,
467
724
  keyDerivation: {
468
725
  type: KeyDerivationType.ECIES,
469
- path: leaf.secretCipher,
726
+ path: leaf.secretCipher!,
470
727
  },
471
728
  newKeyDerivation: {
472
729
  type: KeyDerivationType.LEAF,
@@ -474,43 +731,37 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
474
731
  },
475
732
  }),
476
733
  );
477
- await receiverTransferService.claimTransfer(
478
- receiverPendingTransfer!,
734
+
735
+ await bobTransferService.claimTransfer(
736
+ bobPendingTransfer!,
479
737
  claimingNodes,
480
738
  );
481
- await receiverTransferService.deliverTransferPackage(
482
- receiverTransfer,
739
+
740
+ await bobTransferService.deliverTransferPackage(
741
+ bobTransfer,
483
742
  receiverLeavesToTransfer,
484
743
  newReceiverRefundSignatureMap,
744
+ newReceiverDirectRefundSignatureMap,
745
+ newReceiverDirectFromCpfpRefundSignatureMap,
485
746
  );
486
747
 
487
- const sPendingTransfer =
488
- await senderTransferService.queryPendingTransfers();
489
- expect(sPendingTransfer.transfers.length).toBe(1);
490
- const senderPendingTransfer = sPendingTransfer.transfers[0];
491
- expect(senderPendingTransfer!.id).toBe(receiverTransfer.id);
748
+ const pendingTransfer1 =
749
+ await aliceTransferService.queryPendingTransfers();
750
+ expect(pendingTransfer1.transfers.length).toBe(1);
751
+ const alicePendingTransfer = pendingTransfer1.transfers[0];
752
+ expect(alicePendingTransfer!.id).toBe(bobTransfer.id);
492
753
 
493
- const senderLeafPrivKeyMap =
494
- await senderTransferService.verifyPendingTransfer(
495
- senderPendingTransfer!,
496
- );
497
- expect(senderLeafPrivKeyMap.size).toBe(1);
498
- expect(senderLeafPrivKeyMap.get(receiverRootNode.id)).toBeDefined();
499
- const bytesEqual_1 = equalBytes(
500
- senderLeafPrivKeyMap.get(receiverRootNode.id)!,
501
- await receiverWallet
502
- .getSigner()
503
- .getPublicKeyFromDerivation(receiverNewLeafDerivation),
754
+ const leafPrivKeyMap1 = await aliceTransferService.verifyPendingTransfer(
755
+ alicePendingTransfer!,
504
756
  );
505
- expect(bytesEqual_1).toBe(true);
506
- expect(senderPendingTransfer!.leaves[0]!.leaf).toBeDefined();
757
+ expect(leafPrivKeyMap1.size).toBe(1);
507
758
 
508
- const claimingNodes_1: LeafKeyTweak[] = senderPendingTransfer!.leaves.map(
759
+ const claimingNodes1: LeafKeyTweak[] = alicePendingTransfer!.leaves.map(
509
760
  (leaf) => ({
510
761
  leaf: leaf.leaf!,
511
762
  keyDerivation: {
512
763
  type: KeyDerivationType.ECIES,
513
- path: leaf.secretCipher,
764
+ path: leaf.secretCipher!,
514
765
  },
515
766
  newKeyDerivation: {
516
767
  type: KeyDerivationType.LEAF,
@@ -518,11 +769,12 @@ describe.each(signerTypes)("swap", ({ name, Signer }) => {
518
769
  },
519
770
  }),
520
771
  );
521
- await senderTransferService.claimTransfer(
522
- senderPendingTransfer!,
523
- claimingNodes_1,
772
+
773
+ await aliceTransferService.claimTransfer(
774
+ alicePendingTransfer!,
775
+ claimingNodes1,
524
776
  );
525
777
  },
526
- 30000,
778
+ 30_000,
527
779
  );
528
780
  });