@buildonspark/spark-sdk 0.2.2 → 0.2.4
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 +15 -0
- package/dist/{chunk-TM6CHQXC.js → chunk-3SEOTO43.js} +1 -1
- package/dist/{chunk-2ENZX6LT.js → chunk-AAZWSPUK.js} +84 -8
- package/dist/{chunk-4JD4HIAN.js → chunk-G4MSZ6DE.js} +299 -1
- package/dist/{chunk-S2AL73MZ.js → chunk-TVUMSHWA.js} +1 -1
- package/dist/{chunk-2TUM3R6C.js → chunk-W4ZRBSWM.js} +2351 -797
- package/dist/{chunk-CDLETEDT.js → chunk-WAQKYSDI.js} +13 -1
- package/dist/{client-CGTRS23n.d.ts → client-BF4cn8F4.d.ts} +15 -3
- package/dist/{client-CcYzmpmj.d.cts → client-KhNkrXz4.d.cts} +15 -3
- package/dist/debug.cjs +2948 -1023
- package/dist/debug.d.cts +19 -6
- package/dist/debug.d.ts +19 -6
- package/dist/debug.js +5 -5
- package/dist/graphql/objects/index.cjs +13 -1
- package/dist/graphql/objects/index.d.cts +2 -2
- package/dist/graphql/objects/index.d.ts +2 -2
- package/dist/graphql/objects/index.js +1 -1
- package/dist/index.cjs +2794 -858
- package/dist/index.d.cts +190 -9
- package/dist/index.d.ts +190 -9
- package/dist/index.js +32 -6
- package/dist/index.node.cjs +2931 -892
- package/dist/index.node.d.cts +10 -188
- package/dist/index.node.d.ts +10 -188
- package/dist/index.node.js +134 -6
- package/dist/native/index.cjs +2794 -858
- package/dist/native/index.d.cts +148 -40
- package/dist/native/index.d.ts +148 -40
- package/dist/native/index.js +2799 -877
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/lrc20.js +1 -1
- package/dist/proto/spark.cjs +84 -8
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +1 -1
- package/dist/proto/spark_token.cjs +301 -0
- package/dist/proto/spark_token.d.cts +35 -2
- package/dist/proto/spark_token.d.ts +35 -2
- package/dist/proto/spark_token.js +8 -2
- package/dist/{sdk-types-DJ2ve9YY.d.cts → sdk-types-CB9HrW5O.d.cts} +1 -1
- package/dist/{sdk-types-DCIVdKUT.d.ts → sdk-types-CkRNraXT.d.ts} +1 -1
- package/dist/{spark-BUOx3U7Q.d.cts → spark-B_7nZx6T.d.cts} +112 -10
- package/dist/{spark-BUOx3U7Q.d.ts → spark-B_7nZx6T.d.ts} +112 -10
- package/dist/{spark-wallet-B_96y9BS.d.ts → spark-wallet-C1Tr_VKI.d.ts} +38 -28
- package/dist/{spark-wallet-CHwKQYJu.d.cts → spark-wallet-DG3x2obf.d.cts} +38 -28
- package/dist/spark-wallet.node-CGxoeCpH.d.ts +13 -0
- package/dist/spark-wallet.node-CN9LoB_O.d.cts +13 -0
- package/dist/tests/test-utils.cjs +1086 -218
- package/dist/tests/test-utils.d.cts +13 -13
- package/dist/tests/test-utils.d.ts +13 -13
- package/dist/tests/test-utils.js +56 -19
- package/dist/types/index.cjs +97 -9
- package/dist/types/index.d.cts +3 -3
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +3 -3
- package/dist/{xchain-address-D5MIHCDL.d.cts → xchain-address-BHu6CpZC.d.ts} +55 -8
- package/dist/{xchain-address-DLbW1iDh.d.ts → xchain-address-HBr6isnc.d.cts} +55 -8
- package/package.json +1 -1
- package/src/graphql/client.ts +8 -0
- package/src/graphql/mutations/CompleteLeavesSwap.ts +9 -1
- package/src/graphql/mutations/RequestSwapLeaves.ts +4 -0
- package/src/graphql/objects/CompleteLeavesSwapInput.ts +34 -34
- package/src/graphql/objects/LeavesSwapRequest.ts +4 -0
- package/src/graphql/objects/RequestLeavesSwapInput.ts +48 -47
- package/src/graphql/objects/SwapLeaf.ts +40 -32
- package/src/graphql/objects/UserLeafInput.ts +24 -0
- package/src/graphql/objects/UserRequest.ts +4 -0
- package/src/index.node.ts +1 -1
- package/src/native/index.ts +4 -5
- package/src/proto/spark.ts +172 -16
- package/src/proto/spark_token.ts +369 -0
- package/src/services/coop-exit.ts +171 -36
- package/src/services/deposit.ts +471 -74
- package/src/services/lightning.ts +18 -5
- package/src/services/signing.ts +162 -50
- package/src/services/token-transactions.ts +6 -2
- package/src/services/transfer.ts +950 -384
- package/src/services/tree-creation.ts +342 -121
- package/src/spark-wallet/spark-wallet.node.ts +71 -66
- package/src/spark-wallet/spark-wallet.ts +459 -166
- package/src/tests/integration/coop-exit.test.ts +3 -8
- package/src/tests/integration/deposit.test.ts +3 -3
- package/src/tests/integration/lightning.test.ts +521 -466
- package/src/tests/integration/swap.test.ts +559 -307
- package/src/tests/integration/transfer.test.ts +625 -623
- package/src/tests/integration/wallet.test.ts +2 -2
- package/src/tests/integration/watchtower.test.ts +211 -0
- package/src/tests/test-utils.ts +63 -14
- package/src/tests/utils/test-faucet.ts +4 -2
- package/src/utils/adaptor-signature.ts +15 -5
- package/src/utils/fetch.ts +75 -0
- package/src/utils/mempool.ts +9 -4
- package/src/utils/transaction.ts +388 -26
|
@@ -16,19 +16,24 @@ import {
|
|
|
16
16
|
TreeNode,
|
|
17
17
|
} from "../proto/spark.js";
|
|
18
18
|
import {
|
|
19
|
+
KeyDerivation,
|
|
19
20
|
KeyDerivationType,
|
|
20
21
|
SigningCommitmentWithOptionalNonce,
|
|
21
22
|
} from "../signer/types.js";
|
|
22
23
|
import {
|
|
23
|
-
getP2TRAddressFromPublicKey,
|
|
24
24
|
getSigHashFromTx,
|
|
25
25
|
getTxFromRawTxBytes,
|
|
26
26
|
getTxId,
|
|
27
27
|
} from "../utils/bitcoin.js";
|
|
28
28
|
import { getNetwork, Network } from "../utils/network.js";
|
|
29
29
|
import {
|
|
30
|
+
createLeafNodeTx,
|
|
31
|
+
createNodeTxs,
|
|
32
|
+
createRefundTxs,
|
|
33
|
+
createSplitTx,
|
|
30
34
|
DEFAULT_FEE_SATS,
|
|
31
|
-
|
|
35
|
+
INITIAL_DIRECT_SEQUENCE,
|
|
36
|
+
INITIAL_SEQUENCE,
|
|
32
37
|
} from "../utils/transaction.js";
|
|
33
38
|
import { WalletConfigService } from "./config.js";
|
|
34
39
|
import { ConnectionManager } from "./connection.js";
|
|
@@ -41,8 +46,20 @@ export type DepositAddressTree = {
|
|
|
41
46
|
};
|
|
42
47
|
|
|
43
48
|
export type CreationNodeWithNonces = CreationNode & {
|
|
49
|
+
directNodeTxSigningCommitment?:
|
|
50
|
+
| SigningCommitmentWithOptionalNonce
|
|
51
|
+
| undefined;
|
|
44
52
|
nodeTxSigningCommitment?: SigningCommitmentWithOptionalNonce | undefined;
|
|
45
53
|
refundTxSigningCommitment?: SigningCommitmentWithOptionalNonce | undefined;
|
|
54
|
+
directRefundTxSigningCommitment?:
|
|
55
|
+
| SigningCommitmentWithOptionalNonce
|
|
56
|
+
| undefined;
|
|
57
|
+
directFromCpfpRefundTxSigningCommitment?:
|
|
58
|
+
| SigningCommitmentWithOptionalNonce
|
|
59
|
+
| undefined;
|
|
60
|
+
directNodeTxSigningJob?: SigningJob | undefined;
|
|
61
|
+
directRefundTxSigningJob?: SigningJob | undefined;
|
|
62
|
+
directFromCpfpRefundTxSigningJob?: SigningJob | undefined;
|
|
46
63
|
};
|
|
47
64
|
|
|
48
65
|
const INITIAL_TIME_LOCK = 2000;
|
|
@@ -205,7 +222,7 @@ export class TreeCreationService {
|
|
|
205
222
|
|
|
206
223
|
let response: CreateTreeResponse;
|
|
207
224
|
try {
|
|
208
|
-
response = await sparkClient.
|
|
225
|
+
response = await sparkClient.create_tree_v2(request);
|
|
209
226
|
} catch (error) {
|
|
210
227
|
throw new Error(`Error creating tree: ${error}`);
|
|
211
228
|
}
|
|
@@ -226,7 +243,7 @@ export class TreeCreationService {
|
|
|
226
243
|
|
|
227
244
|
let finalizeResp: FinalizeNodeSignaturesResponse;
|
|
228
245
|
try {
|
|
229
|
-
finalizeResp = await sparkClient.
|
|
246
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
230
247
|
nodeSignatures: nodeSignatures,
|
|
231
248
|
});
|
|
232
249
|
} catch (error) {
|
|
@@ -318,111 +335,154 @@ export class TreeCreationService {
|
|
|
318
335
|
// internal node
|
|
319
336
|
const internalCreationNode: CreationNodeWithNonces = {
|
|
320
337
|
nodeTxSigningJob: undefined,
|
|
321
|
-
refundTxSigningJob: undefined,
|
|
322
|
-
children: [],
|
|
323
338
|
directNodeTxSigningJob: undefined,
|
|
339
|
+
refundTxSigningJob: undefined,
|
|
324
340
|
directRefundTxSigningJob: undefined,
|
|
325
341
|
directFromCpfpRefundTxSigningJob: undefined,
|
|
342
|
+
children: [],
|
|
326
343
|
};
|
|
327
344
|
|
|
328
|
-
const tx = new Transaction({ version: 3 });
|
|
329
|
-
tx.addInput({
|
|
330
|
-
txid: getTxId(parentTx),
|
|
331
|
-
index: vout,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
345
|
const parentTxOut = parentTx.getOutput(vout);
|
|
335
346
|
if (!parentTxOut?.script || !parentTxOut?.amount) {
|
|
336
347
|
throw new Error("parentTxOut is undefined");
|
|
337
348
|
}
|
|
338
349
|
|
|
339
|
-
|
|
350
|
+
const parentOutPoint = {
|
|
351
|
+
txid: hexToBytes(getTxId(parentTx)),
|
|
352
|
+
index: vout,
|
|
353
|
+
};
|
|
354
|
+
const parentTxOutObj = {
|
|
340
355
|
script: parentTxOut.script,
|
|
341
|
-
amount: parentTxOut.amount,
|
|
342
|
-
}
|
|
356
|
+
amount: parentTxOut.amount,
|
|
357
|
+
};
|
|
343
358
|
|
|
344
|
-
|
|
359
|
+
// Create both CPFP and direct node transactions
|
|
360
|
+
const { cpfpNodeTx, directNodeTx } = createNodeTxs(
|
|
361
|
+
parentTxOutObj,
|
|
362
|
+
parentOutPoint,
|
|
363
|
+
);
|
|
345
364
|
|
|
346
|
-
|
|
365
|
+
// Create nonce commitments for node transactions
|
|
366
|
+
const cpfpNodeSigningCommitment =
|
|
367
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
368
|
+
const directNodeSigningCommitment =
|
|
347
369
|
await this.config.signer.getRandomSigningCommitment();
|
|
348
|
-
|
|
370
|
+
|
|
371
|
+
const cpfpNodeSigningJob: SigningJob = {
|
|
349
372
|
signingPublicKey: node.signingPublicKey,
|
|
350
|
-
rawTx:
|
|
351
|
-
signingNonceCommitment:
|
|
373
|
+
rawTx: cpfpNodeTx.toBytes(),
|
|
374
|
+
signingNonceCommitment: cpfpNodeSigningCommitment.commitment,
|
|
352
375
|
};
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
376
|
+
const directNodeSigningJob: SigningJob | undefined = directNodeTx
|
|
377
|
+
? {
|
|
378
|
+
signingPublicKey: node.signingPublicKey,
|
|
379
|
+
rawTx: directNodeTx.toBytes(),
|
|
380
|
+
signingNonceCommitment: directNodeSigningCommitment.commitment,
|
|
381
|
+
}
|
|
382
|
+
: undefined;
|
|
383
|
+
|
|
384
|
+
internalCreationNode.nodeTxSigningCommitment = cpfpNodeSigningCommitment;
|
|
385
|
+
internalCreationNode.directNodeTxSigningCommitment =
|
|
386
|
+
directNodeSigningCommitment;
|
|
387
|
+
internalCreationNode.nodeTxSigningJob = cpfpNodeSigningJob;
|
|
388
|
+
internalCreationNode.directNodeTxSigningJob = directNodeSigningJob;
|
|
356
389
|
|
|
357
390
|
// leaf node
|
|
358
|
-
const sequence =
|
|
391
|
+
const sequence = INITIAL_SEQUENCE;
|
|
392
|
+
const directSequence = INITIAL_DIRECT_SEQUENCE;
|
|
359
393
|
|
|
360
394
|
const childCreationNode: CreationNodeWithNonces = {
|
|
361
395
|
nodeTxSigningJob: undefined,
|
|
362
|
-
refundTxSigningJob: undefined,
|
|
363
|
-
children: [],
|
|
364
396
|
directNodeTxSigningJob: undefined,
|
|
397
|
+
refundTxSigningJob: undefined,
|
|
365
398
|
directRefundTxSigningJob: undefined,
|
|
366
399
|
directFromCpfpRefundTxSigningJob: undefined,
|
|
400
|
+
children: [],
|
|
367
401
|
};
|
|
368
402
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
txid: getTxId(tx),
|
|
372
|
-
index: 0,
|
|
403
|
+
// Create both CPFP and direct leaf node transactions
|
|
404
|
+
const [cpfpLeafTx, directLeafTx] = createLeafNodeTx(
|
|
373
405
|
sequence,
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
childTx.addOutput(getEphemeralAnchorOutput());
|
|
406
|
+
directSequence,
|
|
407
|
+
{ txid: hexToBytes(getTxId(cpfpNodeTx)), index: 0 },
|
|
408
|
+
parentTxOutObj,
|
|
409
|
+
true, // shouldCalculateFee
|
|
410
|
+
);
|
|
382
411
|
|
|
383
|
-
|
|
412
|
+
// Create nonce commitments for leaf node transactions
|
|
413
|
+
const cpfpLeafSigningCommitment =
|
|
384
414
|
await this.config.signer.getRandomSigningCommitment();
|
|
385
|
-
const
|
|
415
|
+
const directLeafSigningCommitment =
|
|
416
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
417
|
+
|
|
418
|
+
const cpfpLeafSigningJob: SigningJob = {
|
|
386
419
|
signingPublicKey: node.signingPublicKey,
|
|
387
|
-
rawTx:
|
|
388
|
-
signingNonceCommitment:
|
|
420
|
+
rawTx: cpfpLeafTx.toBytes(),
|
|
421
|
+
signingNonceCommitment: cpfpLeafSigningCommitment.commitment,
|
|
422
|
+
};
|
|
423
|
+
const directLeafSigningJob: SigningJob = {
|
|
424
|
+
signingPublicKey: node.signingPublicKey,
|
|
425
|
+
rawTx: directLeafTx.toBytes(),
|
|
426
|
+
signingNonceCommitment: directLeafSigningCommitment.commitment,
|
|
389
427
|
};
|
|
390
428
|
|
|
391
|
-
childCreationNode.nodeTxSigningCommitment =
|
|
392
|
-
childCreationNode.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const refundPkScript = OutScript.encode(refundAddress);
|
|
409
|
-
refundTx.addOutput({
|
|
410
|
-
script: refundPkScript,
|
|
411
|
-
amount: maybeApplyFee(parentTxOut.amount),
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
refundTx.addOutput(getEphemeralAnchorOutput());
|
|
429
|
+
childCreationNode.nodeTxSigningCommitment = cpfpLeafSigningCommitment;
|
|
430
|
+
childCreationNode.directNodeTxSigningCommitment =
|
|
431
|
+
directLeafSigningCommitment;
|
|
432
|
+
childCreationNode.nodeTxSigningJob = cpfpLeafSigningJob;
|
|
433
|
+
childCreationNode.directNodeTxSigningJob = directLeafSigningJob;
|
|
434
|
+
|
|
435
|
+
// Create both CPFP and direct refund transactions
|
|
436
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } =
|
|
437
|
+
createRefundTxs({
|
|
438
|
+
sequence,
|
|
439
|
+
directSequence,
|
|
440
|
+
input: { txid: hexToBytes(getTxId(cpfpLeafTx)), index: 0 },
|
|
441
|
+
directInput: { txid: hexToBytes(getTxId(directLeafTx)), index: 0 },
|
|
442
|
+
amountSats: parentTxOut.amount,
|
|
443
|
+
receivingPubkey: node.signingPublicKey,
|
|
444
|
+
network,
|
|
445
|
+
});
|
|
415
446
|
|
|
416
|
-
|
|
447
|
+
// Create nonce commitments for refund transactions
|
|
448
|
+
const cpfpRefundSigningCommitment =
|
|
449
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
450
|
+
const directRefundSigningCommitment =
|
|
451
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
452
|
+
const directFromCpfpRefundSigningCommitment =
|
|
417
453
|
await this.config.signer.getRandomSigningCommitment();
|
|
418
454
|
|
|
419
|
-
const
|
|
455
|
+
const cpfpRefundSigningJob: SigningJob = {
|
|
420
456
|
signingPublicKey: node.signingPublicKey,
|
|
421
|
-
rawTx:
|
|
422
|
-
signingNonceCommitment:
|
|
457
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
458
|
+
signingNonceCommitment: cpfpRefundSigningCommitment.commitment,
|
|
423
459
|
};
|
|
424
|
-
|
|
425
|
-
|
|
460
|
+
const directRefundSigningJob: SigningJob | undefined = directRefundTx
|
|
461
|
+
? {
|
|
462
|
+
signingPublicKey: node.signingPublicKey,
|
|
463
|
+
rawTx: directRefundTx.toBytes(),
|
|
464
|
+
signingNonceCommitment: directRefundSigningCommitment.commitment,
|
|
465
|
+
}
|
|
466
|
+
: undefined;
|
|
467
|
+
const directFromCpfpRefundSigningJob: SigningJob | undefined =
|
|
468
|
+
directFromCpfpRefundTx
|
|
469
|
+
? {
|
|
470
|
+
signingPublicKey: node.signingPublicKey,
|
|
471
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
472
|
+
signingNonceCommitment:
|
|
473
|
+
directFromCpfpRefundSigningCommitment.commitment,
|
|
474
|
+
}
|
|
475
|
+
: undefined;
|
|
476
|
+
|
|
477
|
+
childCreationNode.refundTxSigningCommitment = cpfpRefundSigningCommitment;
|
|
478
|
+
childCreationNode.directRefundTxSigningCommitment =
|
|
479
|
+
directRefundSigningCommitment;
|
|
480
|
+
childCreationNode.directFromCpfpRefundTxSigningCommitment =
|
|
481
|
+
directFromCpfpRefundSigningCommitment;
|
|
482
|
+
childCreationNode.refundTxSigningJob = cpfpRefundSigningJob;
|
|
483
|
+
childCreationNode.directRefundTxSigningJob = directRefundSigningJob;
|
|
484
|
+
childCreationNode.directFromCpfpRefundTxSigningJob =
|
|
485
|
+
directFromCpfpRefundSigningJob;
|
|
426
486
|
|
|
427
487
|
internalCreationNode.children.push(childCreationNode);
|
|
428
488
|
|
|
@@ -440,12 +500,9 @@ export class TreeCreationService {
|
|
|
440
500
|
if (!parentTxOutput?.script || !parentTxOutput?.amount) {
|
|
441
501
|
throw new Error("parentTxOutput is undefined");
|
|
442
502
|
}
|
|
443
|
-
const rootNodeTx = new Transaction({ version: 3 });
|
|
444
|
-
rootNodeTx.addInput({
|
|
445
|
-
txid: getTxId(parentTx),
|
|
446
|
-
index: vout,
|
|
447
|
-
});
|
|
448
503
|
|
|
504
|
+
// Create child transaction outputs
|
|
505
|
+
const childTxOuts: { script: Uint8Array; amount: bigint }[] = [];
|
|
449
506
|
for (let i = 0; i < root.children.length; i++) {
|
|
450
507
|
const child = root.children[i];
|
|
451
508
|
if (!child || !child.address) {
|
|
@@ -454,32 +511,51 @@ export class TreeCreationService {
|
|
|
454
511
|
const childAddress = Address(getNetwork(network)).decode(child.address);
|
|
455
512
|
const childPkScript = OutScript.encode(childAddress);
|
|
456
513
|
|
|
457
|
-
|
|
458
|
-
// const feeAdjustedAmount = maybeApplyFee(parentTxOutput.amount);
|
|
459
|
-
rootNodeTx.addOutput({
|
|
514
|
+
childTxOuts.push({
|
|
460
515
|
script: childPkScript,
|
|
461
|
-
amount: parentTxOutput.amount / 2n,
|
|
516
|
+
amount: parentTxOutput.amount / 2n,
|
|
462
517
|
});
|
|
463
518
|
}
|
|
464
519
|
|
|
465
|
-
|
|
520
|
+
const parentOutPoint = {
|
|
521
|
+
txid: hexToBytes(getTxId(parentTx)),
|
|
522
|
+
index: vout,
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// Create both CPFP and direct split transactions
|
|
526
|
+
const [cpfpSplitTx, directSplitTx] = createSplitTx(
|
|
527
|
+
parentOutPoint,
|
|
528
|
+
childTxOuts,
|
|
529
|
+
);
|
|
466
530
|
|
|
467
|
-
|
|
531
|
+
// Create nonce commitments for split transactions
|
|
532
|
+
const cpfpSplitSigningCommitment =
|
|
533
|
+
await this.config.signer.getRandomSigningCommitment();
|
|
534
|
+
const directSplitSigningCommitment =
|
|
468
535
|
await this.config.signer.getRandomSigningCommitment();
|
|
469
|
-
|
|
536
|
+
|
|
537
|
+
const cpfpSplitSigningJob: SigningJob = {
|
|
470
538
|
signingPublicKey: root.signingPublicKey,
|
|
471
|
-
rawTx:
|
|
472
|
-
signingNonceCommitment:
|
|
539
|
+
rawTx: cpfpSplitTx.toBytes(),
|
|
540
|
+
signingNonceCommitment: cpfpSplitSigningCommitment.commitment,
|
|
473
541
|
};
|
|
542
|
+
const directSplitSigningJob: SigningJob = {
|
|
543
|
+
signingPublicKey: root.signingPublicKey,
|
|
544
|
+
rawTx: directSplitTx.toBytes(),
|
|
545
|
+
signingNonceCommitment: directSplitSigningCommitment.commitment,
|
|
546
|
+
};
|
|
547
|
+
|
|
474
548
|
const rootCreationNode: CreationNodeWithNonces = {
|
|
475
|
-
nodeTxSigningJob:
|
|
549
|
+
nodeTxSigningJob: cpfpSplitSigningJob,
|
|
550
|
+
directNodeTxSigningJob: directSplitSigningJob,
|
|
476
551
|
refundTxSigningJob: undefined,
|
|
477
|
-
children: [],
|
|
478
|
-
directNodeTxSigningJob: undefined,
|
|
479
552
|
directRefundTxSigningJob: undefined,
|
|
480
553
|
directFromCpfpRefundTxSigningJob: undefined,
|
|
554
|
+
children: [],
|
|
481
555
|
};
|
|
482
|
-
rootCreationNode.nodeTxSigningCommitment =
|
|
556
|
+
rootCreationNode.nodeTxSigningCommitment = cpfpSplitSigningCommitment;
|
|
557
|
+
rootCreationNode.directNodeTxSigningCommitment =
|
|
558
|
+
directSplitSigningCommitment;
|
|
483
559
|
|
|
484
560
|
const leftChild = root.children[0];
|
|
485
561
|
const rightChild = root.children[1];
|
|
@@ -489,13 +565,13 @@ export class TreeCreationService {
|
|
|
489
565
|
|
|
490
566
|
const leftChildCreationNode = await this.buildChildCreationNode(
|
|
491
567
|
leftChild,
|
|
492
|
-
|
|
568
|
+
cpfpSplitTx, // Use CPFP version for children
|
|
493
569
|
0,
|
|
494
570
|
network,
|
|
495
571
|
);
|
|
496
572
|
const rightChildCreationNode = await this.buildChildCreationNode(
|
|
497
573
|
rightChild,
|
|
498
|
-
|
|
574
|
+
cpfpSplitTx, // Use CPFP version for children
|
|
499
575
|
1,
|
|
500
576
|
network,
|
|
501
577
|
);
|
|
@@ -515,6 +591,7 @@ export class TreeCreationService {
|
|
|
515
591
|
): Promise<{ tx: Transaction; signature: NodeSignatures }> {
|
|
516
592
|
if (
|
|
517
593
|
!creationNode.nodeTxSigningJob?.signingPublicKey ||
|
|
594
|
+
!creationNode.directNodeTxSigningJob?.signingPublicKey ||
|
|
518
595
|
!internalNode.verificationKey
|
|
519
596
|
) {
|
|
520
597
|
throw new Error("signingPublicKey or verificationKey is undefined");
|
|
@@ -525,13 +602,14 @@ export class TreeCreationService {
|
|
|
525
602
|
throw new Error("parentTxOutput is undefined");
|
|
526
603
|
}
|
|
527
604
|
|
|
528
|
-
|
|
529
|
-
const
|
|
605
|
+
// Sign CPFP node transaction
|
|
606
|
+
const cpfpNodeTx = getTxFromRawTxBytes(creationNode.nodeTxSigningJob.rawTx);
|
|
607
|
+
const cpfpNodeTxSighash = getSigHashFromTx(cpfpNodeTx, 0, parentTxOutput);
|
|
530
608
|
|
|
531
|
-
let
|
|
609
|
+
let cpfpNodeTxSignature: Uint8Array = new Uint8Array();
|
|
532
610
|
if (creationNode.nodeTxSigningCommitment) {
|
|
533
|
-
const
|
|
534
|
-
message:
|
|
611
|
+
const cpfpUserSignature = await this.config.signer.signFrost({
|
|
612
|
+
message: cpfpNodeTxSighash,
|
|
535
613
|
publicKey: creationNode.nodeTxSigningJob.signingPublicKey,
|
|
536
614
|
keyDerivation: {
|
|
537
615
|
type: KeyDerivationType.LEAF,
|
|
@@ -543,8 +621,8 @@ export class TreeCreationService {
|
|
|
543
621
|
verifyingKey: internalNode.verificationKey,
|
|
544
622
|
});
|
|
545
623
|
|
|
546
|
-
|
|
547
|
-
message:
|
|
624
|
+
cpfpNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
625
|
+
message: cpfpNodeTxSighash,
|
|
548
626
|
statechainSignatures:
|
|
549
627
|
creationResponseNode.nodeTxSigningResult?.signatureShares,
|
|
550
628
|
statechainPublicKeys:
|
|
@@ -553,25 +631,105 @@ export class TreeCreationService {
|
|
|
553
631
|
statechainCommitments:
|
|
554
632
|
creationResponseNode.nodeTxSigningResult?.signingNonceCommitments,
|
|
555
633
|
selfCommitment: creationNode.nodeTxSigningCommitment,
|
|
556
|
-
selfSignature:
|
|
634
|
+
selfSignature: cpfpUserSignature,
|
|
557
635
|
publicKey: internalNode.signingPublicKey,
|
|
558
636
|
});
|
|
559
637
|
}
|
|
560
638
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
639
|
+
// Sign direct node transaction
|
|
640
|
+
const directNodeTx = getTxFromRawTxBytes(
|
|
641
|
+
creationNode.directNodeTxSigningJob.rawTx,
|
|
642
|
+
);
|
|
643
|
+
const directNodeTxSighash = getSigHashFromTx(
|
|
644
|
+
directNodeTx,
|
|
645
|
+
0,
|
|
646
|
+
parentTxOutput,
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
let directNodeTxSignature: Uint8Array = new Uint8Array();
|
|
650
|
+
if (creationNode.directNodeTxSigningCommitment) {
|
|
651
|
+
const directUserSignature = await this.config.signer.signFrost({
|
|
652
|
+
message: directNodeTxSighash,
|
|
653
|
+
publicKey: creationNode.directNodeTxSigningJob.signingPublicKey,
|
|
654
|
+
keyDerivation: {
|
|
655
|
+
type: KeyDerivationType.LEAF,
|
|
656
|
+
path: creationResponseNode.nodeId,
|
|
657
|
+
},
|
|
658
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
659
|
+
statechainCommitments:
|
|
660
|
+
creationResponseNode.directNodeTxSigningResult
|
|
661
|
+
?.signingNonceCommitments,
|
|
662
|
+
verifyingKey: internalNode.verificationKey,
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
directNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
666
|
+
message: directNodeTxSighash,
|
|
667
|
+
statechainSignatures:
|
|
668
|
+
creationResponseNode.directNodeTxSigningResult?.signatureShares,
|
|
669
|
+
statechainPublicKeys:
|
|
670
|
+
creationResponseNode.directNodeTxSigningResult?.publicKeys,
|
|
671
|
+
verifyingKey: internalNode.verificationKey,
|
|
672
|
+
statechainCommitments:
|
|
673
|
+
creationResponseNode.directNodeTxSigningResult
|
|
674
|
+
?.signingNonceCommitments,
|
|
675
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
676
|
+
selfSignature: directUserSignature,
|
|
677
|
+
publicKey: internalNode.signingPublicKey,
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Sign refund transactions if they exist
|
|
682
|
+
let cpfpRefundTxSignature: Uint8Array = new Uint8Array();
|
|
683
|
+
let directRefundTxSignature: Uint8Array = new Uint8Array();
|
|
684
|
+
let directFromCpfpRefundTxSignature: Uint8Array = new Uint8Array();
|
|
685
|
+
if (
|
|
686
|
+
creationNode.refundTxSigningCommitment &&
|
|
687
|
+
creationNode.directRefundTxSigningCommitment &&
|
|
688
|
+
creationNode.directFromCpfpRefundTxSigningCommitment
|
|
689
|
+
) {
|
|
690
|
+
const rawCpfpRefundTx = creationNode.refundTxSigningJob?.rawTx;
|
|
691
|
+
const rawDirectRefundTx = creationNode.directRefundTxSigningJob?.rawTx;
|
|
692
|
+
const rawDirectFromCpfpRefundTx =
|
|
693
|
+
creationNode.directFromCpfpRefundTxSigningJob?.rawTx;
|
|
694
|
+
if (
|
|
695
|
+
!rawCpfpRefundTx ||
|
|
696
|
+
!rawDirectRefundTx ||
|
|
697
|
+
!rawDirectFromCpfpRefundTx
|
|
698
|
+
) {
|
|
699
|
+
throw new Error("refund transaction rawTx is undefined");
|
|
566
700
|
}
|
|
567
|
-
if (
|
|
568
|
-
|
|
701
|
+
if (
|
|
702
|
+
!creationNode.refundTxSigningJob?.signingPublicKey ||
|
|
703
|
+
!creationNode.directRefundTxSigningJob?.signingPublicKey ||
|
|
704
|
+
!creationNode.directFromCpfpRefundTxSigningJob?.signingPublicKey
|
|
705
|
+
) {
|
|
706
|
+
throw new Error("refund transaction signingPublicKey is undefined");
|
|
569
707
|
}
|
|
570
|
-
const refundTx = getTxFromRawTxBytes(rawTx);
|
|
571
|
-
const refundTxSighash = getSigHashFromTx(refundTx, 0, parentTxOutput);
|
|
572
708
|
|
|
573
|
-
const
|
|
574
|
-
|
|
709
|
+
const cpfpRefundTx = getTxFromRawTxBytes(rawCpfpRefundTx);
|
|
710
|
+
const directRefundTx = getTxFromRawTxBytes(rawDirectRefundTx);
|
|
711
|
+
const directFromCpfpRefundTx = getTxFromRawTxBytes(
|
|
712
|
+
rawDirectFromCpfpRefundTx,
|
|
713
|
+
);
|
|
714
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
715
|
+
cpfpRefundTx,
|
|
716
|
+
0,
|
|
717
|
+
cpfpNodeTx.getOutput(0),
|
|
718
|
+
);
|
|
719
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
720
|
+
directRefundTx,
|
|
721
|
+
0,
|
|
722
|
+
directNodeTx.getOutput(0),
|
|
723
|
+
);
|
|
724
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
725
|
+
directFromCpfpRefundTx,
|
|
726
|
+
0,
|
|
727
|
+
cpfpNodeTx.getOutput(0),
|
|
728
|
+
);
|
|
729
|
+
|
|
730
|
+
// Sign CPFP refund transaction
|
|
731
|
+
const cpfpRefundUserSignature = await this.config.signer.signFrost({
|
|
732
|
+
message: cpfpRefundTxSighash,
|
|
575
733
|
publicKey: creationNode.refundTxSigningJob.signingPublicKey,
|
|
576
734
|
keyDerivation: {
|
|
577
735
|
type: KeyDerivationType.LEAF,
|
|
@@ -583,8 +741,8 @@ export class TreeCreationService {
|
|
|
583
741
|
verifyingKey: internalNode.verificationKey,
|
|
584
742
|
});
|
|
585
743
|
|
|
586
|
-
|
|
587
|
-
message:
|
|
744
|
+
cpfpRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
745
|
+
message: cpfpRefundTxSighash,
|
|
588
746
|
statechainSignatures:
|
|
589
747
|
creationResponseNode.refundTxSigningResult?.signatureShares,
|
|
590
748
|
statechainPublicKeys:
|
|
@@ -593,21 +751,84 @@ export class TreeCreationService {
|
|
|
593
751
|
statechainCommitments:
|
|
594
752
|
creationResponseNode.refundTxSigningResult?.signingNonceCommitments,
|
|
595
753
|
selfCommitment: creationNode.refundTxSigningCommitment,
|
|
596
|
-
selfSignature:
|
|
754
|
+
selfSignature: cpfpRefundUserSignature,
|
|
597
755
|
publicKey: internalNode.signingPublicKey,
|
|
598
756
|
});
|
|
757
|
+
|
|
758
|
+
const keyDerivation: KeyDerivation = {
|
|
759
|
+
type: KeyDerivationType.LEAF,
|
|
760
|
+
path: creationResponseNode.nodeId,
|
|
761
|
+
};
|
|
762
|
+
// Sign direct refund transaction
|
|
763
|
+
const directRefundUserSignature = await this.config.signer.signFrost({
|
|
764
|
+
message: directRefundTxSighash,
|
|
765
|
+
publicKey: creationNode.directRefundTxSigningJob.signingPublicKey,
|
|
766
|
+
keyDerivation,
|
|
767
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
768
|
+
statechainCommitments:
|
|
769
|
+
creationResponseNode.directRefundTxSigningResult
|
|
770
|
+
?.signingNonceCommitments,
|
|
771
|
+
verifyingKey: internalNode.verificationKey,
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
directRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
775
|
+
message: directRefundTxSighash,
|
|
776
|
+
statechainSignatures:
|
|
777
|
+
creationResponseNode.directRefundTxSigningResult?.signatureShares,
|
|
778
|
+
statechainPublicKeys:
|
|
779
|
+
creationResponseNode.directRefundTxSigningResult?.publicKeys,
|
|
780
|
+
verifyingKey: internalNode.verificationKey,
|
|
781
|
+
statechainCommitments:
|
|
782
|
+
creationResponseNode.directRefundTxSigningResult
|
|
783
|
+
?.signingNonceCommitments,
|
|
784
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
785
|
+
selfSignature: directRefundUserSignature,
|
|
786
|
+
publicKey: internalNode.signingPublicKey,
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
// Sign direct from CPFP refund transaction
|
|
790
|
+
const directFromCpfpRefundUserSignature =
|
|
791
|
+
await this.config.signer.signFrost({
|
|
792
|
+
message: directFromCpfpRefundTxSighash,
|
|
793
|
+
publicKey:
|
|
794
|
+
creationNode.directFromCpfpRefundTxSigningJob.signingPublicKey,
|
|
795
|
+
keyDerivation,
|
|
796
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
797
|
+
statechainCommitments:
|
|
798
|
+
creationResponseNode.directFromCpfpRefundTxSigningResult
|
|
799
|
+
?.signingNonceCommitments,
|
|
800
|
+
verifyingKey: internalNode.verificationKey,
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
directFromCpfpRefundTxSignature = await this.config.signer.aggregateFrost(
|
|
804
|
+
{
|
|
805
|
+
message: directFromCpfpRefundTxSighash,
|
|
806
|
+
statechainSignatures:
|
|
807
|
+
creationResponseNode.directFromCpfpRefundTxSigningResult
|
|
808
|
+
?.signatureShares,
|
|
809
|
+
statechainPublicKeys:
|
|
810
|
+
creationResponseNode.directFromCpfpRefundTxSigningResult
|
|
811
|
+
?.publicKeys,
|
|
812
|
+
verifyingKey: internalNode.verificationKey,
|
|
813
|
+
statechainCommitments:
|
|
814
|
+
creationResponseNode.directFromCpfpRefundTxSigningResult
|
|
815
|
+
?.signingNonceCommitments,
|
|
816
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
817
|
+
selfSignature: directFromCpfpRefundUserSignature,
|
|
818
|
+
publicKey: internalNode.signingPublicKey,
|
|
819
|
+
},
|
|
820
|
+
);
|
|
599
821
|
}
|
|
600
822
|
|
|
601
823
|
return {
|
|
602
|
-
tx:
|
|
824
|
+
tx: cpfpNodeTx, // Return CPFP version for children
|
|
603
825
|
signature: {
|
|
604
826
|
nodeId: creationResponseNode.nodeId,
|
|
605
|
-
nodeTxSignature:
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
directFromCpfpRefundTxSignature: new Uint8Array(),
|
|
827
|
+
nodeTxSignature: cpfpNodeTxSignature,
|
|
828
|
+
directNodeTxSignature: directNodeTxSignature,
|
|
829
|
+
refundTxSignature: cpfpRefundTxSignature,
|
|
830
|
+
directRefundTxSignature: directRefundTxSignature,
|
|
831
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundTxSignature,
|
|
611
832
|
},
|
|
612
833
|
};
|
|
613
834
|
}
|