@buildonspark/spark-sdk 0.2.3 → 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 +8 -0
- package/dist/{chunk-PTRXJS7Q.js → chunk-TVUMSHWA.js} +1 -1
- package/dist/{chunk-PLLJIZC3.js → chunk-W4ZRBSWM.js} +2298 -778
- 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 +2282 -762
- package/dist/debug.d.cts +17 -4
- package/dist/debug.d.ts +17 -4
- package/dist/debug.js +2 -2
- 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 +2283 -752
- package/dist/index.d.cts +189 -8
- package/dist/index.d.ts +189 -8
- package/dist/index.js +29 -3
- package/dist/index.node.cjs +2387 -753
- package/dist/index.node.d.cts +9 -189
- package/dist/index.node.d.ts +9 -189
- package/dist/index.node.js +131 -3
- package/dist/native/index.cjs +2283 -752
- package/dist/native/index.d.cts +95 -30
- package/dist/native/index.d.ts +95 -30
- package/dist/native/index.js +2284 -767
- package/dist/{spark-wallet-CxcGPXRB.d.ts → spark-wallet-C1Tr_VKI.d.ts} +31 -25
- package/dist/{spark-wallet-DJJm19BP.d.cts → spark-wallet-DG3x2obf.d.cts} +31 -25
- 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 +570 -73
- package/dist/tests/test-utils.d.cts +11 -11
- package/dist/tests/test-utils.d.ts +11 -11
- package/dist/tests/test-utils.js +53 -16
- package/dist/types/index.cjs +13 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/dist/{xchain-address-Bh9w1SeC.d.ts → xchain-address-BHu6CpZC.d.ts} +54 -7
- package/dist/{xchain-address-SZ7dkVUE.d.cts → xchain-address-HBr6isnc.d.cts} +54 -7
- 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/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/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 +405 -153
- 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
package/dist/index.node.cjs
CHANGED
|
@@ -1290,7 +1290,10 @@ __export(index_node_exports, {
|
|
|
1290
1290
|
AuthenticationError: () => AuthenticationError,
|
|
1291
1291
|
ConfigurationError: () => ConfigurationError,
|
|
1292
1292
|
DEFAULT_FEE_SATS: () => DEFAULT_FEE_SATS,
|
|
1293
|
+
DIRECT_TIMELOCK_OFFSET: () => DIRECT_TIMELOCK_OFFSET,
|
|
1293
1294
|
DefaultSparkSigner: () => DefaultSparkSigner,
|
|
1295
|
+
INITIAL_DIRECT_SEQUENCE: () => INITIAL_DIRECT_SEQUENCE,
|
|
1296
|
+
INITIAL_SEQUENCE: () => INITIAL_SEQUENCE,
|
|
1294
1297
|
InternalValidationError: () => InternalValidationError,
|
|
1295
1298
|
KeyDerivationType: () => KeyDerivationType,
|
|
1296
1299
|
LRC_WALLET_NETWORK: () => LRC_WALLET_NETWORK,
|
|
@@ -1302,7 +1305,9 @@ __export(index_node_exports, {
|
|
|
1302
1305
|
NotImplementedError: () => NotImplementedError,
|
|
1303
1306
|
RPCError: () => RPCError,
|
|
1304
1307
|
SparkSDKError: () => SparkSDKError,
|
|
1305
|
-
SparkWallet: () =>
|
|
1308
|
+
SparkWallet: () => SparkWallet2,
|
|
1309
|
+
TEST_UNILATERAL_DIRECT_SEQUENCE: () => TEST_UNILATERAL_DIRECT_SEQUENCE,
|
|
1310
|
+
TEST_UNILATERAL_SEQUENCE: () => TEST_UNILATERAL_SEQUENCE,
|
|
1306
1311
|
TaprootOutputKeysGenerator: () => TaprootOutputKeysGenerator,
|
|
1307
1312
|
TaprootSparkSigner: () => TaprootSparkSigner,
|
|
1308
1313
|
TokenTransactionService: () => TokenTransactionService,
|
|
@@ -1322,13 +1327,21 @@ __export(index_node_exports, {
|
|
|
1322
1327
|
constructFeeBumpTx: () => constructFeeBumpTx,
|
|
1323
1328
|
constructUnilateralExitFeeBumpPackages: () => constructUnilateralExitFeeBumpPackages,
|
|
1324
1329
|
constructUnilateralExitTxs: () => constructUnilateralExitTxs,
|
|
1330
|
+
createConnectorRefundTransactions: () => createConnectorRefundTransactions,
|
|
1331
|
+
createLeafNodeTx: () => createLeafNodeTx,
|
|
1332
|
+
createNodeTx: () => createNodeTx,
|
|
1333
|
+
createNodeTxs: () => createNodeTxs,
|
|
1325
1334
|
createRefundTx: () => createRefundTx,
|
|
1335
|
+
createRefundTxs: () => createRefundTxs,
|
|
1336
|
+
createRootTx: () => createRootTx,
|
|
1326
1337
|
createSigningCommitment: () => createSigningCommitment,
|
|
1327
1338
|
createSigningNonce: () => createSigningNonce,
|
|
1339
|
+
createSplitTx: () => createSplitTx,
|
|
1328
1340
|
decodeBech32mTokenIdentifier: () => decodeBech32mTokenIdentifier,
|
|
1329
1341
|
decodeBytesToSigningCommitment: () => decodeBytesToSigningCommitment,
|
|
1330
1342
|
decodeBytesToSigningNonce: () => decodeBytesToSigningNonce,
|
|
1331
1343
|
decodeSparkAddress: () => decodeSparkAddress,
|
|
1344
|
+
doesLeafNeedRefresh: () => doesLeafNeedRefresh,
|
|
1332
1345
|
encodeBech32mTokenIdentifier: () => encodeBech32mTokenIdentifier,
|
|
1333
1346
|
encodeSigningCommitmentToBytes: () => encodeSigningCommitmentToBytes,
|
|
1334
1347
|
encodeSigningNonceToBytes: () => encodeSigningNonceToBytes,
|
|
@@ -16204,13 +16217,24 @@ function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes
|
|
|
16204
16217
|
const adaptorPrivateKey = (0, import_utils4.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
16205
16218
|
const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k12.secp256k1.CURVE.n);
|
|
16206
16219
|
const newSig = new Uint8Array([...r, ...(0, import_utils4.numberToBytesBE)(newS, 32)]);
|
|
16207
|
-
|
|
16208
|
-
|
|
16220
|
+
try {
|
|
16221
|
+
if (import_secp256k12.schnorr.verify(newSig, hash, pubkey)) {
|
|
16222
|
+
return newSig;
|
|
16223
|
+
}
|
|
16224
|
+
} catch (e) {
|
|
16225
|
+
console.error("[applyAdaptorToSignature] Addition verification failed:", e);
|
|
16209
16226
|
}
|
|
16210
16227
|
const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k12.secp256k1.CURVE.n);
|
|
16211
16228
|
const altSig = new Uint8Array([...r, ...(0, import_utils4.numberToBytesBE)(altS, 32)]);
|
|
16212
|
-
|
|
16213
|
-
|
|
16229
|
+
try {
|
|
16230
|
+
if (import_secp256k12.schnorr.verify(altSig, hash, pubkey)) {
|
|
16231
|
+
return altSig;
|
|
16232
|
+
}
|
|
16233
|
+
} catch (e) {
|
|
16234
|
+
console.error(
|
|
16235
|
+
"[applyAdaptorToSignature] Subtraction verification failed:",
|
|
16236
|
+
e
|
|
16237
|
+
);
|
|
16214
16238
|
}
|
|
16215
16239
|
throw new Error("Cannot apply adaptor to signature");
|
|
16216
16240
|
}
|
|
@@ -17104,7 +17128,11 @@ var SwapLeafFromJson = (obj) => {
|
|
|
17104
17128
|
return {
|
|
17105
17129
|
leafId: obj["swap_leaf_leaf_id"],
|
|
17106
17130
|
rawUnsignedRefundTransaction: obj["swap_leaf_raw_unsigned_refund_transaction"],
|
|
17107
|
-
adaptorSignedSignature: obj["swap_leaf_adaptor_signed_signature"]
|
|
17131
|
+
adaptorSignedSignature: obj["swap_leaf_adaptor_signed_signature"],
|
|
17132
|
+
directRawUnsignedRefundTransaction: obj["swap_leaf_direct_raw_unsigned_refund_transaction"],
|
|
17133
|
+
directAdaptorSignedSignature: obj["swap_leaf_direct_adaptor_signed_signature"],
|
|
17134
|
+
directFromCpfpRawUnsignedRefundTransaction: obj["swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction"],
|
|
17135
|
+
directFromCpfpAdaptorSignedSignature: obj["swap_leaf_direct_from_cpfp_adaptor_signed_signature"]
|
|
17108
17136
|
};
|
|
17109
17137
|
};
|
|
17110
17138
|
|
|
@@ -17359,6 +17387,10 @@ fragment LeavesSwapRequestFragment on LeavesSwapRequest {
|
|
|
17359
17387
|
swap_leaf_leaf_id: leaf_id
|
|
17360
17388
|
swap_leaf_raw_unsigned_refund_transaction: raw_unsigned_refund_transaction
|
|
17361
17389
|
swap_leaf_adaptor_signed_signature: adaptor_signed_signature
|
|
17390
|
+
swap_leaf_direct_raw_unsigned_refund_transaction: direct_raw_unsigned_refund_transaction
|
|
17391
|
+
swap_leaf_direct_adaptor_signed_signature: direct_adaptor_signed_signature
|
|
17392
|
+
swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction: direct_from_cpfp_raw_unsigned_refund_transaction
|
|
17393
|
+
swap_leaf_direct_from_cpfp_adaptor_signed_signature: direct_from_cpfp_adaptor_signed_signature
|
|
17362
17394
|
}
|
|
17363
17395
|
}`;
|
|
17364
17396
|
|
|
@@ -17705,6 +17737,10 @@ fragment UserRequestFragment on UserRequest {
|
|
|
17705
17737
|
swap_leaf_leaf_id: leaf_id
|
|
17706
17738
|
swap_leaf_raw_unsigned_refund_transaction: raw_unsigned_refund_transaction
|
|
17707
17739
|
swap_leaf_adaptor_signed_signature: adaptor_signed_signature
|
|
17740
|
+
swap_leaf_direct_raw_unsigned_refund_transaction: direct_raw_unsigned_refund_transaction
|
|
17741
|
+
swap_leaf_direct_adaptor_signed_signature: direct_adaptor_signed_signature
|
|
17742
|
+
swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction: direct_from_cpfp_raw_unsigned_refund_transaction
|
|
17743
|
+
swap_leaf_direct_from_cpfp_adaptor_signed_signature: direct_from_cpfp_adaptor_signed_signature
|
|
17708
17744
|
}
|
|
17709
17745
|
}
|
|
17710
17746
|
... on LightningReceiveRequest {
|
|
@@ -17830,18 +17866,40 @@ function mapTransferToWalletTransfer(proto, identityPublicKey) {
|
|
|
17830
17866
|
};
|
|
17831
17867
|
}
|
|
17832
17868
|
|
|
17869
|
+
// src/utils/fetch.ts
|
|
17870
|
+
init_buffer();
|
|
17871
|
+
var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch : null;
|
|
17872
|
+
var Headers = globalThis.Headers ?? null;
|
|
17873
|
+
var getFetch = () => {
|
|
17874
|
+
if (!fetchImpl) {
|
|
17875
|
+
throw new Error(
|
|
17876
|
+
"Fetch implementation is not set. Please set it using setFetch()."
|
|
17877
|
+
);
|
|
17878
|
+
}
|
|
17879
|
+
if (!Headers) {
|
|
17880
|
+
throw new Error(
|
|
17881
|
+
"Headers implementation is not set. Please set it using setFetch()."
|
|
17882
|
+
);
|
|
17883
|
+
}
|
|
17884
|
+
return {
|
|
17885
|
+
fetch: fetchImpl,
|
|
17886
|
+
Headers
|
|
17887
|
+
};
|
|
17888
|
+
};
|
|
17889
|
+
|
|
17833
17890
|
// src/utils/mempool.ts
|
|
17834
17891
|
async function getLatestDepositTxId(address2) {
|
|
17892
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
17835
17893
|
const network = getNetworkFromAddress(address2);
|
|
17836
17894
|
const baseUrl = network === BitcoinNetwork_default.REGTEST ? getElectrsUrl("REGTEST") : getElectrsUrl("MAINNET");
|
|
17837
|
-
const headers =
|
|
17895
|
+
const headers = new Headers2();
|
|
17838
17896
|
if (network === BitcoinNetwork_default.REGTEST) {
|
|
17839
17897
|
const auth = btoa(
|
|
17840
17898
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
17841
17899
|
);
|
|
17842
|
-
headers
|
|
17900
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
17843
17901
|
}
|
|
17844
|
-
const response = await
|
|
17902
|
+
const response = await fetch2(`${baseUrl}/address/${address2}/txs`, {
|
|
17845
17903
|
headers
|
|
17846
17904
|
});
|
|
17847
17905
|
const addressTxs = await response.json();
|
|
@@ -17858,14 +17916,15 @@ async function getLatestDepositTxId(address2) {
|
|
|
17858
17916
|
return null;
|
|
17859
17917
|
}
|
|
17860
17918
|
async function isTxBroadcast(txid, baseUrl, network) {
|
|
17861
|
-
const
|
|
17919
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
17920
|
+
const headers = new Headers2();
|
|
17862
17921
|
if (network === 3 /* REGTEST */) {
|
|
17863
17922
|
const auth = btoa(
|
|
17864
17923
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
17865
17924
|
);
|
|
17866
|
-
headers
|
|
17925
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
17867
17926
|
}
|
|
17868
|
-
const response = await
|
|
17927
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}`, {
|
|
17869
17928
|
headers
|
|
17870
17929
|
});
|
|
17871
17930
|
const tx = await response.json();
|
|
@@ -18336,7 +18395,14 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
18336
18395
|
// src/utils/transaction.ts
|
|
18337
18396
|
init_buffer();
|
|
18338
18397
|
var import_btc_signer = require("@scure/btc-signer");
|
|
18398
|
+
var INITIAL_TIMELOCK = 2e3;
|
|
18399
|
+
var TEST_UNILATERAL_TIMELOCK = 100;
|
|
18339
18400
|
var TIME_LOCK_INTERVAL = 100;
|
|
18401
|
+
var DIRECT_TIMELOCK_OFFSET = 50;
|
|
18402
|
+
var INITIAL_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK;
|
|
18403
|
+
var INITIAL_DIRECT_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
18404
|
+
var TEST_UNILATERAL_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK;
|
|
18405
|
+
var TEST_UNILATERAL_DIRECT_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
18340
18406
|
var ESTIMATED_TX_SIZE = 191;
|
|
18341
18407
|
var DEFAULT_SATS_PER_VBYTE = 5;
|
|
18342
18408
|
var DEFAULT_FEE_SATS = ESTIMATED_TX_SIZE * DEFAULT_SATS_PER_VBYTE;
|
|
@@ -18346,29 +18412,270 @@ function maybeApplyFee(amount) {
|
|
|
18346
18412
|
}
|
|
18347
18413
|
return amount;
|
|
18348
18414
|
}
|
|
18349
|
-
function
|
|
18350
|
-
const
|
|
18415
|
+
function createRootTx(depositOutPoint, depositTxOut) {
|
|
18416
|
+
const cpfpRootTx = new import_btc_signer.Transaction({
|
|
18417
|
+
version: 3,
|
|
18418
|
+
allowUnknownOutputs: true
|
|
18419
|
+
});
|
|
18420
|
+
cpfpRootTx.addInput(depositOutPoint);
|
|
18421
|
+
cpfpRootTx.addOutput(depositTxOut);
|
|
18422
|
+
cpfpRootTx.addOutput(getEphemeralAnchorOutput());
|
|
18423
|
+
const directRootTx = new import_btc_signer.Transaction({
|
|
18424
|
+
version: 3,
|
|
18425
|
+
allowUnknownOutputs: true
|
|
18426
|
+
});
|
|
18427
|
+
directRootTx.addInput(depositOutPoint);
|
|
18428
|
+
directRootTx.addOutput({
|
|
18429
|
+
script: depositTxOut.script,
|
|
18430
|
+
amount: maybeApplyFee(depositTxOut.amount ?? 0n)
|
|
18431
|
+
});
|
|
18432
|
+
return [cpfpRootTx, directRootTx];
|
|
18433
|
+
}
|
|
18434
|
+
function createSplitTx(parentOutPoint, childTxOuts) {
|
|
18435
|
+
const cpfpSplitTx = new import_btc_signer.Transaction({
|
|
18436
|
+
version: 3,
|
|
18437
|
+
allowUnknownOutputs: true
|
|
18438
|
+
});
|
|
18439
|
+
cpfpSplitTx.addInput(parentOutPoint);
|
|
18440
|
+
for (const txOut of childTxOuts) {
|
|
18441
|
+
cpfpSplitTx.addOutput(txOut);
|
|
18442
|
+
}
|
|
18443
|
+
cpfpSplitTx.addOutput(getEphemeralAnchorOutput());
|
|
18444
|
+
const directSplitTx = new import_btc_signer.Transaction({
|
|
18445
|
+
version: 3,
|
|
18446
|
+
allowUnknownOutputs: true
|
|
18447
|
+
});
|
|
18448
|
+
directSplitTx.addInput(parentOutPoint);
|
|
18449
|
+
let totalOutputAmount = 0n;
|
|
18450
|
+
for (const txOut of childTxOuts) {
|
|
18451
|
+
totalOutputAmount += txOut.amount ?? 0n;
|
|
18452
|
+
}
|
|
18453
|
+
if (totalOutputAmount > BigInt(DEFAULT_FEE_SATS)) {
|
|
18454
|
+
const feeRatio = Number(DEFAULT_FEE_SATS) / Number(totalOutputAmount);
|
|
18455
|
+
for (const txOut of childTxOuts) {
|
|
18456
|
+
const adjustedAmount = BigInt(
|
|
18457
|
+
Math.floor(Number(txOut.amount ?? 0n) * (1 - feeRatio))
|
|
18458
|
+
);
|
|
18459
|
+
directSplitTx.addOutput({
|
|
18460
|
+
script: txOut.script,
|
|
18461
|
+
amount: adjustedAmount
|
|
18462
|
+
});
|
|
18463
|
+
}
|
|
18464
|
+
} else {
|
|
18465
|
+
for (const txOut of childTxOuts) {
|
|
18466
|
+
directSplitTx.addOutput(txOut);
|
|
18467
|
+
}
|
|
18468
|
+
}
|
|
18469
|
+
return [cpfpSplitTx, directSplitTx];
|
|
18470
|
+
}
|
|
18471
|
+
function createNodeTx({
|
|
18472
|
+
txOut,
|
|
18473
|
+
parentOutPoint,
|
|
18474
|
+
applyFee,
|
|
18475
|
+
includeAnchor
|
|
18476
|
+
}) {
|
|
18477
|
+
const nodeTx = new import_btc_signer.Transaction({
|
|
18478
|
+
version: 3,
|
|
18479
|
+
allowUnknownOutputs: true
|
|
18480
|
+
});
|
|
18481
|
+
nodeTx.addInput(parentOutPoint);
|
|
18482
|
+
if (applyFee) {
|
|
18483
|
+
nodeTx.addOutput({
|
|
18484
|
+
script: txOut.script,
|
|
18485
|
+
amount: maybeApplyFee(txOut.amount ?? 0n)
|
|
18486
|
+
});
|
|
18487
|
+
} else {
|
|
18488
|
+
nodeTx.addOutput(txOut);
|
|
18489
|
+
}
|
|
18490
|
+
if (includeAnchor) {
|
|
18491
|
+
nodeTx.addOutput(getEphemeralAnchorOutput());
|
|
18492
|
+
}
|
|
18493
|
+
return nodeTx;
|
|
18494
|
+
}
|
|
18495
|
+
function createNodeTxs(txOut, txIn, directTxIn) {
|
|
18496
|
+
const cpfpNodeTx = createNodeTx({
|
|
18497
|
+
txOut,
|
|
18498
|
+
parentOutPoint: txIn,
|
|
18499
|
+
includeAnchor: true
|
|
18500
|
+
});
|
|
18501
|
+
let directNodeTx;
|
|
18502
|
+
if (directTxIn) {
|
|
18503
|
+
directNodeTx = createNodeTx({
|
|
18504
|
+
txOut,
|
|
18505
|
+
parentOutPoint: directTxIn,
|
|
18506
|
+
includeAnchor: false,
|
|
18507
|
+
applyFee: true
|
|
18508
|
+
});
|
|
18509
|
+
}
|
|
18510
|
+
return { cpfpNodeTx, directNodeTx };
|
|
18511
|
+
}
|
|
18512
|
+
function createLeafNodeTx(sequence, directSequence, parentOutPoint, txOut, shouldCalculateFee) {
|
|
18513
|
+
const cpfpLeafTx = new import_btc_signer.Transaction({
|
|
18514
|
+
version: 3,
|
|
18515
|
+
allowUnknownOutputs: true
|
|
18516
|
+
});
|
|
18517
|
+
cpfpLeafTx.addInput({
|
|
18518
|
+
...parentOutPoint,
|
|
18519
|
+
sequence
|
|
18520
|
+
});
|
|
18521
|
+
cpfpLeafTx.addOutput(txOut);
|
|
18522
|
+
cpfpLeafTx.addOutput(getEphemeralAnchorOutput());
|
|
18523
|
+
const directLeafTx = new import_btc_signer.Transaction({
|
|
18524
|
+
version: 3,
|
|
18525
|
+
allowUnknownOutputs: true
|
|
18526
|
+
});
|
|
18527
|
+
directLeafTx.addInput({
|
|
18528
|
+
...parentOutPoint,
|
|
18529
|
+
sequence: directSequence
|
|
18530
|
+
});
|
|
18531
|
+
const amountSats = txOut.amount ?? 0n;
|
|
18532
|
+
let outputAmount = amountSats;
|
|
18533
|
+
if (shouldCalculateFee) {
|
|
18534
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
18535
|
+
}
|
|
18536
|
+
directLeafTx.addOutput({
|
|
18537
|
+
script: txOut.script,
|
|
18538
|
+
amount: outputAmount
|
|
18539
|
+
});
|
|
18540
|
+
return [cpfpLeafTx, directLeafTx];
|
|
18541
|
+
}
|
|
18542
|
+
function createRefundTx({
|
|
18543
|
+
sequence,
|
|
18544
|
+
input,
|
|
18545
|
+
amountSats,
|
|
18546
|
+
receivingPubkey,
|
|
18547
|
+
network,
|
|
18548
|
+
shouldCalculateFee,
|
|
18549
|
+
includeAnchor
|
|
18550
|
+
}) {
|
|
18551
|
+
const refundTx = new import_btc_signer.Transaction({
|
|
18351
18552
|
version: 3,
|
|
18352
18553
|
allowUnknownOutputs: true
|
|
18353
18554
|
});
|
|
18354
|
-
|
|
18355
|
-
...
|
|
18555
|
+
refundTx.addInput({
|
|
18556
|
+
...input,
|
|
18356
18557
|
sequence
|
|
18357
18558
|
});
|
|
18358
18559
|
const refundPkScript = getP2TRScriptFromPublicKey(receivingPubkey, network);
|
|
18359
|
-
|
|
18560
|
+
let outputAmount = amountSats;
|
|
18561
|
+
if (shouldCalculateFee) {
|
|
18562
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
18563
|
+
}
|
|
18564
|
+
refundTx.addOutput({
|
|
18360
18565
|
script: refundPkScript,
|
|
18566
|
+
amount: outputAmount
|
|
18567
|
+
});
|
|
18568
|
+
if (includeAnchor) {
|
|
18569
|
+
refundTx.addOutput(getEphemeralAnchorOutput());
|
|
18570
|
+
}
|
|
18571
|
+
return refundTx;
|
|
18572
|
+
}
|
|
18573
|
+
function createRefundTxs({
|
|
18574
|
+
sequence,
|
|
18575
|
+
directSequence,
|
|
18576
|
+
input,
|
|
18577
|
+
directInput,
|
|
18578
|
+
amountSats,
|
|
18579
|
+
receivingPubkey,
|
|
18580
|
+
network
|
|
18581
|
+
}) {
|
|
18582
|
+
const cpfpRefundTx = createRefundTx({
|
|
18583
|
+
sequence,
|
|
18584
|
+
input,
|
|
18585
|
+
amountSats,
|
|
18586
|
+
receivingPubkey,
|
|
18587
|
+
network,
|
|
18588
|
+
shouldCalculateFee: false,
|
|
18589
|
+
includeAnchor: true
|
|
18590
|
+
});
|
|
18591
|
+
let directRefundTx;
|
|
18592
|
+
let directFromCpfpRefundTx;
|
|
18593
|
+
if (directSequence && directInput) {
|
|
18594
|
+
directRefundTx = createRefundTx({
|
|
18595
|
+
sequence: directSequence,
|
|
18596
|
+
input: directInput,
|
|
18597
|
+
amountSats,
|
|
18598
|
+
receivingPubkey,
|
|
18599
|
+
network,
|
|
18600
|
+
shouldCalculateFee: true,
|
|
18601
|
+
includeAnchor: false
|
|
18602
|
+
});
|
|
18603
|
+
directFromCpfpRefundTx = createRefundTx({
|
|
18604
|
+
sequence: directSequence,
|
|
18605
|
+
input,
|
|
18606
|
+
amountSats,
|
|
18607
|
+
receivingPubkey,
|
|
18608
|
+
network,
|
|
18609
|
+
shouldCalculateFee: true,
|
|
18610
|
+
includeAnchor: false
|
|
18611
|
+
});
|
|
18612
|
+
} else if (directInput && !directSequence) {
|
|
18613
|
+
throw new ValidationError(
|
|
18614
|
+
"directSequence must be provided if directInput is",
|
|
18615
|
+
{
|
|
18616
|
+
field: "directSequence",
|
|
18617
|
+
value: directSequence
|
|
18618
|
+
}
|
|
18619
|
+
);
|
|
18620
|
+
}
|
|
18621
|
+
return { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx };
|
|
18622
|
+
}
|
|
18623
|
+
function createConnectorRefundTransactions(sequence, cpfpNodeOutPoint, directNodeOutPoint, connectorOutput, amountSats, receiverPubKey, network, shouldCalculateFee) {
|
|
18624
|
+
const cpfpRefundTx = new import_btc_signer.Transaction({
|
|
18625
|
+
version: 3,
|
|
18626
|
+
allowUnknownOutputs: true
|
|
18627
|
+
});
|
|
18628
|
+
cpfpRefundTx.addInput({
|
|
18629
|
+
...cpfpNodeOutPoint,
|
|
18630
|
+
sequence
|
|
18631
|
+
});
|
|
18632
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
18633
|
+
const receiverScript = getP2TRScriptFromPublicKey(receiverPubKey, network);
|
|
18634
|
+
cpfpRefundTx.addOutput({
|
|
18635
|
+
script: receiverScript,
|
|
18361
18636
|
amount: amountSats
|
|
18362
18637
|
});
|
|
18363
|
-
|
|
18364
|
-
|
|
18638
|
+
const directRefundTx = new import_btc_signer.Transaction({
|
|
18639
|
+
version: 3,
|
|
18640
|
+
allowUnknownOutputs: true
|
|
18641
|
+
});
|
|
18642
|
+
directRefundTx.addInput({
|
|
18643
|
+
...directNodeOutPoint,
|
|
18644
|
+
sequence
|
|
18645
|
+
});
|
|
18646
|
+
directRefundTx.addInput(connectorOutput);
|
|
18647
|
+
let outputAmount = amountSats;
|
|
18648
|
+
if (shouldCalculateFee) {
|
|
18649
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
18650
|
+
}
|
|
18651
|
+
directRefundTx.addOutput({
|
|
18652
|
+
script: receiverScript,
|
|
18653
|
+
amount: outputAmount
|
|
18654
|
+
});
|
|
18655
|
+
const directFromCpfpTx = new import_btc_signer.Transaction({
|
|
18656
|
+
version: 3,
|
|
18657
|
+
allowUnknownOutputs: true
|
|
18658
|
+
});
|
|
18659
|
+
directFromCpfpTx.addInput({
|
|
18660
|
+
...cpfpNodeOutPoint,
|
|
18661
|
+
sequence
|
|
18662
|
+
});
|
|
18663
|
+
directFromCpfpTx.addInput(connectorOutput);
|
|
18664
|
+
directFromCpfpTx.addOutput({
|
|
18665
|
+
script: receiverScript,
|
|
18666
|
+
amount: outputAmount
|
|
18667
|
+
});
|
|
18668
|
+
return [cpfpRefundTx, directRefundTx, directFromCpfpTx];
|
|
18365
18669
|
}
|
|
18366
18670
|
function getCurrentTimelock(currSequence) {
|
|
18367
18671
|
return (currSequence || 0) & 65535;
|
|
18368
18672
|
}
|
|
18369
18673
|
function getTransactionSequence(currSequence) {
|
|
18370
18674
|
const timelock = getCurrentTimelock(currSequence);
|
|
18371
|
-
return
|
|
18675
|
+
return {
|
|
18676
|
+
nextSequence: 1 << 30 | timelock,
|
|
18677
|
+
nextDirectSequence: 1 << 30 | timelock + DIRECT_TIMELOCK_OFFSET
|
|
18678
|
+
};
|
|
18372
18679
|
}
|
|
18373
18680
|
function checkIfValidSequence(currSequence) {
|
|
18374
18681
|
const TIME_LOCK_ACTIVE = (currSequence || 0) & 2147483648;
|
|
@@ -18386,24 +18693,32 @@ function checkIfValidSequence(currSequence) {
|
|
|
18386
18693
|
});
|
|
18387
18694
|
}
|
|
18388
18695
|
}
|
|
18389
|
-
function
|
|
18696
|
+
function doesLeafNeedRefresh(currSequence, isNodeTx) {
|
|
18390
18697
|
const currentTimelock = getCurrentTimelock(currSequence);
|
|
18391
|
-
|
|
18392
|
-
|
|
18393
|
-
return {
|
|
18394
|
-
nextSequence: 1 << 30 | nextTimelock,
|
|
18395
|
-
needRefresh: true
|
|
18396
|
-
};
|
|
18698
|
+
if (isNodeTx) {
|
|
18699
|
+
return currentTimelock === 0;
|
|
18397
18700
|
}
|
|
18398
|
-
|
|
18701
|
+
return currentTimelock <= 100;
|
|
18702
|
+
}
|
|
18703
|
+
function getNextTransactionSequence(currSequence, isNodeTx) {
|
|
18704
|
+
const currentTimelock = getCurrentTimelock(currSequence);
|
|
18705
|
+
const nextTimelock = currentTimelock - TIME_LOCK_INTERVAL;
|
|
18706
|
+
if (isNodeTx && nextTimelock < 0) {
|
|
18399
18707
|
throw new ValidationError("timelock interval is less than 0", {
|
|
18400
18708
|
field: "nextTimelock",
|
|
18401
|
-
value: nextTimelock
|
|
18709
|
+
value: nextTimelock,
|
|
18710
|
+
expected: "Non-negative timelock interval"
|
|
18711
|
+
});
|
|
18712
|
+
} else if (!isNodeTx && nextTimelock <= 0) {
|
|
18713
|
+
throw new ValidationError("timelock interval is less than or equal to 0", {
|
|
18714
|
+
field: "nextTimelock",
|
|
18715
|
+
value: nextTimelock,
|
|
18716
|
+
expected: "Timelock greater than 0"
|
|
18402
18717
|
});
|
|
18403
18718
|
}
|
|
18404
18719
|
return {
|
|
18405
18720
|
nextSequence: 1 << 30 | nextTimelock,
|
|
18406
|
-
|
|
18721
|
+
nextDirectSequence: 1 << 30 | nextTimelock + DIRECT_TIMELOCK_OFFSET
|
|
18407
18722
|
};
|
|
18408
18723
|
}
|
|
18409
18724
|
function getEphemeralAnchorOutput() {
|
|
@@ -18932,7 +19247,7 @@ init_buffer();
|
|
|
18932
19247
|
var import_core8 = require("@lightsparkdev/core");
|
|
18933
19248
|
var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
18934
19249
|
var isBun = globalThis.Bun !== void 0;
|
|
18935
|
-
var packageVersion = true ? "0.2.
|
|
19250
|
+
var packageVersion = true ? "0.2.4" : "unknown";
|
|
18936
19251
|
var baseEnvStr = "unknown";
|
|
18937
19252
|
if (isBun) {
|
|
18938
19253
|
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
@@ -19481,6 +19796,9 @@ var TaprootSparkSigner = class extends DefaultSparkSigner {
|
|
|
19481
19796
|
}
|
|
19482
19797
|
};
|
|
19483
19798
|
|
|
19799
|
+
// src/spark-wallet/spark-wallet.node.ts
|
|
19800
|
+
init_buffer();
|
|
19801
|
+
|
|
19484
19802
|
// src/spark-wallet/spark-wallet.ts
|
|
19485
19803
|
init_buffer();
|
|
19486
19804
|
var import_core12 = require("@lightsparkdev/core");
|
|
@@ -19643,10 +19961,18 @@ init_buffer();
|
|
|
19643
19961
|
var CompleteLeavesSwap = `
|
|
19644
19962
|
mutation CompleteLeavesSwap(
|
|
19645
19963
|
$adaptor_secret_key: String!
|
|
19964
|
+
$direct_adaptor_secret_key: String!
|
|
19965
|
+
$direct_from_cpfp_adaptor_secret_key: String!
|
|
19646
19966
|
$user_outbound_transfer_external_id: UUID!
|
|
19647
19967
|
$leaves_swap_request_id: ID!
|
|
19648
19968
|
) {
|
|
19649
|
-
complete_leaves_swap(input: {
|
|
19969
|
+
complete_leaves_swap(input: {
|
|
19970
|
+
adaptor_secret_key: $adaptor_secret_key,
|
|
19971
|
+
direct_adaptor_secret_key: $direct_adaptor_secret_key,
|
|
19972
|
+
direct_from_cpfp_adaptor_secret_key: $direct_from_cpfp_adaptor_secret_key,
|
|
19973
|
+
user_outbound_transfer_external_id: $user_outbound_transfer_external_id,
|
|
19974
|
+
leaves_swap_request_id: $leaves_swap_request_id
|
|
19975
|
+
}) {
|
|
19650
19976
|
request {
|
|
19651
19977
|
...LeavesSwapRequestFragment
|
|
19652
19978
|
}
|
|
@@ -19777,6 +20103,8 @@ init_buffer();
|
|
|
19777
20103
|
var RequestSwapLeaves = `
|
|
19778
20104
|
mutation RequestSwapLeaves(
|
|
19779
20105
|
$adaptor_pubkey: PublicKey!
|
|
20106
|
+
$direct_adaptor_pubkey: PublicKey
|
|
20107
|
+
$direct_from_cpfp_adaptor_pubkey: PublicKey
|
|
19780
20108
|
$total_amount_sats: Long!
|
|
19781
20109
|
$target_amount_sats: Long!
|
|
19782
20110
|
$fee_sats: Long!
|
|
@@ -19786,6 +20114,8 @@ var RequestSwapLeaves = `
|
|
|
19786
20114
|
) {
|
|
19787
20115
|
request_leaves_swap(input: {
|
|
19788
20116
|
adaptor_pubkey: $adaptor_pubkey
|
|
20117
|
+
direct_adaptor_pubkey: $direct_adaptor_pubkey
|
|
20118
|
+
direct_from_cpfp_adaptor_pubkey: $direct_from_cpfp_adaptor_pubkey
|
|
19789
20119
|
total_amount_sats: $total_amount_sats
|
|
19790
20120
|
target_amount_sats: $target_amount_sats
|
|
19791
20121
|
fee_sats: $fee_sats
|
|
@@ -20294,6 +20624,8 @@ var SspClient = class {
|
|
|
20294
20624
|
}
|
|
20295
20625
|
async requestLeaveSwap({
|
|
20296
20626
|
adaptorPubkey,
|
|
20627
|
+
directAdaptorPubkey,
|
|
20628
|
+
directFromCpfpAdaptorPubkey,
|
|
20297
20629
|
totalAmountSats,
|
|
20298
20630
|
targetAmountSats,
|
|
20299
20631
|
feeSats,
|
|
@@ -20305,6 +20637,8 @@ var SspClient = class {
|
|
|
20305
20637
|
queryPayload: RequestSwapLeaves,
|
|
20306
20638
|
variables: {
|
|
20307
20639
|
adaptor_pubkey: adaptorPubkey,
|
|
20640
|
+
direct_adaptor_pubkey: directAdaptorPubkey,
|
|
20641
|
+
direct_from_cpfp_adaptor_pubkey: directFromCpfpAdaptorPubkey,
|
|
20308
20642
|
total_amount_sats: totalAmountSats,
|
|
20309
20643
|
target_amount_sats: targetAmountSats,
|
|
20310
20644
|
fee_sats: feeSats,
|
|
@@ -20323,6 +20657,8 @@ var SspClient = class {
|
|
|
20323
20657
|
}
|
|
20324
20658
|
async completeLeaveSwap({
|
|
20325
20659
|
adaptorSecretKey,
|
|
20660
|
+
directAdaptorSecretKey,
|
|
20661
|
+
directFromCpfpAdaptorSecretKey,
|
|
20326
20662
|
userOutboundTransferExternalId,
|
|
20327
20663
|
leavesSwapRequestId
|
|
20328
20664
|
}) {
|
|
@@ -20330,6 +20666,8 @@ var SspClient = class {
|
|
|
20330
20666
|
queryPayload: CompleteLeavesSwap,
|
|
20331
20667
|
variables: {
|
|
20332
20668
|
adaptor_secret_key: adaptorSecretKey,
|
|
20669
|
+
direct_adaptor_secret_key: directAdaptorSecretKey,
|
|
20670
|
+
direct_from_cpfp_adaptor_secret_key: directFromCpfpAdaptorSecretKey,
|
|
20333
20671
|
user_outbound_transfer_external_id: userOutboundTransferExternalId,
|
|
20334
20672
|
leaves_swap_request_id: leavesSwapRequestId
|
|
20335
20673
|
},
|
|
@@ -24494,11 +24832,7 @@ var import_sha28 = require("@noble/hashes/sha2");
|
|
|
24494
24832
|
var import_btc_signer2 = require("@scure/btc-signer");
|
|
24495
24833
|
var ecies2 = __toESM(require("eciesjs"), 1);
|
|
24496
24834
|
var import_uuidv72 = require("uuidv7");
|
|
24497
|
-
var INITIAL_TIME_LOCK = 2e3;
|
|
24498
24835
|
var DEFAULT_EXPIRY_TIME = 10 * 60 * 1e3;
|
|
24499
|
-
function initialSequence() {
|
|
24500
|
-
return 1 << 30 | INITIAL_TIME_LOCK;
|
|
24501
|
-
}
|
|
24502
24836
|
function getSigningJobProto(signingJob) {
|
|
24503
24837
|
return {
|
|
24504
24838
|
signingPublicKey: signingJob.signingPublicKey,
|
|
@@ -24515,12 +24849,14 @@ var BaseTransferService = class {
|
|
|
24515
24849
|
this.connectionManager = connectionManager;
|
|
24516
24850
|
this.signingService = signingService;
|
|
24517
24851
|
}
|
|
24518
|
-
async sendTransferTweakKey(transfer, leaves,
|
|
24852
|
+
async sendTransferTweakKey(transfer, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
24519
24853
|
const keyTweakInputMap = await this.prepareSendTransferKeyTweaks(
|
|
24520
24854
|
transfer.id,
|
|
24521
24855
|
transfer.receiverIdentityPublicKey,
|
|
24522
24856
|
leaves,
|
|
24523
|
-
|
|
24857
|
+
cpfpRefundSignatureMap,
|
|
24858
|
+
directRefundSignatureMap,
|
|
24859
|
+
directFromCpfpRefundSignatureMap
|
|
24524
24860
|
);
|
|
24525
24861
|
let updatedTransfer;
|
|
24526
24862
|
const coordinatorOperator = this.config.getSigningOperators()[this.config.getCoordinatorIdentifier()];
|
|
@@ -24558,13 +24894,26 @@ var BaseTransferService = class {
|
|
|
24558
24894
|
}
|
|
24559
24895
|
return updatedTransfer;
|
|
24560
24896
|
}
|
|
24561
|
-
async deliverTransferPackage(transfer, leaves,
|
|
24897
|
+
async deliverTransferPackage(transfer, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
24562
24898
|
const keyTweakInputMap = await this.prepareSendTransferKeyTweaks(
|
|
24563
24899
|
transfer.id,
|
|
24564
24900
|
transfer.receiverIdentityPublicKey,
|
|
24565
24901
|
leaves,
|
|
24566
|
-
|
|
24902
|
+
cpfpRefundSignatureMap,
|
|
24903
|
+
directRefundSignatureMap,
|
|
24904
|
+
directFromCpfpRefundSignatureMap
|
|
24567
24905
|
);
|
|
24906
|
+
for (const [key, operator] of Object.entries(
|
|
24907
|
+
this.config.getSigningOperators()
|
|
24908
|
+
)) {
|
|
24909
|
+
const tweaks = keyTweakInputMap.get(key);
|
|
24910
|
+
if (!tweaks) {
|
|
24911
|
+
throw new ValidationError("No tweaks for operator", {
|
|
24912
|
+
field: "operator",
|
|
24913
|
+
value: key
|
|
24914
|
+
});
|
|
24915
|
+
}
|
|
24916
|
+
}
|
|
24568
24917
|
const transferPackage = await this.prepareTransferPackage(
|
|
24569
24918
|
transfer.id,
|
|
24570
24919
|
keyTweakInputMap,
|
|
@@ -24590,6 +24939,8 @@ var BaseTransferService = class {
|
|
|
24590
24939
|
transferID,
|
|
24591
24940
|
receiverIdentityPubkey,
|
|
24592
24941
|
leaves,
|
|
24942
|
+
/* @__PURE__ */ new Map(),
|
|
24943
|
+
/* @__PURE__ */ new Map(),
|
|
24593
24944
|
/* @__PURE__ */ new Map()
|
|
24594
24945
|
);
|
|
24595
24946
|
const transferPackage = await this.prepareTransferPackage(
|
|
@@ -24603,7 +24954,7 @@ var BaseTransferService = class {
|
|
|
24603
24954
|
);
|
|
24604
24955
|
let response;
|
|
24605
24956
|
try {
|
|
24606
|
-
response = await sparkClient.
|
|
24957
|
+
response = await sparkClient.start_transfer_v2({
|
|
24607
24958
|
transferId: transferID,
|
|
24608
24959
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
24609
24960
|
receiverIdentityPublicKey: receiverIdentityPubkey,
|
|
@@ -24632,12 +24983,22 @@ var BaseTransferService = class {
|
|
|
24632
24983
|
nodes.push(leaf.leaf.id);
|
|
24633
24984
|
}
|
|
24634
24985
|
const signingCommitments = await sparkClient.get_signing_commitments({
|
|
24635
|
-
nodeIds: nodes
|
|
24986
|
+
nodeIds: nodes,
|
|
24987
|
+
count: 3
|
|
24636
24988
|
});
|
|
24637
|
-
const
|
|
24989
|
+
const {
|
|
24990
|
+
cpfpLeafSigningJobs,
|
|
24991
|
+
directLeafSigningJobs,
|
|
24992
|
+
directFromCpfpLeafSigningJobs
|
|
24993
|
+
} = await this.signingService.signRefunds(
|
|
24638
24994
|
leaves,
|
|
24639
|
-
|
|
24640
|
-
|
|
24995
|
+
receiverIdentityPubkey,
|
|
24996
|
+
signingCommitments.signingCommitments.slice(0, leaves.length),
|
|
24997
|
+
signingCommitments.signingCommitments.slice(
|
|
24998
|
+
leaves.length,
|
|
24999
|
+
2 * leaves.length
|
|
25000
|
+
),
|
|
25001
|
+
signingCommitments.signingCommitments.slice(2 * leaves.length)
|
|
24641
25002
|
);
|
|
24642
25003
|
const encryptedKeyTweaks = {};
|
|
24643
25004
|
for (const [key, value] of keyTweakInputMap) {
|
|
@@ -24657,12 +25018,11 @@ var BaseTransferService = class {
|
|
|
24657
25018
|
encryptedKeyTweaks[key] = Uint8Array.from(encryptedProto);
|
|
24658
25019
|
}
|
|
24659
25020
|
const transferPackage = {
|
|
24660
|
-
leavesToSend:
|
|
25021
|
+
leavesToSend: cpfpLeafSigningJobs,
|
|
24661
25022
|
keyTweakPackage: encryptedKeyTweaks,
|
|
24662
25023
|
userSignature: new Uint8Array(),
|
|
24663
|
-
|
|
24664
|
-
|
|
24665
|
-
directFromCpfpLeavesToSend: []
|
|
25024
|
+
directLeavesToSend: directLeafSigningJobs,
|
|
25025
|
+
directFromCpfpLeavesToSend: directFromCpfpLeafSigningJobs
|
|
24666
25026
|
};
|
|
24667
25027
|
const transferPackageSigningPayload = getTransferPackageSigningPayload(
|
|
24668
25028
|
transferID,
|
|
@@ -24722,7 +25082,7 @@ var BaseTransferService = class {
|
|
|
24722
25082
|
}
|
|
24723
25083
|
return updatedTransfer;
|
|
24724
25084
|
}
|
|
24725
|
-
async signRefunds(leafDataMap, operatorSigningResults,
|
|
25085
|
+
async signRefunds(leafDataMap, operatorSigningResults, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
24726
25086
|
const nodeSignatures = [];
|
|
24727
25087
|
for (const operatorSigningResult of operatorSigningResults) {
|
|
24728
25088
|
const leafData = leafDataMap.get(operatorSigningResult.leafId);
|
|
@@ -24737,54 +25097,120 @@ var BaseTransferService = class {
|
|
|
24737
25097
|
`Output not found for leaf ${operatorSigningResult.leafId}`
|
|
24738
25098
|
);
|
|
24739
25099
|
}
|
|
24740
|
-
const
|
|
25100
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
25101
|
+
leafData.refundTx,
|
|
25102
|
+
0,
|
|
25103
|
+
txOutput
|
|
25104
|
+
);
|
|
24741
25105
|
const publicKey = await this.config.signer.getPublicKeyFromDerivation(
|
|
24742
25106
|
leafData.keyDerivation
|
|
24743
25107
|
);
|
|
24744
|
-
const
|
|
24745
|
-
message:
|
|
25108
|
+
const cpfpUserSignature = await this.config.signer.signFrost({
|
|
25109
|
+
message: cpfpRefundTxSighash,
|
|
24746
25110
|
publicKey,
|
|
24747
25111
|
keyDerivation: leafData.keyDerivation,
|
|
24748
25112
|
selfCommitment: leafData.signingNonceCommitment,
|
|
24749
25113
|
statechainCommitments: operatorSigningResult.refundTxSigningResult?.signingNonceCommitments,
|
|
24750
|
-
adaptorPubKey,
|
|
25114
|
+
adaptorPubKey: cpfpAdaptorPubKey,
|
|
24751
25115
|
verifyingKey: operatorSigningResult.verifyingKey
|
|
24752
25116
|
});
|
|
24753
|
-
const
|
|
24754
|
-
message:
|
|
25117
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25118
|
+
message: cpfpRefundTxSighash,
|
|
24755
25119
|
statechainSignatures: operatorSigningResult.refundTxSigningResult?.signatureShares,
|
|
24756
25120
|
statechainPublicKeys: operatorSigningResult.refundTxSigningResult?.publicKeys,
|
|
24757
25121
|
verifyingKey: operatorSigningResult.verifyingKey,
|
|
24758
25122
|
statechainCommitments: operatorSigningResult.refundTxSigningResult?.signingNonceCommitments,
|
|
24759
25123
|
selfCommitment: leafData.signingNonceCommitment,
|
|
24760
25124
|
publicKey,
|
|
24761
|
-
selfSignature:
|
|
24762
|
-
adaptorPubKey
|
|
25125
|
+
selfSignature: cpfpUserSignature,
|
|
25126
|
+
adaptorPubKey: cpfpAdaptorPubKey
|
|
24763
25127
|
});
|
|
25128
|
+
let directRefundAggregate;
|
|
25129
|
+
let directFromCpfpRefundAggregate;
|
|
25130
|
+
if (leafData.directTx) {
|
|
25131
|
+
const directTxOutput = leafData.directTx.getOutput(0);
|
|
25132
|
+
if (leafData.directRefundTx) {
|
|
25133
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
25134
|
+
leafData.directRefundTx,
|
|
25135
|
+
0,
|
|
25136
|
+
directTxOutput
|
|
25137
|
+
);
|
|
25138
|
+
const directUserSignature = await this.config.signer.signFrost({
|
|
25139
|
+
message: directRefundTxSighash,
|
|
25140
|
+
publicKey,
|
|
25141
|
+
keyDerivation: leafData.keyDerivation,
|
|
25142
|
+
selfCommitment: leafData.directSigningNonceCommitment,
|
|
25143
|
+
statechainCommitments: operatorSigningResult.directRefundTxSigningResult?.signingNonceCommitments,
|
|
25144
|
+
adaptorPubKey: directAdaptorPubKey,
|
|
25145
|
+
verifyingKey: operatorSigningResult.verifyingKey
|
|
25146
|
+
});
|
|
25147
|
+
directRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25148
|
+
message: directRefundTxSighash,
|
|
25149
|
+
statechainSignatures: operatorSigningResult.directRefundTxSigningResult?.signatureShares,
|
|
25150
|
+
statechainPublicKeys: operatorSigningResult.directRefundTxSigningResult?.publicKeys,
|
|
25151
|
+
verifyingKey: operatorSigningResult.verifyingKey,
|
|
25152
|
+
statechainCommitments: operatorSigningResult.directRefundTxSigningResult?.signingNonceCommitments,
|
|
25153
|
+
selfCommitment: leafData.directSigningNonceCommitment,
|
|
25154
|
+
publicKey,
|
|
25155
|
+
selfSignature: directUserSignature,
|
|
25156
|
+
adaptorPubKey: directAdaptorPubKey
|
|
25157
|
+
});
|
|
25158
|
+
}
|
|
25159
|
+
if (leafData.directFromCpfpRefundTx) {
|
|
25160
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
25161
|
+
leafData.directFromCpfpRefundTx,
|
|
25162
|
+
0,
|
|
25163
|
+
txOutput
|
|
25164
|
+
);
|
|
25165
|
+
const directFromCpfpUserSignature = await this.config.signer.signFrost({
|
|
25166
|
+
message: directFromCpfpRefundTxSighash,
|
|
25167
|
+
publicKey,
|
|
25168
|
+
keyDerivation: leafData.keyDerivation,
|
|
25169
|
+
selfCommitment: leafData.directFromCpfpRefundSigningNonceCommitment,
|
|
25170
|
+
statechainCommitments: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
25171
|
+
adaptorPubKey: directFromCpfpAdaptorPubKey,
|
|
25172
|
+
verifyingKey: operatorSigningResult.verifyingKey
|
|
25173
|
+
});
|
|
25174
|
+
directFromCpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25175
|
+
message: directFromCpfpRefundTxSighash,
|
|
25176
|
+
statechainSignatures: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signatureShares,
|
|
25177
|
+
statechainPublicKeys: operatorSigningResult.directFromCpfpRefundTxSigningResult?.publicKeys,
|
|
25178
|
+
verifyingKey: operatorSigningResult.verifyingKey,
|
|
25179
|
+
statechainCommitments: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
25180
|
+
selfCommitment: leafData.directFromCpfpRefundSigningNonceCommitment,
|
|
25181
|
+
publicKey,
|
|
25182
|
+
selfSignature: directFromCpfpUserSignature,
|
|
25183
|
+
adaptorPubKey: directFromCpfpAdaptorPubKey
|
|
25184
|
+
});
|
|
25185
|
+
}
|
|
25186
|
+
}
|
|
24764
25187
|
nodeSignatures.push({
|
|
24765
25188
|
nodeId: operatorSigningResult.leafId,
|
|
24766
|
-
refundTxSignature: refundAggregate,
|
|
24767
25189
|
nodeTxSignature: new Uint8Array(),
|
|
24768
|
-
// TODO: Add direct refund signature
|
|
24769
25190
|
directNodeTxSignature: new Uint8Array(),
|
|
24770
|
-
|
|
24771
|
-
|
|
25191
|
+
refundTxSignature: cpfpRefundAggregate,
|
|
25192
|
+
directRefundTxSignature: directRefundAggregate ?? new Uint8Array(),
|
|
25193
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundAggregate ?? new Uint8Array()
|
|
24772
25194
|
});
|
|
24773
25195
|
}
|
|
24774
25196
|
return nodeSignatures;
|
|
24775
25197
|
}
|
|
24776
|
-
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves,
|
|
25198
|
+
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
24777
25199
|
const receiverEciesPubKey = ecies2.PublicKey.fromHex(
|
|
24778
25200
|
(0, import_utils14.bytesToHex)(receiverIdentityPubkey)
|
|
24779
25201
|
);
|
|
24780
25202
|
const leavesTweaksMap = /* @__PURE__ */ new Map();
|
|
24781
25203
|
for (const leaf of leaves) {
|
|
24782
|
-
const
|
|
25204
|
+
const cpfpRefundSignature = cpfpRefundSignatureMap.get(leaf.leaf.id);
|
|
25205
|
+
const directRefundSignature = directRefundSignatureMap.get(leaf.leaf.id);
|
|
25206
|
+
const directFromCpfpRefundSignature = directFromCpfpRefundSignatureMap.get(leaf.leaf.id);
|
|
24783
25207
|
const leafTweaksMap = await this.prepareSingleSendTransferKeyTweak(
|
|
24784
25208
|
transferID,
|
|
24785
25209
|
leaf,
|
|
24786
25210
|
receiverEciesPubKey,
|
|
24787
|
-
|
|
25211
|
+
cpfpRefundSignature,
|
|
25212
|
+
directRefundSignature,
|
|
25213
|
+
directFromCpfpRefundSignature
|
|
24788
25214
|
);
|
|
24789
25215
|
for (const [identifier, leafTweak] of leafTweaksMap) {
|
|
24790
25216
|
leavesTweaksMap.set(identifier, [
|
|
@@ -24795,7 +25221,7 @@ var BaseTransferService = class {
|
|
|
24795
25221
|
}
|
|
24796
25222
|
return leavesTweaksMap;
|
|
24797
25223
|
}
|
|
24798
|
-
async prepareSingleSendTransferKeyTweak(transferID, leaf, receiverEciesPubKey,
|
|
25224
|
+
async prepareSingleSendTransferKeyTweak(transferID, leaf, receiverEciesPubKey, cpfpRefundSignature, directRefundSignature, directFromCpfpRefundSignature) {
|
|
24799
25225
|
const signingOperators = this.config.getSigningOperators();
|
|
24800
25226
|
const { shares, secretCipher } = await this.config.signer.subtractSplitAndEncrypt({
|
|
24801
25227
|
first: leaf.keyDerivation,
|
|
@@ -24843,10 +25269,9 @@ var BaseTransferService = class {
|
|
|
24843
25269
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak),
|
|
24844
25270
|
secretCipher,
|
|
24845
25271
|
signature,
|
|
24846
|
-
refundSignature:
|
|
24847
|
-
|
|
24848
|
-
|
|
24849
|
-
directFromCpfpRefundSignature: new Uint8Array()
|
|
25272
|
+
refundSignature: cpfpRefundSignature ?? new Uint8Array(),
|
|
25273
|
+
directRefundSignature: directRefundSignature ?? new Uint8Array(),
|
|
25274
|
+
directFromCpfpRefundSignature: directFromCpfpRefundSignature ?? new Uint8Array()
|
|
24850
25275
|
});
|
|
24851
25276
|
}
|
|
24852
25277
|
return leafTweaksMap;
|
|
@@ -24876,7 +25301,12 @@ var TransferService = class extends BaseTransferService {
|
|
|
24876
25301
|
* Deprecated in v0.1.32
|
|
24877
25302
|
*/
|
|
24878
25303
|
async sendTransfer(leaves, receiverIdentityPubkey) {
|
|
24879
|
-
const {
|
|
25304
|
+
const {
|
|
25305
|
+
transfer,
|
|
25306
|
+
signatureMap,
|
|
25307
|
+
directSignatureMap,
|
|
25308
|
+
directFromCpfpSignatureMap
|
|
25309
|
+
} = await this.sendTransferSignRefund(
|
|
24880
25310
|
leaves,
|
|
24881
25311
|
receiverIdentityPubkey,
|
|
24882
25312
|
new Date(Date.now() + DEFAULT_EXPIRY_TIME)
|
|
@@ -24884,7 +25314,9 @@ var TransferService = class extends BaseTransferService {
|
|
|
24884
25314
|
const transferWithTweakedKeys = await this.sendTransferTweakKey(
|
|
24885
25315
|
transfer,
|
|
24886
25316
|
leaves,
|
|
24887
|
-
signatureMap
|
|
25317
|
+
signatureMap,
|
|
25318
|
+
directSignatureMap,
|
|
25319
|
+
directFromCpfpSignatureMap
|
|
24888
25320
|
);
|
|
24889
25321
|
return transferWithTweakedKeys;
|
|
24890
25322
|
}
|
|
@@ -24988,7 +25420,13 @@ var TransferService = class extends BaseTransferService {
|
|
|
24988
25420
|
return transferResp.transfers[0];
|
|
24989
25421
|
}
|
|
24990
25422
|
async sendTransferSignRefund(leaves, receiverIdentityPubkey, expiryTime) {
|
|
24991
|
-
const {
|
|
25423
|
+
const {
|
|
25424
|
+
transfer,
|
|
25425
|
+
signatureMap,
|
|
25426
|
+
directSignatureMap,
|
|
25427
|
+
directFromCpfpSignatureMap,
|
|
25428
|
+
leafDataMap
|
|
25429
|
+
} = await this.sendTransferSignRefundInternal(
|
|
24992
25430
|
leaves,
|
|
24993
25431
|
receiverIdentityPubkey,
|
|
24994
25432
|
expiryTime,
|
|
@@ -24997,11 +25435,19 @@ var TransferService = class extends BaseTransferService {
|
|
|
24997
25435
|
return {
|
|
24998
25436
|
transfer,
|
|
24999
25437
|
signatureMap,
|
|
25438
|
+
directSignatureMap,
|
|
25439
|
+
directFromCpfpSignatureMap,
|
|
25000
25440
|
leafDataMap
|
|
25001
25441
|
};
|
|
25002
25442
|
}
|
|
25003
25443
|
async startSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime) {
|
|
25004
|
-
const {
|
|
25444
|
+
const {
|
|
25445
|
+
transfer,
|
|
25446
|
+
signatureMap,
|
|
25447
|
+
directSignatureMap,
|
|
25448
|
+
directFromCpfpSignatureMap,
|
|
25449
|
+
leafDataMap
|
|
25450
|
+
} = await this.sendTransferSignRefundInternal(
|
|
25005
25451
|
leaves,
|
|
25006
25452
|
receiverIdentityPubkey,
|
|
25007
25453
|
expiryTime,
|
|
@@ -25010,31 +25456,45 @@ var TransferService = class extends BaseTransferService {
|
|
|
25010
25456
|
return {
|
|
25011
25457
|
transfer,
|
|
25012
25458
|
signatureMap,
|
|
25459
|
+
directSignatureMap,
|
|
25460
|
+
directFromCpfpSignatureMap,
|
|
25013
25461
|
leafDataMap
|
|
25014
25462
|
};
|
|
25015
25463
|
}
|
|
25016
|
-
async counterSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime,
|
|
25464
|
+
async counterSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
25017
25465
|
return this.sendTransferSignRefundInternal(
|
|
25018
25466
|
leaves,
|
|
25019
25467
|
receiverIdentityPubkey,
|
|
25020
25468
|
expiryTime,
|
|
25021
25469
|
true,
|
|
25022
|
-
|
|
25470
|
+
cpfpAdaptorPubKey,
|
|
25471
|
+
directAdaptorPubKey,
|
|
25472
|
+
directFromCpfpAdaptorPubKey
|
|
25023
25473
|
);
|
|
25024
25474
|
}
|
|
25025
|
-
async sendTransferSignRefundInternal(leaves, receiverIdentityPubkey, expiryTime, forSwap,
|
|
25475
|
+
async sendTransferSignRefundInternal(leaves, receiverIdentityPubkey, expiryTime, forSwap, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
25026
25476
|
const transferId = (0, import_uuidv72.uuidv7)();
|
|
25027
25477
|
const leafDataMap = /* @__PURE__ */ new Map();
|
|
25028
25478
|
for (const leaf of leaves) {
|
|
25029
25479
|
const signingNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25480
|
+
const directSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25481
|
+
const directFromCpfpRefundSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25030
25482
|
const tx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
25031
25483
|
const refundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
25484
|
+
const directTx = leaf.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directTx) : void 0;
|
|
25485
|
+
const directRefundTx = leaf.leaf.directRefundTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directRefundTx) : void 0;
|
|
25486
|
+
const directFromCpfpRefundTx = leaf.leaf.directFromCpfpRefundTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directFromCpfpRefundTx) : void 0;
|
|
25032
25487
|
leafDataMap.set(leaf.leaf.id, {
|
|
25033
25488
|
keyDerivation: leaf.keyDerivation,
|
|
25034
25489
|
receivingPubkey: receiverIdentityPubkey,
|
|
25035
25490
|
signingNonceCommitment,
|
|
25491
|
+
directSigningNonceCommitment,
|
|
25036
25492
|
tx,
|
|
25493
|
+
directTx,
|
|
25037
25494
|
refundTx,
|
|
25495
|
+
directRefundTx,
|
|
25496
|
+
directFromCpfpRefundTx,
|
|
25497
|
+
directFromCpfpRefundSigningNonceCommitment,
|
|
25038
25498
|
vout: leaf.leaf.vout
|
|
25039
25499
|
});
|
|
25040
25500
|
}
|
|
@@ -25047,8 +25507,8 @@ var TransferService = class extends BaseTransferService {
|
|
|
25047
25507
|
);
|
|
25048
25508
|
let response;
|
|
25049
25509
|
try {
|
|
25050
|
-
if (
|
|
25051
|
-
response = await sparkClient.
|
|
25510
|
+
if (cpfpAdaptorPubKey !== void 0 || directAdaptorPubKey !== void 0 || directFromCpfpAdaptorPubKey !== void 0) {
|
|
25511
|
+
response = await sparkClient.counter_leaf_swap_v2({
|
|
25052
25512
|
transfer: {
|
|
25053
25513
|
transferId,
|
|
25054
25514
|
leavesToSend: signingJobs,
|
|
@@ -25057,10 +25517,12 @@ var TransferService = class extends BaseTransferService {
|
|
|
25057
25517
|
expiryTime
|
|
25058
25518
|
},
|
|
25059
25519
|
swapId: (0, import_uuidv72.uuidv7)(),
|
|
25060
|
-
adaptorPublicKey:
|
|
25520
|
+
adaptorPublicKey: cpfpAdaptorPubKey,
|
|
25521
|
+
directAdaptorPublicKey: directAdaptorPubKey,
|
|
25522
|
+
directFromCpfpAdaptorPublicKey: directFromCpfpAdaptorPubKey
|
|
25061
25523
|
});
|
|
25062
25524
|
} else if (forSwap) {
|
|
25063
|
-
response = await sparkClient.
|
|
25525
|
+
response = await sparkClient.start_leaf_swap_v2({
|
|
25064
25526
|
transferId,
|
|
25065
25527
|
leavesToSend: signingJobs,
|
|
25066
25528
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
@@ -25068,7 +25530,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25068
25530
|
expiryTime
|
|
25069
25531
|
});
|
|
25070
25532
|
} else {
|
|
25071
|
-
response = await sparkClient.
|
|
25533
|
+
response = await sparkClient.start_transfer_v2({
|
|
25072
25534
|
transferId,
|
|
25073
25535
|
leavesToSend: signingJobs,
|
|
25074
25536
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
@@ -25085,15 +25547,29 @@ var TransferService = class extends BaseTransferService {
|
|
|
25085
25547
|
const signatures = await this.signRefunds(
|
|
25086
25548
|
leafDataMap,
|
|
25087
25549
|
response.signingResults,
|
|
25088
|
-
|
|
25550
|
+
cpfpAdaptorPubKey,
|
|
25551
|
+
directAdaptorPubKey,
|
|
25552
|
+
directFromCpfpAdaptorPubKey
|
|
25089
25553
|
);
|
|
25090
|
-
const
|
|
25554
|
+
const cpfpSignatureMap = /* @__PURE__ */ new Map();
|
|
25555
|
+
const directSignatureMap = /* @__PURE__ */ new Map();
|
|
25556
|
+
const directFromCpfpSignatureMap = /* @__PURE__ */ new Map();
|
|
25091
25557
|
for (const signature of signatures) {
|
|
25092
|
-
|
|
25558
|
+
cpfpSignatureMap.set(signature.nodeId, signature.refundTxSignature);
|
|
25559
|
+
directSignatureMap.set(
|
|
25560
|
+
signature.nodeId,
|
|
25561
|
+
signature.directRefundTxSignature
|
|
25562
|
+
);
|
|
25563
|
+
directFromCpfpSignatureMap.set(
|
|
25564
|
+
signature.nodeId,
|
|
25565
|
+
signature.directFromCpfpRefundTxSignature
|
|
25566
|
+
);
|
|
25093
25567
|
}
|
|
25094
25568
|
return {
|
|
25095
25569
|
transfer: response.transfer,
|
|
25096
|
-
signatureMap,
|
|
25570
|
+
signatureMap: cpfpSignatureMap,
|
|
25571
|
+
directSignatureMap,
|
|
25572
|
+
directFromCpfpSignatureMap,
|
|
25097
25573
|
leafDataMap,
|
|
25098
25574
|
signingResults: response.signingResults
|
|
25099
25575
|
};
|
|
@@ -25106,38 +25582,68 @@ var TransferService = class extends BaseTransferService {
|
|
|
25106
25582
|
throw new Error(`Leaf data not found for leaf ${leaf.leaf.id}`);
|
|
25107
25583
|
}
|
|
25108
25584
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
25109
|
-
const
|
|
25585
|
+
const cpfpNodeOutPoint = {
|
|
25110
25586
|
txid: (0, import_utils14.hexToBytes)(getTxId(nodeTx)),
|
|
25111
25587
|
index: 0
|
|
25112
25588
|
};
|
|
25589
|
+
let directNodeTx;
|
|
25590
|
+
let directNodeOutPoint;
|
|
25591
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
25592
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
25593
|
+
directNodeOutPoint = {
|
|
25594
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(directNodeTx)),
|
|
25595
|
+
index: 0
|
|
25596
|
+
};
|
|
25597
|
+
}
|
|
25113
25598
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
25114
|
-
const
|
|
25599
|
+
const sequence = currRefundTx.getInput(0).sequence;
|
|
25600
|
+
if (!sequence) {
|
|
25601
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
25602
|
+
field: "sequence",
|
|
25603
|
+
value: currRefundTx.getInput(0),
|
|
25604
|
+
expected: "Non-null sequence"
|
|
25605
|
+
});
|
|
25606
|
+
}
|
|
25607
|
+
const { nextSequence, nextDirectSequence } = isForClaim ? getTransactionSequence(sequence) : getNextTransactionSequence(sequence);
|
|
25115
25608
|
const amountSats = currRefundTx.getOutput(0).amount;
|
|
25116
25609
|
if (amountSats === void 0) {
|
|
25117
25610
|
throw new Error("Amount not found in signRefunds");
|
|
25118
25611
|
}
|
|
25119
|
-
const
|
|
25120
|
-
nextSequence,
|
|
25121
|
-
|
|
25612
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
25613
|
+
sequence: nextSequence,
|
|
25614
|
+
directSequence: nextDirectSequence,
|
|
25615
|
+
input: cpfpNodeOutPoint,
|
|
25616
|
+
directInput: directNodeOutPoint,
|
|
25122
25617
|
amountSats,
|
|
25123
|
-
refundSigningData.receivingPubkey,
|
|
25124
|
-
this.config.getNetwork()
|
|
25618
|
+
receivingPubkey: refundSigningData.receivingPubkey,
|
|
25619
|
+
network: this.config.getNetwork()
|
|
25620
|
+
});
|
|
25621
|
+
refundSigningData.refundTx = cpfpRefundTx;
|
|
25622
|
+
refundSigningData.directRefundTx = directRefundTx;
|
|
25623
|
+
refundSigningData.directFromCpfpRefundTx = directFromCpfpRefundTx;
|
|
25624
|
+
const cpfpRefundNonceCommitmentProto = refundSigningData.signingNonceCommitment;
|
|
25625
|
+
const directRefundNonceCommitmentProto = refundSigningData.directSigningNonceCommitment;
|
|
25626
|
+
const directFromCpfpRefundNonceCommitmentProto = refundSigningData.directFromCpfpRefundSigningNonceCommitment;
|
|
25627
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(
|
|
25628
|
+
refundSigningData.keyDerivation
|
|
25125
25629
|
);
|
|
25126
|
-
refundSigningData.refundTx = refundTx;
|
|
25127
|
-
const refundNonceCommitmentProto = refundSigningData.signingNonceCommitment;
|
|
25128
25630
|
signingJobs.push({
|
|
25129
25631
|
leafId: leaf.leaf.id,
|
|
25130
25632
|
refundTxSigningJob: {
|
|
25131
|
-
signingPublicKey
|
|
25132
|
-
|
|
25133
|
-
|
|
25134
|
-
rawTx: refundTx.toBytes(),
|
|
25135
|
-
signingNonceCommitment: refundNonceCommitmentProto.commitment
|
|
25633
|
+
signingPublicKey,
|
|
25634
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
25635
|
+
signingNonceCommitment: cpfpRefundNonceCommitmentProto.commitment
|
|
25136
25636
|
},
|
|
25137
|
-
|
|
25138
|
-
|
|
25139
|
-
|
|
25140
|
-
|
|
25637
|
+
directRefundTxSigningJob: directRefundTx ? {
|
|
25638
|
+
signingPublicKey,
|
|
25639
|
+
rawTx: directRefundTx.toBytes(),
|
|
25640
|
+
signingNonceCommitment: directRefundNonceCommitmentProto.commitment
|
|
25641
|
+
} : void 0,
|
|
25642
|
+
directFromCpfpRefundTxSigningJob: directFromCpfpRefundTx ? {
|
|
25643
|
+
signingPublicKey,
|
|
25644
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
25645
|
+
signingNonceCommitment: directFromCpfpRefundNonceCommitmentProto.commitment
|
|
25646
|
+
} : void 0
|
|
25141
25647
|
});
|
|
25142
25648
|
}
|
|
25143
25649
|
return signingJobs;
|
|
@@ -25258,13 +25764,17 @@ var TransferService = class extends BaseTransferService {
|
|
|
25258
25764
|
const leafDataMap = /* @__PURE__ */ new Map();
|
|
25259
25765
|
for (const leafKey of leafKeys) {
|
|
25260
25766
|
const tx = getTxFromRawTxBytes(leafKey.leaf.nodeTx);
|
|
25767
|
+
const directTx = leafKey.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leafKey.leaf.directTx) : void 0;
|
|
25261
25768
|
leafDataMap.set(leafKey.leaf.id, {
|
|
25262
25769
|
keyDerivation: leafKey.newKeyDerivation,
|
|
25263
25770
|
receivingPubkey: await this.config.signer.getPublicKeyFromDerivation(
|
|
25264
25771
|
leafKey.newKeyDerivation
|
|
25265
25772
|
),
|
|
25266
25773
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25774
|
+
directSigningNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25775
|
+
directFromCpfpRefundSigningNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25267
25776
|
tx,
|
|
25777
|
+
directTx,
|
|
25268
25778
|
vout: leafKey.leaf.vout
|
|
25269
25779
|
});
|
|
25270
25780
|
}
|
|
@@ -25286,7 +25796,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25286
25796
|
}
|
|
25287
25797
|
}
|
|
25288
25798
|
try {
|
|
25289
|
-
resp = await sparkClient.
|
|
25799
|
+
resp = await sparkClient.claim_transfer_sign_refunds_v2({
|
|
25290
25800
|
transferId: transfer.id,
|
|
25291
25801
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25292
25802
|
signingJobs
|
|
@@ -25301,7 +25811,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
25301
25811
|
this.config.getCoordinatorAddress()
|
|
25302
25812
|
);
|
|
25303
25813
|
try {
|
|
25304
|
-
return await sparkClient.
|
|
25814
|
+
return await sparkClient.finalize_node_signatures_v2({
|
|
25305
25815
|
intent: 1 /* TRANSFER */,
|
|
25306
25816
|
nodeSignatures
|
|
25307
25817
|
});
|
|
@@ -25340,109 +25850,134 @@ var TransferService = class extends BaseTransferService {
|
|
|
25340
25850
|
throw new Error(`Error querying pending transfers by sender: ${error}`);
|
|
25341
25851
|
}
|
|
25342
25852
|
}
|
|
25343
|
-
async
|
|
25344
|
-
if (nodes.length === 0) {
|
|
25345
|
-
throw Error("no nodes to refresh");
|
|
25346
|
-
}
|
|
25853
|
+
async refreshTimelockNodesInternal(node, parentNode, useTestUnilateralSequence) {
|
|
25347
25854
|
const signingJobs = [];
|
|
25348
|
-
const
|
|
25349
|
-
|
|
25350
|
-
|
|
25351
|
-
|
|
25352
|
-
|
|
25353
|
-
|
|
25354
|
-
|
|
25355
|
-
|
|
25356
|
-
|
|
25357
|
-
|
|
25358
|
-
|
|
25359
|
-
|
|
25360
|
-
|
|
25361
|
-
|
|
25362
|
-
|
|
25363
|
-
|
|
25364
|
-
|
|
25365
|
-
|
|
25366
|
-
|
|
25367
|
-
|
|
25368
|
-
|
|
25369
|
-
|
|
25370
|
-
|
|
25371
|
-
newTx.addOutput(additionalOutput);
|
|
25372
|
-
}
|
|
25373
|
-
}
|
|
25374
|
-
if (i === 0) {
|
|
25375
|
-
const currSequence = input.sequence;
|
|
25376
|
-
newTx.addInput({
|
|
25377
|
-
...input,
|
|
25378
|
-
sequence: getNextTransactionSequence(currSequence).nextSequence
|
|
25379
|
-
});
|
|
25380
|
-
} else {
|
|
25381
|
-
newTx.addInput({
|
|
25382
|
-
...input,
|
|
25383
|
-
sequence: initialSequence(),
|
|
25384
|
-
txid: newNodeTxs[i - 1]?.id
|
|
25385
|
-
});
|
|
25386
|
-
}
|
|
25387
|
-
signingJobs.push({
|
|
25388
|
-
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation({
|
|
25389
|
-
type: "leaf" /* LEAF */,
|
|
25390
|
-
path: node.id
|
|
25391
|
-
}),
|
|
25392
|
-
rawTx: newTx.toBytes(),
|
|
25393
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
25855
|
+
const parentNodeTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
25856
|
+
const parentNodeOutput = parentNodeTx.getOutput(0);
|
|
25857
|
+
if (!parentNodeOutput) {
|
|
25858
|
+
throw Error("Could not get parent node output");
|
|
25859
|
+
}
|
|
25860
|
+
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
25861
|
+
const nodeInput = nodeTx.getInput(0);
|
|
25862
|
+
const nodeOutput = nodeTx.getOutput(0);
|
|
25863
|
+
if (!nodeOutput) {
|
|
25864
|
+
throw Error("Could not get node output");
|
|
25865
|
+
}
|
|
25866
|
+
let directNodeTx;
|
|
25867
|
+
let directNodeInput;
|
|
25868
|
+
if (node.directTx.length > 0) {
|
|
25869
|
+
directNodeTx = getTxFromRawTxBytes(node.directTx);
|
|
25870
|
+
directNodeInput = directNodeTx.getInput(0);
|
|
25871
|
+
}
|
|
25872
|
+
const currSequence = nodeInput.sequence;
|
|
25873
|
+
if (!currSequence) {
|
|
25874
|
+
throw new ValidationError("Invalid node transaction", {
|
|
25875
|
+
field: "sequence",
|
|
25876
|
+
value: nodeInput,
|
|
25877
|
+
expected: "Non-null sequence"
|
|
25394
25878
|
});
|
|
25395
|
-
newNodeTxs[i] = newTx;
|
|
25396
25879
|
}
|
|
25397
|
-
|
|
25398
|
-
|
|
25399
|
-
|
|
25880
|
+
let { nextSequence, nextDirectSequence } = getNextTransactionSequence(
|
|
25881
|
+
currSequence,
|
|
25882
|
+
true
|
|
25883
|
+
);
|
|
25884
|
+
const output = {
|
|
25885
|
+
script: parentNodeOutput.script,
|
|
25886
|
+
amount: parentNodeOutput.amount
|
|
25887
|
+
};
|
|
25888
|
+
const newNodeInput = {
|
|
25889
|
+
txid: nodeInput.txid,
|
|
25890
|
+
index: nodeInput.index,
|
|
25891
|
+
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_SEQUENCE : nextSequence
|
|
25892
|
+
};
|
|
25893
|
+
const newDirectInput = directNodeTx && directNodeInput ? {
|
|
25894
|
+
txid: directNodeInput.txid,
|
|
25895
|
+
index: directNodeInput.index,
|
|
25896
|
+
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_DIRECT_SEQUENCE : nextDirectSequence
|
|
25897
|
+
} : void 0;
|
|
25898
|
+
const { cpfpNodeTx, directNodeTx: newDirectNodeTx } = createNodeTxs(
|
|
25899
|
+
output,
|
|
25900
|
+
newNodeInput,
|
|
25901
|
+
newDirectInput
|
|
25902
|
+
);
|
|
25903
|
+
const newCpfpNodeOutput = cpfpNodeTx.getOutput(0);
|
|
25904
|
+
if (!newCpfpNodeOutput) {
|
|
25905
|
+
throw Error("Could not get new cpfp node output");
|
|
25400
25906
|
}
|
|
25401
|
-
const
|
|
25402
|
-
const
|
|
25403
|
-
|
|
25404
|
-
|
|
25907
|
+
const newDirectNodeOutput = newDirectNodeTx?.getOutput(0);
|
|
25908
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
25909
|
+
type: "leaf" /* LEAF */,
|
|
25910
|
+
path: node.id
|
|
25405
25911
|
});
|
|
25406
|
-
|
|
25407
|
-
|
|
25408
|
-
|
|
25409
|
-
|
|
25410
|
-
|
|
25411
|
-
|
|
25412
|
-
amount: originalRefundOutput.amount
|
|
25912
|
+
signingJobs.push({
|
|
25913
|
+
signingPublicKey,
|
|
25914
|
+
rawTx: cpfpNodeTx.toBytes(),
|
|
25915
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25916
|
+
type: "node",
|
|
25917
|
+
parentTxOut: parentNodeOutput
|
|
25413
25918
|
});
|
|
25414
|
-
|
|
25415
|
-
|
|
25416
|
-
|
|
25417
|
-
|
|
25418
|
-
|
|
25419
|
-
|
|
25420
|
-
|
|
25421
|
-
|
|
25422
|
-
throw Error("refund tx doesn't have input");
|
|
25919
|
+
if (newDirectNodeTx) {
|
|
25920
|
+
signingJobs.push({
|
|
25921
|
+
signingPublicKey,
|
|
25922
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
25923
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25924
|
+
type: "directNode",
|
|
25925
|
+
parentTxOut: parentNodeOutput
|
|
25926
|
+
});
|
|
25423
25927
|
}
|
|
25424
|
-
|
|
25425
|
-
|
|
25928
|
+
const newCpfpRefundOutPoint = {
|
|
25929
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(cpfpNodeTx)),
|
|
25930
|
+
index: 0
|
|
25931
|
+
};
|
|
25932
|
+
let newDirectRefundOutPoint;
|
|
25933
|
+
if (newDirectNodeTx) {
|
|
25934
|
+
newDirectRefundOutPoint = {
|
|
25935
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
25936
|
+
index: 0
|
|
25937
|
+
};
|
|
25426
25938
|
}
|
|
25427
|
-
|
|
25428
|
-
|
|
25429
|
-
|
|
25430
|
-
|
|
25431
|
-
|
|
25432
|
-
|
|
25433
|
-
|
|
25939
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
25940
|
+
sequence: INITIAL_SEQUENCE,
|
|
25941
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
25942
|
+
input: newCpfpRefundOutPoint,
|
|
25943
|
+
directInput: newDirectRefundOutPoint,
|
|
25944
|
+
amountSats: nodeOutput.amount,
|
|
25945
|
+
receivingPubkey: await this.config.signer.getPublicKeyFromDerivation({
|
|
25434
25946
|
type: "leaf" /* LEAF */,
|
|
25435
|
-
path:
|
|
25947
|
+
path: node.id
|
|
25436
25948
|
}),
|
|
25437
|
-
|
|
25438
|
-
|
|
25439
|
-
|
|
25440
|
-
|
|
25949
|
+
network: this.config.getNetwork()
|
|
25950
|
+
});
|
|
25951
|
+
signingJobs.push({
|
|
25952
|
+
signingPublicKey,
|
|
25953
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
25954
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25955
|
+
type: "cpfp",
|
|
25956
|
+
parentTxOut: newCpfpNodeOutput
|
|
25957
|
+
});
|
|
25958
|
+
if (directRefundTx && newDirectNodeOutput) {
|
|
25959
|
+
signingJobs.push({
|
|
25960
|
+
signingPublicKey,
|
|
25961
|
+
rawTx: directRefundTx.toBytes(),
|
|
25962
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25963
|
+
type: "direct",
|
|
25964
|
+
parentTxOut: newDirectNodeOutput
|
|
25965
|
+
});
|
|
25966
|
+
}
|
|
25967
|
+
if (directFromCpfpRefundTx && newCpfpNodeOutput) {
|
|
25968
|
+
signingJobs.push({
|
|
25969
|
+
signingPublicKey,
|
|
25970
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
25971
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25972
|
+
type: "directFromCpfp",
|
|
25973
|
+
parentTxOut: newCpfpNodeOutput
|
|
25974
|
+
});
|
|
25975
|
+
}
|
|
25441
25976
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
25442
25977
|
this.config.getCoordinatorAddress()
|
|
25443
25978
|
);
|
|
25444
|
-
const response = await sparkClient.
|
|
25445
|
-
leafId:
|
|
25979
|
+
const response = await sparkClient.refresh_timelock_v2({
|
|
25980
|
+
leafId: node.id,
|
|
25446
25981
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25447
25982
|
signingJobs: signingJobs.map(getSigningJobProto)
|
|
25448
25983
|
});
|
|
@@ -25452,45 +25987,27 @@ var TransferService = class extends BaseTransferService {
|
|
|
25452
25987
|
);
|
|
25453
25988
|
}
|
|
25454
25989
|
let nodeSignatures = [];
|
|
25455
|
-
let
|
|
25456
|
-
let
|
|
25457
|
-
let
|
|
25458
|
-
|
|
25459
|
-
|
|
25990
|
+
let leafCpfpSignature;
|
|
25991
|
+
let leafDirectSignature;
|
|
25992
|
+
let cpfpRefundSignature;
|
|
25993
|
+
let directRefundSignature;
|
|
25994
|
+
let directFromCpfpRefundSignature;
|
|
25995
|
+
for (const [i, signingResult] of response.signingResults.entries()) {
|
|
25460
25996
|
const signingJob = signingJobs[i];
|
|
25461
25997
|
if (!signingJob || !signingResult) {
|
|
25462
25998
|
throw Error("Signing job does not exist");
|
|
25463
25999
|
}
|
|
25464
|
-
if (!signingJob.signingNonceCommitment) {
|
|
25465
|
-
throw Error("nonce commitment does not exist");
|
|
25466
|
-
}
|
|
25467
26000
|
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
25468
|
-
|
|
25469
|
-
|
|
25470
|
-
|
|
25471
|
-
if (i === nodes.length) {
|
|
25472
|
-
nodeId = nodes[i - 1]?.id;
|
|
25473
|
-
parentTx = newNodeTxs[i - 1];
|
|
25474
|
-
vout = 0;
|
|
25475
|
-
} else if (i === 0) {
|
|
25476
|
-
nodeId = nodes[i]?.id;
|
|
25477
|
-
parentTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
25478
|
-
vout = nodes[i]?.vout;
|
|
25479
|
-
} else {
|
|
25480
|
-
nodeId = nodes[i]?.id;
|
|
25481
|
-
parentTx = newNodeTxs[i - 1];
|
|
25482
|
-
vout = nodes[i]?.vout;
|
|
26001
|
+
const txOut = signingJob.parentTxOut;
|
|
26002
|
+
if (!txOut) {
|
|
26003
|
+
throw Error("Could not get tx out");
|
|
25483
26004
|
}
|
|
25484
|
-
if (!parentTx || !nodeId || vout === void 0) {
|
|
25485
|
-
throw Error("Could not parse signing results");
|
|
25486
|
-
}
|
|
25487
|
-
const txOut = parentTx.getOutput(vout);
|
|
25488
26005
|
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
25489
26006
|
const userSignature = await this.config.signer.signFrost({
|
|
25490
26007
|
message: rawTxSighash,
|
|
25491
26008
|
keyDerivation: {
|
|
25492
26009
|
type: "leaf" /* LEAF */,
|
|
25493
|
-
path:
|
|
26010
|
+
path: node.id
|
|
25494
26011
|
},
|
|
25495
26012
|
publicKey: signingJob.signingPublicKey,
|
|
25496
26013
|
verifyingKey: signingResult.verifyingKey,
|
|
@@ -25509,41 +26026,35 @@ var TransferService = class extends BaseTransferService {
|
|
|
25509
26026
|
selfSignature: userSignature,
|
|
25510
26027
|
adaptorPubKey: new Uint8Array()
|
|
25511
26028
|
});
|
|
25512
|
-
if (
|
|
25513
|
-
|
|
25514
|
-
|
|
25515
|
-
|
|
25516
|
-
|
|
25517
|
-
|
|
25518
|
-
|
|
25519
|
-
|
|
25520
|
-
|
|
25521
|
-
|
|
25522
|
-
} else if (i === nodes.length) {
|
|
25523
|
-
refundSignature = signature;
|
|
25524
|
-
} else if (i === nodes.length - 1) {
|
|
25525
|
-
leafNodeId = nodeId;
|
|
25526
|
-
leafSignature = signature;
|
|
26029
|
+
if (signingJob.type === "node") {
|
|
26030
|
+
leafCpfpSignature = signature;
|
|
26031
|
+
} else if (signingJob.type === "directNode") {
|
|
26032
|
+
leafDirectSignature = signature;
|
|
26033
|
+
} else if (signingJob.type === "cpfp") {
|
|
26034
|
+
cpfpRefundSignature = signature;
|
|
26035
|
+
} else if (signingJob.type === "direct") {
|
|
26036
|
+
directRefundSignature = signature;
|
|
26037
|
+
} else if (signingJob.type === "directFromCpfp") {
|
|
26038
|
+
directFromCpfpRefundSignature = signature;
|
|
25527
26039
|
}
|
|
25528
26040
|
}
|
|
25529
|
-
if (!leafSignature || !refundSignature || !leafNodeId) {
|
|
25530
|
-
throw Error("leaf or refund signature does not exist");
|
|
25531
|
-
}
|
|
25532
26041
|
nodeSignatures.push({
|
|
25533
|
-
nodeId:
|
|
25534
|
-
nodeTxSignature:
|
|
25535
|
-
|
|
25536
|
-
|
|
25537
|
-
|
|
25538
|
-
|
|
25539
|
-
directFromCpfpRefundTxSignature: new Uint8Array()
|
|
26042
|
+
nodeId: node.id,
|
|
26043
|
+
nodeTxSignature: leafCpfpSignature || new Uint8Array(),
|
|
26044
|
+
directNodeTxSignature: leafDirectSignature || new Uint8Array(),
|
|
26045
|
+
refundTxSignature: cpfpRefundSignature || new Uint8Array(),
|
|
26046
|
+
directRefundTxSignature: directRefundSignature || new Uint8Array(),
|
|
26047
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSignature || new Uint8Array()
|
|
25540
26048
|
});
|
|
25541
|
-
const result = await sparkClient.
|
|
26049
|
+
const result = await sparkClient.finalize_node_signatures_v2({
|
|
25542
26050
|
intent: 3 /* REFRESH */,
|
|
25543
26051
|
nodeSignatures
|
|
25544
26052
|
});
|
|
25545
26053
|
return result;
|
|
25546
26054
|
}
|
|
26055
|
+
async refreshTimelockNodes(node, parentNode) {
|
|
26056
|
+
return await this.refreshTimelockNodesInternal(node, parentNode);
|
|
26057
|
+
}
|
|
25547
26058
|
async extendTimelock(node) {
|
|
25548
26059
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
25549
26060
|
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
@@ -25552,7 +26063,10 @@ var TransferService = class extends BaseTransferService {
|
|
|
25552
26063
|
txid: (0, import_utils14.hexToBytes)(getTxId(nodeTx)),
|
|
25553
26064
|
index: 0
|
|
25554
26065
|
};
|
|
25555
|
-
const {
|
|
26066
|
+
const {
|
|
26067
|
+
nextSequence: newNodeSequence,
|
|
26068
|
+
nextDirectSequence: newDirectNodeSequence
|
|
26069
|
+
} = getNextTransactionSequence(refundSequence);
|
|
25556
26070
|
const newNodeTx = new import_btc_signer2.Transaction({
|
|
25557
26071
|
version: 3,
|
|
25558
26072
|
allowUnknownOutputs: true
|
|
@@ -25565,81 +26079,122 @@ var TransferService = class extends BaseTransferService {
|
|
|
25565
26079
|
newNodeTx.addOutput({
|
|
25566
26080
|
script: originalOutput.script,
|
|
25567
26081
|
amount: originalOutput.amount
|
|
25568
|
-
// feeReducedAmount,
|
|
25569
26082
|
});
|
|
25570
26083
|
newNodeTx.addOutput(getEphemeralAnchorOutput());
|
|
25571
|
-
|
|
26084
|
+
let newDirectNodeTx;
|
|
26085
|
+
if (node.directTx.length > 0) {
|
|
26086
|
+
newDirectNodeTx = new import_btc_signer2.Transaction({
|
|
26087
|
+
version: 3,
|
|
26088
|
+
allowUnknownOutputs: true
|
|
26089
|
+
});
|
|
26090
|
+
newDirectNodeTx.addInput({
|
|
26091
|
+
...newNodeOutPoint,
|
|
26092
|
+
sequence: newDirectNodeSequence
|
|
26093
|
+
});
|
|
26094
|
+
newDirectNodeTx.addOutput({
|
|
26095
|
+
script: originalOutput.script,
|
|
26096
|
+
amount: maybeApplyFee(originalOutput.amount)
|
|
26097
|
+
});
|
|
26098
|
+
}
|
|
26099
|
+
const newCpfpRefundOutPoint = {
|
|
25572
26100
|
txid: (0, import_utils14.hexToBytes)(getTxId(newNodeTx)),
|
|
25573
26101
|
index: 0
|
|
25574
26102
|
};
|
|
26103
|
+
let newDirectRefundOutPoint;
|
|
26104
|
+
if (newDirectNodeTx) {
|
|
26105
|
+
newDirectRefundOutPoint = {
|
|
26106
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
26107
|
+
index: 0
|
|
26108
|
+
};
|
|
26109
|
+
}
|
|
25575
26110
|
const amountSats = refundTx.getOutput(0).amount;
|
|
25576
26111
|
if (amountSats === void 0) {
|
|
25577
26112
|
throw new Error("Amount not found in extendTimelock");
|
|
25578
26113
|
}
|
|
25579
|
-
const
|
|
26114
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
25580
26115
|
type: "leaf" /* LEAF */,
|
|
25581
26116
|
path: node.id
|
|
25582
26117
|
});
|
|
25583
|
-
const
|
|
25584
|
-
|
|
25585
|
-
|
|
26118
|
+
const {
|
|
26119
|
+
cpfpRefundTx: newCpfpRefundTx,
|
|
26120
|
+
directRefundTx: newDirectRefundTx,
|
|
26121
|
+
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
26122
|
+
} = createRefundTxs({
|
|
26123
|
+
sequence: INITIAL_SEQUENCE,
|
|
26124
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
26125
|
+
input: newCpfpRefundOutPoint,
|
|
26126
|
+
directInput: newDirectRefundOutPoint,
|
|
25586
26127
|
amountSats,
|
|
25587
|
-
|
|
25588
|
-
|
|
25589
|
-
|
|
25590
|
-
)
|
|
26128
|
+
receivingPubkey: signingPublicKey,
|
|
26129
|
+
network: this.config.getNetwork()
|
|
26130
|
+
});
|
|
26131
|
+
if (!newCpfpRefundTx) {
|
|
26132
|
+
throw new ValidationError(
|
|
26133
|
+
"Failed to create refund transactions in extendTimelock"
|
|
26134
|
+
);
|
|
26135
|
+
}
|
|
25591
26136
|
const nodeSighash = getSigHashFromTx(newNodeTx, 0, nodeTx.getOutput(0));
|
|
25592
|
-
const
|
|
25593
|
-
|
|
26137
|
+
const directNodeSighash = newDirectNodeTx ? getSigHashFromTx(newDirectNodeTx, 0, nodeTx.getOutput(0)) : void 0;
|
|
26138
|
+
const cpfpRefundSighash = getSigHashFromTx(
|
|
26139
|
+
newCpfpRefundTx,
|
|
25594
26140
|
0,
|
|
25595
26141
|
newNodeTx.getOutput(0)
|
|
25596
26142
|
);
|
|
26143
|
+
const directRefundSighash = newDirectNodeTx && newDirectRefundTx ? getSigHashFromTx(newDirectRefundTx, 0, newDirectNodeTx.getOutput(0)) : void 0;
|
|
26144
|
+
const directFromCpfpRefundSighash = newDirectFromCpfpRefundTx ? getSigHashFromTx(newDirectFromCpfpRefundTx, 0, newNodeTx.getOutput(0)) : void 0;
|
|
25597
26145
|
const newNodeSigningJob = {
|
|
25598
|
-
signingPublicKey
|
|
26146
|
+
signingPublicKey,
|
|
25599
26147
|
rawTx: newNodeTx.toBytes(),
|
|
25600
26148
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
25601
26149
|
};
|
|
25602
|
-
const
|
|
25603
|
-
signingPublicKey
|
|
25604
|
-
rawTx:
|
|
26150
|
+
const newDirectNodeSigningJob = newDirectNodeTx ? {
|
|
26151
|
+
signingPublicKey,
|
|
26152
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
26153
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
26154
|
+
} : void 0;
|
|
26155
|
+
const newCpfpRefundSigningJob = {
|
|
26156
|
+
signingPublicKey,
|
|
26157
|
+
rawTx: newCpfpRefundTx.toBytes(),
|
|
25605
26158
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
25606
26159
|
};
|
|
26160
|
+
const newDirectRefundSigningJob = newDirectRefundTx ? {
|
|
26161
|
+
signingPublicKey,
|
|
26162
|
+
rawTx: newDirectRefundTx.toBytes(),
|
|
26163
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
26164
|
+
} : void 0;
|
|
26165
|
+
const newDirectFromCpfpRefundSigningJob = newDirectFromCpfpRefundTx ? {
|
|
26166
|
+
signingPublicKey,
|
|
26167
|
+
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
26168
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
26169
|
+
} : void 0;
|
|
25607
26170
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
25608
26171
|
this.config.getCoordinatorAddress()
|
|
25609
26172
|
);
|
|
25610
|
-
const response = await sparkClient.
|
|
26173
|
+
const response = await sparkClient.extend_leaf_v2({
|
|
25611
26174
|
leafId: node.id,
|
|
25612
26175
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25613
26176
|
nodeTxSigningJob: getSigningJobProto(newNodeSigningJob),
|
|
25614
|
-
|
|
26177
|
+
directNodeTxSigningJob: newDirectNodeSigningJob ? getSigningJobProto(newDirectNodeSigningJob) : void 0,
|
|
26178
|
+
refundTxSigningJob: getSigningJobProto(newCpfpRefundSigningJob),
|
|
26179
|
+
directRefundTxSigningJob: newDirectRefundSigningJob ? getSigningJobProto(newDirectRefundSigningJob) : void 0,
|
|
26180
|
+
directFromCpfpRefundTxSigningJob: newDirectFromCpfpRefundSigningJob ? getSigningJobProto(newDirectFromCpfpRefundSigningJob) : void 0
|
|
25615
26181
|
});
|
|
25616
26182
|
if (!response.nodeTxSigningResult || !response.refundTxSigningResult) {
|
|
25617
26183
|
throw new Error("Signing result does not exist");
|
|
25618
26184
|
}
|
|
26185
|
+
const keyDerivation = {
|
|
26186
|
+
type: "leaf" /* LEAF */,
|
|
26187
|
+
path: node.id
|
|
26188
|
+
};
|
|
25619
26189
|
const nodeUserSig = await this.config.signer.signFrost({
|
|
25620
26190
|
message: nodeSighash,
|
|
25621
|
-
keyDerivation
|
|
25622
|
-
|
|
25623
|
-
path: node.id
|
|
25624
|
-
},
|
|
25625
|
-
publicKey: signingPubKey,
|
|
26191
|
+
keyDerivation,
|
|
26192
|
+
publicKey: signingPublicKey,
|
|
25626
26193
|
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
25627
26194
|
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
25628
26195
|
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25629
26196
|
adaptorPubKey: new Uint8Array()
|
|
25630
26197
|
});
|
|
25631
|
-
const refundUserSig = await this.config.signer.signFrost({
|
|
25632
|
-
message: refundSighash,
|
|
25633
|
-
keyDerivation: {
|
|
25634
|
-
type: "leaf" /* LEAF */,
|
|
25635
|
-
path: node.id
|
|
25636
|
-
},
|
|
25637
|
-
publicKey: signingPubKey,
|
|
25638
|
-
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
25639
|
-
selfCommitment: newRefundSigningJob.signingNonceCommitment,
|
|
25640
|
-
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25641
|
-
adaptorPubKey: new Uint8Array()
|
|
25642
|
-
});
|
|
25643
26198
|
const nodeSig = await this.config.signer.aggregateFrost({
|
|
25644
26199
|
message: nodeSighash,
|
|
25645
26200
|
statechainSignatures: response.nodeTxSigningResult.signingResult?.signatureShares,
|
|
@@ -25647,122 +26202,253 @@ var TransferService = class extends BaseTransferService {
|
|
|
25647
26202
|
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
25648
26203
|
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25649
26204
|
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
25650
|
-
publicKey:
|
|
26205
|
+
publicKey: signingPublicKey,
|
|
25651
26206
|
selfSignature: nodeUserSig,
|
|
25652
26207
|
adaptorPubKey: new Uint8Array()
|
|
25653
26208
|
});
|
|
25654
|
-
|
|
25655
|
-
|
|
26209
|
+
let directNodeSig;
|
|
26210
|
+
if (directNodeSighash && newDirectNodeSigningJob && response.directNodeTxSigningResult) {
|
|
26211
|
+
const directNodeUserSig = await this.config.signer.signFrost({
|
|
26212
|
+
message: directNodeSighash,
|
|
26213
|
+
keyDerivation,
|
|
26214
|
+
publicKey: signingPublicKey,
|
|
26215
|
+
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
26216
|
+
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
26217
|
+
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26218
|
+
adaptorPubKey: new Uint8Array()
|
|
26219
|
+
});
|
|
26220
|
+
directNodeSig = await this.config.signer.aggregateFrost({
|
|
26221
|
+
message: directNodeSighash,
|
|
26222
|
+
statechainSignatures: response.directNodeTxSigningResult.signingResult?.signatureShares,
|
|
26223
|
+
statechainPublicKeys: response.directNodeTxSigningResult.signingResult?.publicKeys,
|
|
26224
|
+
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
26225
|
+
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26226
|
+
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
26227
|
+
publicKey: signingPublicKey,
|
|
26228
|
+
selfSignature: directNodeUserSig,
|
|
26229
|
+
adaptorPubKey: new Uint8Array()
|
|
26230
|
+
});
|
|
26231
|
+
}
|
|
26232
|
+
const cpfpRefundUserSig = await this.config.signer.signFrost({
|
|
26233
|
+
message: cpfpRefundSighash,
|
|
26234
|
+
keyDerivation,
|
|
26235
|
+
publicKey: signingPublicKey,
|
|
26236
|
+
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
26237
|
+
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
26238
|
+
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26239
|
+
adaptorPubKey: new Uint8Array()
|
|
26240
|
+
});
|
|
26241
|
+
const cpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
26242
|
+
message: cpfpRefundSighash,
|
|
25656
26243
|
statechainSignatures: response.refundTxSigningResult.signingResult?.signatureShares,
|
|
25657
26244
|
statechainPublicKeys: response.refundTxSigningResult.signingResult?.publicKeys,
|
|
25658
26245
|
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
25659
26246
|
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25660
|
-
selfCommitment:
|
|
25661
|
-
publicKey:
|
|
25662
|
-
selfSignature:
|
|
26247
|
+
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
26248
|
+
publicKey: signingPublicKey,
|
|
26249
|
+
selfSignature: cpfpRefundUserSig,
|
|
25663
26250
|
adaptorPubKey: new Uint8Array()
|
|
25664
26251
|
});
|
|
25665
|
-
|
|
26252
|
+
let directRefundSig;
|
|
26253
|
+
if (directRefundSighash && newDirectRefundSigningJob && response.directRefundTxSigningResult) {
|
|
26254
|
+
const directRefundUserSig = await this.config.signer.signFrost({
|
|
26255
|
+
message: directRefundSighash,
|
|
26256
|
+
keyDerivation,
|
|
26257
|
+
publicKey: signingPublicKey,
|
|
26258
|
+
verifyingKey: response.directRefundTxSigningResult.verifyingKey,
|
|
26259
|
+
selfCommitment: newDirectRefundSigningJob.signingNonceCommitment,
|
|
26260
|
+
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26261
|
+
adaptorPubKey: new Uint8Array()
|
|
26262
|
+
});
|
|
26263
|
+
directRefundSig = await this.config.signer.aggregateFrost({
|
|
26264
|
+
message: directRefundSighash,
|
|
26265
|
+
statechainSignatures: response.directRefundTxSigningResult.signingResult?.signatureShares,
|
|
26266
|
+
statechainPublicKeys: response.directRefundTxSigningResult.signingResult?.publicKeys,
|
|
26267
|
+
verifyingKey: response.directRefundTxSigningResult.verifyingKey,
|
|
26268
|
+
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26269
|
+
selfCommitment: newDirectRefundSigningJob.signingNonceCommitment,
|
|
26270
|
+
publicKey: signingPublicKey,
|
|
26271
|
+
selfSignature: directRefundUserSig,
|
|
26272
|
+
adaptorPubKey: new Uint8Array()
|
|
26273
|
+
});
|
|
26274
|
+
}
|
|
26275
|
+
let directFromCpfpRefundSig;
|
|
26276
|
+
if (directFromCpfpRefundSighash && newDirectFromCpfpRefundSigningJob && response.directFromCpfpRefundTxSigningResult) {
|
|
26277
|
+
const directFromCpfpRefundUserSig = await this.config.signer.signFrost({
|
|
26278
|
+
message: directFromCpfpRefundSighash,
|
|
26279
|
+
keyDerivation,
|
|
26280
|
+
publicKey: signingPublicKey,
|
|
26281
|
+
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
26282
|
+
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
26283
|
+
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26284
|
+
adaptorPubKey: new Uint8Array()
|
|
26285
|
+
});
|
|
26286
|
+
directFromCpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
26287
|
+
message: directFromCpfpRefundSighash,
|
|
26288
|
+
statechainSignatures: response.directFromCpfpRefundTxSigningResult.signingResult?.signatureShares,
|
|
26289
|
+
statechainPublicKeys: response.directFromCpfpRefundTxSigningResult.signingResult?.publicKeys,
|
|
26290
|
+
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
26291
|
+
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
26292
|
+
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
26293
|
+
publicKey: signingPublicKey,
|
|
26294
|
+
selfSignature: directFromCpfpRefundUserSig,
|
|
26295
|
+
adaptorPubKey: new Uint8Array()
|
|
26296
|
+
});
|
|
26297
|
+
}
|
|
26298
|
+
return await sparkClient.finalize_node_signatures_v2({
|
|
25666
26299
|
intent: 4 /* EXTEND */,
|
|
25667
26300
|
nodeSignatures: [
|
|
25668
26301
|
{
|
|
25669
26302
|
nodeId: response.leafId,
|
|
25670
26303
|
nodeTxSignature: nodeSig,
|
|
25671
|
-
|
|
26304
|
+
directNodeTxSignature: directNodeSig,
|
|
26305
|
+
refundTxSignature: cpfpRefundSig,
|
|
26306
|
+
directRefundTxSignature: directRefundSig,
|
|
26307
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSig
|
|
25672
26308
|
}
|
|
25673
26309
|
]
|
|
25674
26310
|
});
|
|
25675
26311
|
}
|
|
25676
|
-
async
|
|
26312
|
+
async testonly_expireTimeLockNodeTx(node, parentNode) {
|
|
26313
|
+
return await this.refreshTimelockNodesInternal(node, parentNode, true);
|
|
26314
|
+
}
|
|
26315
|
+
async testonly_expireTimeLockRefundtx(node) {
|
|
25677
26316
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
25678
|
-
const
|
|
25679
|
-
const
|
|
25680
|
-
const
|
|
25681
|
-
const
|
|
26317
|
+
const directNodeTx = node.directTx.length > 0 ? getTxFromRawTxBytes(node.directTx) : void 0;
|
|
26318
|
+
const cpfpRefundTx = getTxFromRawTxBytes(node.refundTx);
|
|
26319
|
+
const currSequence = cpfpRefundTx.getInput(0).sequence || 0;
|
|
26320
|
+
const currTimelock = getCurrentTimelock(currSequence);
|
|
26321
|
+
if (currTimelock <= 100) {
|
|
26322
|
+
throw new ValidationError("Cannot expire timelock below 100", {
|
|
26323
|
+
field: "currTimelock",
|
|
26324
|
+
value: currTimelock,
|
|
26325
|
+
expected: "Timelock greater than 100"
|
|
26326
|
+
});
|
|
26327
|
+
}
|
|
26328
|
+
const nextSequence = TEST_UNILATERAL_SEQUENCE;
|
|
26329
|
+
const nextDirectSequence = TEST_UNILATERAL_SEQUENCE + DIRECT_TIMELOCK_OFFSET;
|
|
26330
|
+
const nodeOutput = nodeTx.getOutput(0);
|
|
26331
|
+
if (!nodeOutput) {
|
|
26332
|
+
throw Error("Could not get node output");
|
|
26333
|
+
}
|
|
26334
|
+
const keyDerivation = {
|
|
25682
26335
|
type: "leaf" /* LEAF */,
|
|
25683
26336
|
path: node.id
|
|
25684
|
-
}
|
|
25685
|
-
const
|
|
25686
|
-
|
|
25687
|
-
|
|
25688
|
-
|
|
25689
|
-
|
|
25690
|
-
|
|
25691
|
-
|
|
26337
|
+
};
|
|
26338
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
26339
|
+
const cpfpRefundOutPoint = {
|
|
26340
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(nodeTx)),
|
|
26341
|
+
index: 0
|
|
26342
|
+
};
|
|
26343
|
+
let directRefundOutPoint;
|
|
26344
|
+
if (directNodeTx) {
|
|
26345
|
+
directRefundOutPoint = {
|
|
26346
|
+
txid: (0, import_utils14.hexToBytes)(getTxId(directNodeTx)),
|
|
26347
|
+
index: 0
|
|
26348
|
+
};
|
|
25692
26349
|
}
|
|
25693
|
-
|
|
25694
|
-
|
|
25695
|
-
|
|
26350
|
+
const {
|
|
26351
|
+
cpfpRefundTx: newCpfpRefundTx,
|
|
26352
|
+
directRefundTx: newDirectRefundTx,
|
|
26353
|
+
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
26354
|
+
} = createRefundTxs({
|
|
26355
|
+
sequence: nextSequence,
|
|
26356
|
+
directSequence: nextDirectSequence,
|
|
26357
|
+
input: cpfpRefundOutPoint,
|
|
26358
|
+
directInput: directRefundOutPoint,
|
|
26359
|
+
amountSats: nodeOutput.amount,
|
|
26360
|
+
receivingPubkey: signingPublicKey,
|
|
26361
|
+
network: this.config.getNetwork()
|
|
25696
26362
|
});
|
|
25697
|
-
|
|
25698
|
-
|
|
25699
|
-
|
|
25700
|
-
|
|
25701
|
-
|
|
26363
|
+
const signingJobs = [];
|
|
26364
|
+
signingJobs.push({
|
|
26365
|
+
signingPublicKey,
|
|
26366
|
+
rawTx: newCpfpRefundTx.toBytes(),
|
|
26367
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
26368
|
+
type: "cpfp",
|
|
26369
|
+
parentTxOut: nodeOutput
|
|
26370
|
+
});
|
|
26371
|
+
const directNodeTxOut = directNodeTx?.getOutput(0);
|
|
26372
|
+
if (newDirectRefundTx && directNodeTxOut) {
|
|
26373
|
+
signingJobs.push({
|
|
26374
|
+
signingPublicKey,
|
|
26375
|
+
rawTx: newDirectRefundTx.toBytes(),
|
|
26376
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
26377
|
+
type: "direct",
|
|
26378
|
+
parentTxOut: directNodeTxOut
|
|
26379
|
+
});
|
|
25702
26380
|
}
|
|
25703
|
-
|
|
25704
|
-
|
|
25705
|
-
|
|
26381
|
+
if (newDirectFromCpfpRefundTx) {
|
|
26382
|
+
signingJobs.push({
|
|
26383
|
+
signingPublicKey,
|
|
26384
|
+
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
26385
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
26386
|
+
type: "directFromCpfp",
|
|
26387
|
+
parentTxOut: nodeOutput
|
|
26388
|
+
});
|
|
25706
26389
|
}
|
|
25707
|
-
newRefundTx.addInput({
|
|
25708
|
-
...refundTxInput,
|
|
25709
|
-
sequence: nextSequence
|
|
25710
|
-
});
|
|
25711
|
-
const refundSigningJob = {
|
|
25712
|
-
signingPublicKey: signingPubKey,
|
|
25713
|
-
rawTx: newRefundTx.toBytes(),
|
|
25714
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
25715
|
-
};
|
|
25716
26390
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
25717
26391
|
this.config.getCoordinatorAddress()
|
|
25718
26392
|
);
|
|
25719
|
-
const response = await sparkClient.
|
|
26393
|
+
const response = await sparkClient.refresh_timelock_v2({
|
|
25720
26394
|
leafId: node.id,
|
|
25721
26395
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25722
|
-
signingJobs:
|
|
26396
|
+
signingJobs: signingJobs.map(getSigningJobProto)
|
|
25723
26397
|
});
|
|
25724
|
-
if (response.signingResults.length !==
|
|
26398
|
+
if (response.signingResults.length !== signingJobs.length) {
|
|
25725
26399
|
throw Error(
|
|
25726
|
-
`Expected
|
|
26400
|
+
`Expected ${signingJobs.length} signing results, got ${response.signingResults.length}`
|
|
25727
26401
|
);
|
|
25728
26402
|
}
|
|
25729
|
-
|
|
25730
|
-
|
|
25731
|
-
|
|
26403
|
+
let cpfpRefundSignature;
|
|
26404
|
+
let directRefundSignature;
|
|
26405
|
+
let directFromCpfpRefundSignature;
|
|
26406
|
+
for (const [i, signingJob] of signingJobs.entries()) {
|
|
26407
|
+
const signingResult = response.signingResults[i];
|
|
26408
|
+
if (!signingResult) {
|
|
26409
|
+
throw Error("Signing result does not exist");
|
|
26410
|
+
}
|
|
26411
|
+
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
26412
|
+
const txOut = signingJob.parentTxOut;
|
|
26413
|
+
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
26414
|
+
const userSignature = await this.config.signer.signFrost({
|
|
26415
|
+
message: rawTxSighash,
|
|
26416
|
+
keyDerivation,
|
|
26417
|
+
publicKey: signingPublicKey,
|
|
26418
|
+
verifyingKey: signingResult.verifyingKey,
|
|
26419
|
+
selfCommitment: signingJob.signingNonceCommitment,
|
|
26420
|
+
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
26421
|
+
adaptorPubKey: new Uint8Array()
|
|
26422
|
+
});
|
|
26423
|
+
const signature = await this.config.signer.aggregateFrost({
|
|
26424
|
+
message: rawTxSighash,
|
|
26425
|
+
statechainSignatures: signingResult.signingResult?.signatureShares,
|
|
26426
|
+
statechainPublicKeys: signingResult.signingResult?.publicKeys,
|
|
26427
|
+
verifyingKey: signingResult.verifyingKey,
|
|
26428
|
+
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
26429
|
+
selfCommitment: signingJob.signingNonceCommitment,
|
|
26430
|
+
publicKey: signingPublicKey,
|
|
26431
|
+
selfSignature: userSignature,
|
|
26432
|
+
adaptorPubKey: new Uint8Array()
|
|
26433
|
+
});
|
|
26434
|
+
if (signingJob.type === "cpfp") {
|
|
26435
|
+
cpfpRefundSignature = signature;
|
|
26436
|
+
} else if (signingJob.type === "direct") {
|
|
26437
|
+
directRefundSignature = signature;
|
|
26438
|
+
} else if (signingJob.type === "directFromCpfp") {
|
|
26439
|
+
directFromCpfpRefundSignature = signature;
|
|
26440
|
+
}
|
|
25732
26441
|
}
|
|
25733
|
-
const
|
|
25734
|
-
const txOut = nodeTx.getOutput(0);
|
|
25735
|
-
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
25736
|
-
const userSignature = await this.config.signer.signFrost({
|
|
25737
|
-
message: rawTxSighash,
|
|
25738
|
-
keyDerivation: {
|
|
25739
|
-
type: "leaf" /* LEAF */,
|
|
25740
|
-
path: node.id
|
|
25741
|
-
},
|
|
25742
|
-
publicKey: signingPubKey,
|
|
25743
|
-
verifyingKey: signingResult.verifyingKey,
|
|
25744
|
-
selfCommitment: refundSigningJob.signingNonceCommitment,
|
|
25745
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
25746
|
-
adaptorPubKey: new Uint8Array()
|
|
25747
|
-
});
|
|
25748
|
-
const signature = await this.config.signer.aggregateFrost({
|
|
25749
|
-
message: rawTxSighash,
|
|
25750
|
-
statechainSignatures: signingResult.signingResult?.signatureShares,
|
|
25751
|
-
statechainPublicKeys: signingResult.signingResult?.publicKeys,
|
|
25752
|
-
verifyingKey: signingResult.verifyingKey,
|
|
25753
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
25754
|
-
selfCommitment: refundSigningJob.signingNonceCommitment,
|
|
25755
|
-
publicKey: signingPubKey,
|
|
25756
|
-
selfSignature: userSignature,
|
|
25757
|
-
adaptorPubKey: new Uint8Array()
|
|
25758
|
-
});
|
|
25759
|
-
const result = await sparkClient.finalize_node_signatures({
|
|
26442
|
+
const result = await sparkClient.finalize_node_signatures_v2({
|
|
25760
26443
|
intent: 3 /* REFRESH */,
|
|
25761
26444
|
nodeSignatures: [
|
|
25762
26445
|
{
|
|
25763
26446
|
nodeId: node.id,
|
|
25764
26447
|
nodeTxSignature: new Uint8Array(),
|
|
25765
|
-
|
|
26448
|
+
directNodeTxSignature: new Uint8Array(),
|
|
26449
|
+
refundTxSignature: cpfpRefundSignature,
|
|
26450
|
+
directRefundTxSignature: directRefundSignature,
|
|
26451
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSignature
|
|
25766
26452
|
}
|
|
25767
26453
|
]
|
|
25768
26454
|
});
|
|
@@ -25781,7 +26467,12 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25781
26467
|
connectorOutputs,
|
|
25782
26468
|
receiverPubKey
|
|
25783
26469
|
}) {
|
|
25784
|
-
const {
|
|
26470
|
+
const {
|
|
26471
|
+
transfer,
|
|
26472
|
+
signaturesMap,
|
|
26473
|
+
directSignaturesMap,
|
|
26474
|
+
directFromCpfpSignaturesMap
|
|
26475
|
+
} = await this.signCoopExitRefunds(
|
|
25785
26476
|
leaves,
|
|
25786
26477
|
exitTxId,
|
|
25787
26478
|
connectorOutputs,
|
|
@@ -25790,34 +26481,81 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25790
26481
|
const transferTweak = await this.deliverTransferPackage(
|
|
25791
26482
|
transfer,
|
|
25792
26483
|
leaves,
|
|
25793
|
-
signaturesMap
|
|
26484
|
+
signaturesMap,
|
|
26485
|
+
directSignaturesMap,
|
|
26486
|
+
directFromCpfpSignaturesMap
|
|
25794
26487
|
);
|
|
25795
|
-
return {
|
|
25796
|
-
|
|
25797
|
-
|
|
25798
|
-
|
|
25799
|
-
|
|
25800
|
-
|
|
25801
|
-
|
|
25802
|
-
|
|
26488
|
+
return {
|
|
26489
|
+
transfer: transferTweak,
|
|
26490
|
+
signaturesMap,
|
|
26491
|
+
directSignaturesMap,
|
|
26492
|
+
directFromCpfpSignaturesMap
|
|
26493
|
+
};
|
|
26494
|
+
}
|
|
26495
|
+
createConnectorRefundTransactions(sequence, directSequence, cpfpNodeOutPoint, directNodeOutPoint, connectorOutput, amountSats, receiverPubKey) {
|
|
26496
|
+
const cpfpRefundTx = new import_btc_signer3.Transaction();
|
|
26497
|
+
if (!cpfpNodeOutPoint.txid || cpfpNodeOutPoint.index === void 0) {
|
|
26498
|
+
throw new ValidationError("Invalid CPFP node outpoint", {
|
|
26499
|
+
field: "cpfpNodeOutPoint",
|
|
26500
|
+
value: { txid: cpfpNodeOutPoint.txid, index: cpfpNodeOutPoint.index },
|
|
25803
26501
|
expected: "Both txid and index must be defined"
|
|
25804
26502
|
});
|
|
25805
26503
|
}
|
|
25806
|
-
|
|
25807
|
-
txid:
|
|
25808
|
-
index:
|
|
26504
|
+
cpfpRefundTx.addInput({
|
|
26505
|
+
txid: cpfpNodeOutPoint.txid,
|
|
26506
|
+
index: cpfpNodeOutPoint.index,
|
|
25809
26507
|
sequence
|
|
25810
26508
|
});
|
|
25811
|
-
|
|
26509
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
25812
26510
|
const receiverScript = getP2TRScriptFromPublicKey(
|
|
25813
26511
|
receiverPubKey,
|
|
25814
26512
|
this.config.getNetwork()
|
|
25815
26513
|
);
|
|
25816
|
-
|
|
26514
|
+
cpfpRefundTx.addOutput({
|
|
25817
26515
|
script: receiverScript,
|
|
25818
26516
|
amount: amountSats
|
|
25819
26517
|
});
|
|
25820
|
-
|
|
26518
|
+
let directRefundTx;
|
|
26519
|
+
let directFromCpfpRefundTx;
|
|
26520
|
+
if (directNodeOutPoint) {
|
|
26521
|
+
if (!directNodeOutPoint.txid || directNodeOutPoint.index === void 0) {
|
|
26522
|
+
throw new ValidationError("Invalid direct node outpoint", {
|
|
26523
|
+
field: "directNodeOutPoint",
|
|
26524
|
+
value: {
|
|
26525
|
+
txid: directNodeOutPoint.txid,
|
|
26526
|
+
index: directNodeOutPoint.index
|
|
26527
|
+
},
|
|
26528
|
+
expected: "Both txid and index must be defined"
|
|
26529
|
+
});
|
|
26530
|
+
}
|
|
26531
|
+
directRefundTx = new import_btc_signer3.Transaction();
|
|
26532
|
+
directRefundTx.addInput({
|
|
26533
|
+
txid: directNodeOutPoint.txid,
|
|
26534
|
+
index: directNodeOutPoint.index,
|
|
26535
|
+
sequence: directSequence
|
|
26536
|
+
});
|
|
26537
|
+
directRefundTx.addInput(connectorOutput);
|
|
26538
|
+
directRefundTx.addOutput({
|
|
26539
|
+
script: receiverScript,
|
|
26540
|
+
amount: maybeApplyFee(amountSats)
|
|
26541
|
+
});
|
|
26542
|
+
directFromCpfpRefundTx = new import_btc_signer3.Transaction();
|
|
26543
|
+
directFromCpfpRefundTx.addInput({
|
|
26544
|
+
txid: cpfpNodeOutPoint.txid,
|
|
26545
|
+
index: cpfpNodeOutPoint.index,
|
|
26546
|
+
sequence: directSequence
|
|
26547
|
+
});
|
|
26548
|
+
directFromCpfpRefundTx.addInput(connectorOutput);
|
|
26549
|
+
directFromCpfpRefundTx.addOutput({
|
|
26550
|
+
script: receiverScript,
|
|
26551
|
+
amount: maybeApplyFee(amountSats)
|
|
26552
|
+
});
|
|
26553
|
+
}
|
|
26554
|
+
return {
|
|
26555
|
+
cpfpRefundTx,
|
|
26556
|
+
directRefundTx,
|
|
26557
|
+
directFromCpfpRefundTx
|
|
26558
|
+
};
|
|
25821
26559
|
}
|
|
25822
26560
|
async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey) {
|
|
25823
26561
|
if (leaves.length !== connectorOutputs.length) {
|
|
@@ -25853,39 +26591,67 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25853
26591
|
});
|
|
25854
26592
|
}
|
|
25855
26593
|
const currentRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
25856
|
-
const
|
|
25857
|
-
|
|
25858
|
-
|
|
25859
|
-
|
|
26594
|
+
const sequence = currentRefundTx.getInput(0).sequence;
|
|
26595
|
+
if (!sequence) {
|
|
26596
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
26597
|
+
field: "sequence",
|
|
26598
|
+
value: currentRefundTx.getInput(0),
|
|
26599
|
+
expected: "Non-null sequence"
|
|
26600
|
+
});
|
|
26601
|
+
}
|
|
26602
|
+
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
26603
|
+
let currentDirectRefundTx;
|
|
26604
|
+
if (leaf.leaf.directRefundTx.length > 0) {
|
|
26605
|
+
currentDirectRefundTx = getTxFromRawTxBytes(leaf.leaf.directRefundTx);
|
|
26606
|
+
}
|
|
26607
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = this.createConnectorRefundTransactions(
|
|
25860
26608
|
nextSequence,
|
|
26609
|
+
nextDirectSequence,
|
|
25861
26610
|
currentRefundTx.getInput(0),
|
|
26611
|
+
currentDirectRefundTx?.getInput(0),
|
|
25862
26612
|
connectorOutput,
|
|
25863
26613
|
BigInt(leaf.leaf.value),
|
|
25864
26614
|
receiverPubKey
|
|
25865
26615
|
);
|
|
25866
26616
|
const signingNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26617
|
+
const directSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26618
|
+
const directFromCpfpSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26619
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(leaf.keyDerivation);
|
|
25867
26620
|
const signingJob = {
|
|
25868
26621
|
leafId: leaf.leaf.id,
|
|
25869
26622
|
refundTxSigningJob: {
|
|
25870
26623
|
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
25871
26624
|
leaf.keyDerivation
|
|
25872
26625
|
),
|
|
25873
|
-
rawTx:
|
|
26626
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
25874
26627
|
signingNonceCommitment: signingNonceCommitment.commitment
|
|
25875
26628
|
},
|
|
25876
|
-
|
|
25877
|
-
|
|
25878
|
-
|
|
26629
|
+
directRefundTxSigningJob: directRefundTx ? {
|
|
26630
|
+
signingPublicKey,
|
|
26631
|
+
rawTx: directRefundTx.toBytes(),
|
|
26632
|
+
signingNonceCommitment: directSigningNonceCommitment.commitment
|
|
26633
|
+
} : void 0,
|
|
26634
|
+
directFromCpfpRefundTxSigningJob: directFromCpfpRefundTx ? {
|
|
26635
|
+
signingPublicKey,
|
|
26636
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
26637
|
+
signingNonceCommitment: directFromCpfpSigningNonceCommitment.commitment
|
|
26638
|
+
} : void 0
|
|
25879
26639
|
};
|
|
25880
26640
|
signingJobs.push(signingJob);
|
|
25881
26641
|
const tx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
26642
|
+
const directTx = leaf.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directTx) : void 0;
|
|
25882
26643
|
leafDataMap.set(leaf.leaf.id, {
|
|
25883
26644
|
keyDerivation: leaf.keyDerivation,
|
|
25884
|
-
|
|
26645
|
+
receivingPubkey: receiverPubKey,
|
|
25885
26646
|
signingNonceCommitment,
|
|
26647
|
+
directSigningNonceCommitment,
|
|
25886
26648
|
tx,
|
|
25887
|
-
|
|
25888
|
-
|
|
26649
|
+
directTx,
|
|
26650
|
+
refundTx: cpfpRefundTx,
|
|
26651
|
+
directRefundTx,
|
|
26652
|
+
directFromCpfpRefundTx,
|
|
26653
|
+
directFromCpfpRefundSigningNonceCommitment: directFromCpfpSigningNonceCommitment,
|
|
26654
|
+
vout: leaf.leaf.vout
|
|
25889
26655
|
});
|
|
25890
26656
|
}
|
|
25891
26657
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
@@ -25893,7 +26659,7 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25893
26659
|
);
|
|
25894
26660
|
let response;
|
|
25895
26661
|
try {
|
|
25896
|
-
response = await sparkClient.
|
|
26662
|
+
response = await sparkClient.cooperative_exit_v2({
|
|
25897
26663
|
transfer: {
|
|
25898
26664
|
transferId: (0, import_uuidv73.uuidv7)(),
|
|
25899
26665
|
leavesToSend: signingJobs,
|
|
@@ -25927,10 +26693,25 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
25927
26693
|
response.signingResults
|
|
25928
26694
|
);
|
|
25929
26695
|
const signaturesMap = /* @__PURE__ */ new Map();
|
|
26696
|
+
const directSignaturesMap = /* @__PURE__ */ new Map();
|
|
26697
|
+
const directFromCpfpSignaturesMap = /* @__PURE__ */ new Map();
|
|
25930
26698
|
for (const signature of signatures) {
|
|
25931
26699
|
signaturesMap.set(signature.nodeId, signature.refundTxSignature);
|
|
26700
|
+
directSignaturesMap.set(
|
|
26701
|
+
signature.nodeId,
|
|
26702
|
+
signature.directRefundTxSignature
|
|
26703
|
+
);
|
|
26704
|
+
directFromCpfpSignaturesMap.set(
|
|
26705
|
+
signature.nodeId,
|
|
26706
|
+
signature.directFromCpfpRefundTxSignature
|
|
26707
|
+
);
|
|
25932
26708
|
}
|
|
25933
|
-
return {
|
|
26709
|
+
return {
|
|
26710
|
+
transfer: response.transfer,
|
|
26711
|
+
signaturesMap,
|
|
26712
|
+
directSignaturesMap,
|
|
26713
|
+
directFromCpfpSignaturesMap
|
|
26714
|
+
};
|
|
25934
26715
|
}
|
|
25935
26716
|
};
|
|
25936
26717
|
|
|
@@ -25939,10 +26720,8 @@ init_buffer();
|
|
|
25939
26720
|
var import_secp256k110 = require("@noble/curves/secp256k1");
|
|
25940
26721
|
var import_sha29 = require("@noble/hashes/sha2");
|
|
25941
26722
|
var import_utils15 = require("@noble/hashes/utils");
|
|
25942
|
-
var btc5 = __toESM(require("@scure/btc-signer"), 1);
|
|
25943
26723
|
var import_btc_signer4 = require("@scure/btc-signer");
|
|
25944
26724
|
var import_utils16 = require("@scure/btc-signer/utils");
|
|
25945
|
-
var INITIAL_TIME_LOCK2 = 2e3;
|
|
25946
26725
|
var DepositService = class {
|
|
25947
26726
|
config;
|
|
25948
26727
|
connectionManager;
|
|
@@ -26060,7 +26839,6 @@ var DepositService = class {
|
|
|
26060
26839
|
depositTx,
|
|
26061
26840
|
vout
|
|
26062
26841
|
}) {
|
|
26063
|
-
const rootTx = new import_btc_signer4.Transaction({ version: 3 });
|
|
26064
26842
|
const output = depositTx.getOutput(vout);
|
|
26065
26843
|
if (!output) {
|
|
26066
26844
|
throw new ValidationError("Invalid deposit transaction output", {
|
|
@@ -26078,39 +26856,345 @@ var DepositService = class {
|
|
|
26078
26856
|
expected: "Output with script and amount"
|
|
26079
26857
|
});
|
|
26080
26858
|
}
|
|
26081
|
-
|
|
26082
|
-
|
|
26083
|
-
txid: getTxId(depositTx),
|
|
26859
|
+
const depositOutPoint = {
|
|
26860
|
+
txid: (0, import_utils15.hexToBytes)(getTxId(depositTx)),
|
|
26084
26861
|
index: vout
|
|
26085
|
-
}
|
|
26086
|
-
|
|
26862
|
+
};
|
|
26863
|
+
const depositTxOut = {
|
|
26087
26864
|
script,
|
|
26088
|
-
amount
|
|
26865
|
+
amount
|
|
26866
|
+
};
|
|
26867
|
+
const [cpfpRootTx, directRootTx] = createRootTx(
|
|
26868
|
+
depositOutPoint,
|
|
26869
|
+
depositTxOut
|
|
26870
|
+
);
|
|
26871
|
+
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26872
|
+
const directRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26873
|
+
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
26874
|
+
const directRootTxSighash = getSigHashFromTx(directRootTx, 0, output);
|
|
26875
|
+
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
26876
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
26877
|
+
sequence: INITIAL_SEQUENCE,
|
|
26878
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
26879
|
+
input: { txid: (0, import_utils15.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
26880
|
+
directInput: { txid: (0, import_utils15.hexToBytes)(getTxId(directRootTx)), index: 0 },
|
|
26881
|
+
amountSats: amount,
|
|
26882
|
+
receivingPubkey: signingPubKey,
|
|
26883
|
+
network: this.config.getNetwork()
|
|
26089
26884
|
});
|
|
26090
|
-
|
|
26091
|
-
const
|
|
26092
|
-
const
|
|
26093
|
-
const
|
|
26094
|
-
|
|
26095
|
-
|
|
26096
|
-
|
|
26097
|
-
|
|
26098
|
-
|
|
26885
|
+
const cpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26886
|
+
const directRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26887
|
+
const directFromCpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
26888
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
26889
|
+
cpfpRefundTx,
|
|
26890
|
+
0,
|
|
26891
|
+
cpfpRootTx.getOutput(0)
|
|
26892
|
+
);
|
|
26893
|
+
if (!directRefundTx || !directFromCpfpRefundTx) {
|
|
26894
|
+
throw new ValidationError(
|
|
26895
|
+
"Expected direct refund transactions for tree creation",
|
|
26896
|
+
{
|
|
26897
|
+
field: "directRefundTx",
|
|
26898
|
+
value: directRefundTx
|
|
26899
|
+
}
|
|
26900
|
+
);
|
|
26901
|
+
}
|
|
26902
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
26903
|
+
directRefundTx,
|
|
26904
|
+
0,
|
|
26905
|
+
directRootTx.getOutput(0)
|
|
26906
|
+
);
|
|
26907
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
26908
|
+
directFromCpfpRefundTx,
|
|
26909
|
+
0,
|
|
26910
|
+
cpfpRootTx.getOutput(0)
|
|
26911
|
+
);
|
|
26912
|
+
const sparkClient = await this.connectionManager.createSparkClient(
|
|
26913
|
+
this.config.getCoordinatorAddress()
|
|
26914
|
+
);
|
|
26915
|
+
let treeResp;
|
|
26916
|
+
try {
|
|
26917
|
+
treeResp = await sparkClient.start_deposit_tree_creation({
|
|
26918
|
+
identityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
26919
|
+
onChainUtxo: {
|
|
26920
|
+
vout,
|
|
26921
|
+
rawTx: depositTx.toBytes(true),
|
|
26922
|
+
network: this.config.getNetworkProto()
|
|
26923
|
+
},
|
|
26924
|
+
rootTxSigningJob: {
|
|
26925
|
+
rawTx: cpfpRootTx.toBytes(),
|
|
26926
|
+
signingPublicKey: signingPubKey,
|
|
26927
|
+
signingNonceCommitment: cpfpRootNonceCommitment.commitment
|
|
26928
|
+
},
|
|
26929
|
+
refundTxSigningJob: {
|
|
26930
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
26931
|
+
signingPublicKey: signingPubKey,
|
|
26932
|
+
signingNonceCommitment: cpfpRefundNonceCommitment.commitment
|
|
26933
|
+
},
|
|
26934
|
+
directRootTxSigningJob: {
|
|
26935
|
+
rawTx: directRootTx.toBytes(),
|
|
26936
|
+
signingPublicKey: signingPubKey,
|
|
26937
|
+
signingNonceCommitment: directRootNonceCommitment.commitment
|
|
26938
|
+
},
|
|
26939
|
+
directRefundTxSigningJob: {
|
|
26940
|
+
rawTx: directRefundTx.toBytes(),
|
|
26941
|
+
signingPublicKey: signingPubKey,
|
|
26942
|
+
signingNonceCommitment: directRefundNonceCommitment.commitment
|
|
26943
|
+
},
|
|
26944
|
+
directFromCpfpRefundTxSigningJob: {
|
|
26945
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
26946
|
+
signingPublicKey: signingPubKey,
|
|
26947
|
+
signingNonceCommitment: directFromCpfpRefundNonceCommitment.commitment
|
|
26948
|
+
}
|
|
26949
|
+
});
|
|
26950
|
+
} catch (error) {
|
|
26951
|
+
throw new NetworkError(
|
|
26952
|
+
"Failed to start deposit tree creation",
|
|
26953
|
+
{
|
|
26954
|
+
operation: "start_deposit_tree_creation",
|
|
26955
|
+
errorCount: 1,
|
|
26956
|
+
errors: error instanceof Error ? error.message : String(error)
|
|
26957
|
+
},
|
|
26958
|
+
error
|
|
26959
|
+
);
|
|
26960
|
+
}
|
|
26961
|
+
if (!treeResp.rootNodeSignatureShares?.verifyingKey) {
|
|
26962
|
+
throw new ValidationError("No verifying key found in tree response", {
|
|
26963
|
+
field: "verifyingKey",
|
|
26964
|
+
value: treeResp.rootNodeSignatureShares,
|
|
26965
|
+
expected: "Non-null verifying key"
|
|
26966
|
+
});
|
|
26967
|
+
}
|
|
26968
|
+
if (!treeResp.rootNodeSignatureShares.nodeTxSigningResult?.signingNonceCommitments) {
|
|
26969
|
+
throw new ValidationError(
|
|
26970
|
+
"No signing nonce commitments found in tree response",
|
|
26971
|
+
{
|
|
26972
|
+
field: "nodeTxSigningResult.signingNonceCommitments",
|
|
26973
|
+
value: treeResp.rootNodeSignatureShares.nodeTxSigningResult,
|
|
26974
|
+
expected: "Non-null signing nonce commitments"
|
|
26975
|
+
}
|
|
26976
|
+
);
|
|
26977
|
+
}
|
|
26978
|
+
if (!treeResp.rootNodeSignatureShares.refundTxSigningResult?.signingNonceCommitments) {
|
|
26979
|
+
throw new ValidationError(
|
|
26980
|
+
"No signing nonce commitments found in tree response",
|
|
26981
|
+
{
|
|
26982
|
+
field: "refundTxSigningResult.signingNonceCommitments"
|
|
26983
|
+
}
|
|
26984
|
+
);
|
|
26985
|
+
}
|
|
26986
|
+
if (!treeResp.rootNodeSignatureShares.directNodeTxSigningResult?.signingNonceCommitments) {
|
|
26987
|
+
throw new ValidationError(
|
|
26988
|
+
"No direct node signing nonce commitments found in tree response",
|
|
26989
|
+
{
|
|
26990
|
+
field: "directNodeTxSigningResult.signingNonceCommitments"
|
|
26991
|
+
}
|
|
26992
|
+
);
|
|
26993
|
+
}
|
|
26994
|
+
if (!treeResp.rootNodeSignatureShares.directRefundTxSigningResult?.signingNonceCommitments) {
|
|
26995
|
+
throw new ValidationError(
|
|
26996
|
+
"No direct refund signing nonce commitments found in tree response",
|
|
26997
|
+
{
|
|
26998
|
+
field: "directRefundTxSigningResult.signingNonceCommitments"
|
|
26999
|
+
}
|
|
27000
|
+
);
|
|
27001
|
+
}
|
|
27002
|
+
if (!treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult?.signingNonceCommitments) {
|
|
27003
|
+
throw new ValidationError(
|
|
27004
|
+
"No direct from CPFP refund signing nonce commitments found in tree response",
|
|
27005
|
+
{
|
|
27006
|
+
field: "directFromCpfpRefundTxSigningResult.signingNonceCommitments"
|
|
27007
|
+
}
|
|
27008
|
+
);
|
|
27009
|
+
}
|
|
27010
|
+
if (!(0, import_utils16.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
27011
|
+
throw new ValidationError("Verifying key mismatch", {
|
|
27012
|
+
field: "verifyingKey",
|
|
27013
|
+
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27014
|
+
expected: verifyingKey
|
|
27015
|
+
});
|
|
27016
|
+
}
|
|
27017
|
+
const cpfpRootSignature = await this.config.signer.signFrost({
|
|
27018
|
+
message: cpfpRootTxSighash,
|
|
27019
|
+
publicKey: signingPubKey,
|
|
27020
|
+
keyDerivation,
|
|
27021
|
+
verifyingKey,
|
|
27022
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
27023
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
27024
|
+
adaptorPubKey: new Uint8Array()
|
|
26099
27025
|
});
|
|
27026
|
+
const directRootSignature = await this.config.signer.signFrost({
|
|
27027
|
+
message: directRootTxSighash,
|
|
27028
|
+
publicKey: signingPubKey,
|
|
27029
|
+
keyDerivation,
|
|
27030
|
+
verifyingKey,
|
|
27031
|
+
selfCommitment: directRootNonceCommitment,
|
|
27032
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signingNonceCommitments,
|
|
27033
|
+
adaptorPubKey: new Uint8Array()
|
|
27034
|
+
});
|
|
27035
|
+
const cpfpRefundSignature = await this.config.signer.signFrost({
|
|
27036
|
+
message: cpfpRefundTxSighash,
|
|
27037
|
+
publicKey: signingPubKey,
|
|
27038
|
+
keyDerivation,
|
|
27039
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27040
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
27041
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
27042
|
+
adaptorPubKey: new Uint8Array()
|
|
27043
|
+
});
|
|
27044
|
+
const directRefundSignature = await this.config.signer.signFrost({
|
|
27045
|
+
message: directRefundTxSighash,
|
|
27046
|
+
publicKey: signingPubKey,
|
|
27047
|
+
keyDerivation,
|
|
27048
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27049
|
+
selfCommitment: directRefundNonceCommitment,
|
|
27050
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signingNonceCommitments,
|
|
27051
|
+
adaptorPubKey: new Uint8Array()
|
|
27052
|
+
});
|
|
27053
|
+
const directFromCpfpRefundSignature = await this.config.signer.signFrost({
|
|
27054
|
+
message: directFromCpfpRefundTxSighash,
|
|
27055
|
+
publicKey: signingPubKey,
|
|
27056
|
+
keyDerivation,
|
|
27057
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27058
|
+
selfCommitment: directFromCpfpRefundNonceCommitment,
|
|
27059
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signingNonceCommitments,
|
|
27060
|
+
adaptorPubKey: new Uint8Array()
|
|
27061
|
+
});
|
|
27062
|
+
const cpfpRootAggregate = await this.config.signer.aggregateFrost({
|
|
27063
|
+
message: cpfpRootTxSighash,
|
|
27064
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signatureShares,
|
|
27065
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.nodeTxSigningResult.publicKeys,
|
|
27066
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27067
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
27068
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
27069
|
+
publicKey: signingPubKey,
|
|
27070
|
+
selfSignature: cpfpRootSignature,
|
|
27071
|
+
adaptorPubKey: new Uint8Array()
|
|
27072
|
+
});
|
|
27073
|
+
const directRootAggregate = await this.config.signer.aggregateFrost({
|
|
27074
|
+
message: directRootTxSighash,
|
|
27075
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signatureShares,
|
|
27076
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.publicKeys,
|
|
27077
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27078
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signingNonceCommitments,
|
|
27079
|
+
selfCommitment: directRootNonceCommitment,
|
|
27080
|
+
publicKey: signingPubKey,
|
|
27081
|
+
selfSignature: directRootSignature,
|
|
27082
|
+
adaptorPubKey: new Uint8Array()
|
|
27083
|
+
});
|
|
27084
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
27085
|
+
message: cpfpRefundTxSighash,
|
|
27086
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.refundTxSigningResult.signatureShares,
|
|
27087
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.refundTxSigningResult.publicKeys,
|
|
27088
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27089
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
27090
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
27091
|
+
publicKey: signingPubKey,
|
|
27092
|
+
selfSignature: cpfpRefundSignature,
|
|
27093
|
+
adaptorPubKey: new Uint8Array()
|
|
27094
|
+
});
|
|
27095
|
+
const directRefundAggregate = await this.config.signer.aggregateFrost({
|
|
27096
|
+
message: directRefundTxSighash,
|
|
27097
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signatureShares,
|
|
27098
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.publicKeys,
|
|
27099
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27100
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signingNonceCommitments,
|
|
27101
|
+
selfCommitment: directRefundNonceCommitment,
|
|
27102
|
+
publicKey: signingPubKey,
|
|
27103
|
+
selfSignature: directRefundSignature,
|
|
27104
|
+
adaptorPubKey: new Uint8Array()
|
|
27105
|
+
});
|
|
27106
|
+
const directFromCpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
27107
|
+
message: directFromCpfpRefundTxSighash,
|
|
27108
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signatureShares,
|
|
27109
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.publicKeys,
|
|
27110
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27111
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signingNonceCommitments,
|
|
27112
|
+
selfCommitment: directFromCpfpRefundNonceCommitment,
|
|
27113
|
+
publicKey: signingPubKey,
|
|
27114
|
+
selfSignature: directFromCpfpRefundSignature,
|
|
27115
|
+
adaptorPubKey: new Uint8Array()
|
|
27116
|
+
});
|
|
27117
|
+
let finalizeResp;
|
|
27118
|
+
try {
|
|
27119
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
27120
|
+
intent: 0 /* CREATION */,
|
|
27121
|
+
nodeSignatures: [
|
|
27122
|
+
{
|
|
27123
|
+
nodeId: treeResp.rootNodeSignatureShares.nodeId,
|
|
27124
|
+
nodeTxSignature: cpfpRootAggregate,
|
|
27125
|
+
refundTxSignature: cpfpRefundAggregate,
|
|
27126
|
+
directNodeTxSignature: directRootAggregate,
|
|
27127
|
+
directRefundTxSignature: directRefundAggregate,
|
|
27128
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundAggregate
|
|
27129
|
+
}
|
|
27130
|
+
]
|
|
27131
|
+
});
|
|
27132
|
+
} catch (error) {
|
|
27133
|
+
throw new NetworkError(
|
|
27134
|
+
"Failed to finalize node signatures",
|
|
27135
|
+
{
|
|
27136
|
+
operation: "finalize_node_signatures",
|
|
27137
|
+
errorCount: 1,
|
|
27138
|
+
errors: error instanceof Error ? error.message : String(error)
|
|
27139
|
+
},
|
|
27140
|
+
error
|
|
27141
|
+
);
|
|
27142
|
+
}
|
|
27143
|
+
return finalizeResp;
|
|
27144
|
+
}
|
|
27145
|
+
/**
|
|
27146
|
+
* @deprecated
|
|
27147
|
+
* Use createTreeRoot instead.
|
|
27148
|
+
* This is currently only used to test backwards compatibility.
|
|
27149
|
+
*/
|
|
27150
|
+
async createTreeWithoutDirectTx({
|
|
27151
|
+
keyDerivation,
|
|
27152
|
+
verifyingKey,
|
|
27153
|
+
depositTx,
|
|
27154
|
+
vout
|
|
27155
|
+
}) {
|
|
27156
|
+
const output = depositTx.getOutput(vout);
|
|
27157
|
+
if (!output) {
|
|
27158
|
+
throw new ValidationError("Invalid deposit transaction output", {
|
|
27159
|
+
field: "vout",
|
|
27160
|
+
value: vout,
|
|
27161
|
+
expected: "Valid output index"
|
|
27162
|
+
});
|
|
27163
|
+
}
|
|
27164
|
+
const script = output.script;
|
|
27165
|
+
const amount = output.amount;
|
|
27166
|
+
if (!script || !amount) {
|
|
27167
|
+
throw new ValidationError("No script or amount found in deposit tx", {
|
|
27168
|
+
field: "output",
|
|
27169
|
+
value: output,
|
|
27170
|
+
expected: "Output with script and amount"
|
|
27171
|
+
});
|
|
27172
|
+
}
|
|
27173
|
+
const depositOutPoint = {
|
|
27174
|
+
txid: (0, import_utils15.hexToBytes)(getTxId(depositTx)),
|
|
27175
|
+
index: vout
|
|
27176
|
+
};
|
|
27177
|
+
const depositTxOut = {
|
|
27178
|
+
script,
|
|
27179
|
+
amount
|
|
27180
|
+
};
|
|
27181
|
+
const [cpfpRootTx, _] = createRootTx(depositOutPoint, depositTxOut);
|
|
27182
|
+
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
27183
|
+
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
26100
27184
|
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
26101
|
-
const
|
|
26102
|
-
|
|
26103
|
-
|
|
26104
|
-
|
|
26105
|
-
|
|
26106
|
-
|
|
26107
|
-
refundTx.addOutput({
|
|
26108
|
-
script: refundPkScript,
|
|
26109
|
-
amount: outputAmount
|
|
27185
|
+
const { cpfpRefundTx } = createRefundTxs({
|
|
27186
|
+
sequence: INITIAL_SEQUENCE,
|
|
27187
|
+
input: { txid: (0, import_utils15.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
27188
|
+
amountSats: amount,
|
|
27189
|
+
receivingPubkey: signingPubKey,
|
|
27190
|
+
network: this.config.getNetwork()
|
|
26110
27191
|
});
|
|
26111
|
-
|
|
26112
|
-
const
|
|
26113
|
-
|
|
27192
|
+
const cpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
27193
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
27194
|
+
cpfpRefundTx,
|
|
27195
|
+
0,
|
|
27196
|
+
cpfpRootTx.getOutput(0)
|
|
27197
|
+
);
|
|
26114
27198
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
26115
27199
|
this.config.getCoordinatorAddress()
|
|
26116
27200
|
);
|
|
@@ -26124,14 +27208,14 @@ var DepositService = class {
|
|
|
26124
27208
|
network: this.config.getNetworkProto()
|
|
26125
27209
|
},
|
|
26126
27210
|
rootTxSigningJob: {
|
|
26127
|
-
rawTx:
|
|
27211
|
+
rawTx: cpfpRootTx.toBytes(),
|
|
26128
27212
|
signingPublicKey: signingPubKey,
|
|
26129
|
-
signingNonceCommitment:
|
|
27213
|
+
signingNonceCommitment: cpfpRootNonceCommitment.commitment
|
|
26130
27214
|
},
|
|
26131
27215
|
refundTxSigningJob: {
|
|
26132
|
-
rawTx:
|
|
27216
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
26133
27217
|
signingPublicKey: signingPubKey,
|
|
26134
|
-
signingNonceCommitment:
|
|
27218
|
+
signingNonceCommitment: cpfpRefundNonceCommitment.commitment
|
|
26135
27219
|
}
|
|
26136
27220
|
});
|
|
26137
27221
|
} catch (error) {
|
|
@@ -26177,55 +27261,55 @@ var DepositService = class {
|
|
|
26177
27261
|
expected: verifyingKey
|
|
26178
27262
|
});
|
|
26179
27263
|
}
|
|
26180
|
-
const
|
|
26181
|
-
message:
|
|
27264
|
+
const cpfpRootSignature = await this.config.signer.signFrost({
|
|
27265
|
+
message: cpfpRootTxSighash,
|
|
26182
27266
|
publicKey: signingPubKey,
|
|
26183
27267
|
keyDerivation,
|
|
26184
27268
|
verifyingKey,
|
|
26185
|
-
selfCommitment:
|
|
27269
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
26186
27270
|
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
26187
27271
|
adaptorPubKey: new Uint8Array()
|
|
26188
27272
|
});
|
|
26189
|
-
const
|
|
26190
|
-
message:
|
|
27273
|
+
const cpfpRefundSignature = await this.config.signer.signFrost({
|
|
27274
|
+
message: cpfpRefundTxSighash,
|
|
26191
27275
|
publicKey: signingPubKey,
|
|
26192
27276
|
keyDerivation,
|
|
26193
|
-
verifyingKey,
|
|
26194
|
-
selfCommitment:
|
|
27277
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
27278
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
26195
27279
|
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
26196
27280
|
adaptorPubKey: new Uint8Array()
|
|
26197
27281
|
});
|
|
26198
|
-
const
|
|
26199
|
-
message:
|
|
27282
|
+
const cpfpRootAggregate = await this.config.signer.aggregateFrost({
|
|
27283
|
+
message: cpfpRootTxSighash,
|
|
26200
27284
|
statechainSignatures: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signatureShares,
|
|
26201
27285
|
statechainPublicKeys: treeResp.rootNodeSignatureShares.nodeTxSigningResult.publicKeys,
|
|
26202
27286
|
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
26203
27287
|
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
26204
|
-
selfCommitment:
|
|
27288
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
26205
27289
|
publicKey: signingPubKey,
|
|
26206
|
-
selfSignature:
|
|
27290
|
+
selfSignature: cpfpRootSignature,
|
|
26207
27291
|
adaptorPubKey: new Uint8Array()
|
|
26208
27292
|
});
|
|
26209
|
-
const
|
|
26210
|
-
message:
|
|
27293
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
27294
|
+
message: cpfpRefundTxSighash,
|
|
26211
27295
|
statechainSignatures: treeResp.rootNodeSignatureShares.refundTxSigningResult.signatureShares,
|
|
26212
27296
|
statechainPublicKeys: treeResp.rootNodeSignatureShares.refundTxSigningResult.publicKeys,
|
|
26213
27297
|
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
26214
27298
|
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
26215
|
-
selfCommitment:
|
|
27299
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
26216
27300
|
publicKey: signingPubKey,
|
|
26217
|
-
selfSignature:
|
|
27301
|
+
selfSignature: cpfpRefundSignature,
|
|
26218
27302
|
adaptorPubKey: new Uint8Array()
|
|
26219
27303
|
});
|
|
26220
27304
|
let finalizeResp;
|
|
26221
27305
|
try {
|
|
26222
|
-
finalizeResp = await sparkClient.
|
|
27306
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
26223
27307
|
intent: 0 /* CREATION */,
|
|
26224
27308
|
nodeSignatures: [
|
|
26225
27309
|
{
|
|
26226
27310
|
nodeId: treeResp.rootNodeSignatureShares.nodeId,
|
|
26227
|
-
nodeTxSignature:
|
|
26228
|
-
refundTxSignature:
|
|
27311
|
+
nodeTxSignature: cpfpRootAggregate,
|
|
27312
|
+
refundTxSignature: cpfpRefundAggregate
|
|
26229
27313
|
}
|
|
26230
27314
|
]
|
|
26231
27315
|
});
|
|
@@ -26435,7 +27519,8 @@ var LightningService = class {
|
|
|
26435
27519
|
let signingCommitments;
|
|
26436
27520
|
try {
|
|
26437
27521
|
signingCommitments = await sparkClient.get_signing_commitments({
|
|
26438
|
-
nodeIds: leaves.map((leaf) => leaf.leaf.id)
|
|
27522
|
+
nodeIds: leaves.map((leaf) => leaf.leaf.id),
|
|
27523
|
+
count: 3
|
|
26439
27524
|
});
|
|
26440
27525
|
} catch (error) {
|
|
26441
27526
|
throw new NetworkError(
|
|
@@ -26448,10 +27533,19 @@ var LightningService = class {
|
|
|
26448
27533
|
error
|
|
26449
27534
|
);
|
|
26450
27535
|
}
|
|
26451
|
-
const
|
|
27536
|
+
const {
|
|
27537
|
+
cpfpLeafSigningJobs,
|
|
27538
|
+
directLeafSigningJobs,
|
|
27539
|
+
directFromCpfpLeafSigningJobs
|
|
27540
|
+
} = await this.signingService.signRefunds(
|
|
26452
27541
|
leaves,
|
|
26453
|
-
|
|
26454
|
-
|
|
27542
|
+
receiverIdentityPubkey,
|
|
27543
|
+
signingCommitments.signingCommitments.slice(0, leaves.length),
|
|
27544
|
+
signingCommitments.signingCommitments.slice(
|
|
27545
|
+
leaves.length,
|
|
27546
|
+
2 * leaves.length
|
|
27547
|
+
),
|
|
27548
|
+
signingCommitments.signingCommitments.slice(2 * leaves.length)
|
|
26455
27549
|
);
|
|
26456
27550
|
const transferId = (0, import_uuidv74.uuidv7)();
|
|
26457
27551
|
let bolt11String = "";
|
|
@@ -26488,7 +27582,7 @@ var LightningService = class {
|
|
|
26488
27582
|
const reason = isInboundPayment ? 1 /* REASON_RECEIVE */ : 0 /* REASON_SEND */;
|
|
26489
27583
|
let response;
|
|
26490
27584
|
try {
|
|
26491
|
-
response = await sparkClient.
|
|
27585
|
+
response = await sparkClient.initiate_preimage_swap_v2({
|
|
26492
27586
|
paymentHash,
|
|
26493
27587
|
invoiceAmount: {
|
|
26494
27588
|
invoiceAmountProof: {
|
|
@@ -26500,7 +27594,9 @@ var LightningService = class {
|
|
|
26500
27594
|
transfer: {
|
|
26501
27595
|
transferId,
|
|
26502
27596
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
26503
|
-
leavesToSend:
|
|
27597
|
+
leavesToSend: cpfpLeafSigningJobs,
|
|
27598
|
+
directLeavesToSend: directLeafSigningJobs,
|
|
27599
|
+
directFromCpfpLeavesToSend: directFromCpfpLeafSigningJobs,
|
|
26504
27600
|
receiverIdentityPublicKey: receiverIdentityPubkey,
|
|
26505
27601
|
expiryTime: new Date(Date.now() + 2 * 60 * 1e3)
|
|
26506
27602
|
},
|
|
@@ -28977,13 +30073,6 @@ function isTokenTransaction(tokenTransaction) {
|
|
|
28977
30073
|
init_buffer();
|
|
28978
30074
|
var import_utils20 = require("@noble/curves/abstract/utils");
|
|
28979
30075
|
var import_btc_signer5 = require("@scure/btc-signer");
|
|
28980
|
-
var INITIAL_TIME_LOCK3 = 2e3;
|
|
28981
|
-
function maybeApplyFee2(amount) {
|
|
28982
|
-
if (amount > BigInt(DEFAULT_FEE_SATS)) {
|
|
28983
|
-
return amount - BigInt(DEFAULT_FEE_SATS);
|
|
28984
|
-
}
|
|
28985
|
-
return amount;
|
|
28986
|
-
}
|
|
28987
30076
|
var TreeCreationService = class {
|
|
28988
30077
|
config;
|
|
28989
30078
|
connectionManager;
|
|
@@ -29098,7 +30187,7 @@ var TreeCreationService = class {
|
|
|
29098
30187
|
);
|
|
29099
30188
|
let response;
|
|
29100
30189
|
try {
|
|
29101
|
-
response = await sparkClient.
|
|
30190
|
+
response = await sparkClient.create_tree_v2(request);
|
|
29102
30191
|
} catch (error) {
|
|
29103
30192
|
throw new Error(`Error creating tree: ${error}`);
|
|
29104
30193
|
}
|
|
@@ -29115,7 +30204,7 @@ var TreeCreationService = class {
|
|
|
29115
30204
|
);
|
|
29116
30205
|
let finalizeResp;
|
|
29117
30206
|
try {
|
|
29118
|
-
finalizeResp = await sparkClient.
|
|
30207
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
29119
30208
|
nodeSignatures
|
|
29120
30209
|
});
|
|
29121
30210
|
} catch (error) {
|
|
@@ -29180,91 +30269,111 @@ var TreeCreationService = class {
|
|
|
29180
30269
|
async buildChildCreationNode(node, parentTx, vout, network) {
|
|
29181
30270
|
const internalCreationNode = {
|
|
29182
30271
|
nodeTxSigningJob: void 0,
|
|
29183
|
-
refundTxSigningJob: void 0,
|
|
29184
|
-
children: [],
|
|
29185
30272
|
directNodeTxSigningJob: void 0,
|
|
30273
|
+
refundTxSigningJob: void 0,
|
|
29186
30274
|
directRefundTxSigningJob: void 0,
|
|
29187
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
30275
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
30276
|
+
children: []
|
|
29188
30277
|
};
|
|
29189
|
-
const tx = new import_btc_signer5.Transaction({ version: 3 });
|
|
29190
|
-
tx.addInput({
|
|
29191
|
-
txid: getTxId(parentTx),
|
|
29192
|
-
index: vout
|
|
29193
|
-
});
|
|
29194
30278
|
const parentTxOut = parentTx.getOutput(vout);
|
|
29195
30279
|
if (!parentTxOut?.script || !parentTxOut?.amount) {
|
|
29196
30280
|
throw new Error("parentTxOut is undefined");
|
|
29197
30281
|
}
|
|
29198
|
-
|
|
30282
|
+
const parentOutPoint = {
|
|
30283
|
+
txid: (0, import_utils20.hexToBytes)(getTxId(parentTx)),
|
|
30284
|
+
index: vout
|
|
30285
|
+
};
|
|
30286
|
+
const parentTxOutObj = {
|
|
29199
30287
|
script: parentTxOut.script,
|
|
29200
30288
|
amount: parentTxOut.amount
|
|
29201
|
-
|
|
29202
|
-
}
|
|
29203
|
-
|
|
29204
|
-
|
|
29205
|
-
|
|
30289
|
+
};
|
|
30290
|
+
const { cpfpNodeTx, directNodeTx } = createNodeTxs(
|
|
30291
|
+
parentTxOutObj,
|
|
30292
|
+
parentOutPoint
|
|
30293
|
+
);
|
|
30294
|
+
const cpfpNodeSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30295
|
+
const directNodeSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30296
|
+
const cpfpNodeSigningJob = {
|
|
29206
30297
|
signingPublicKey: node.signingPublicKey,
|
|
29207
|
-
rawTx:
|
|
29208
|
-
signingNonceCommitment:
|
|
30298
|
+
rawTx: cpfpNodeTx.toBytes(),
|
|
30299
|
+
signingNonceCommitment: cpfpNodeSigningCommitment.commitment
|
|
29209
30300
|
};
|
|
29210
|
-
|
|
29211
|
-
|
|
29212
|
-
|
|
30301
|
+
const directNodeSigningJob = directNodeTx ? {
|
|
30302
|
+
signingPublicKey: node.signingPublicKey,
|
|
30303
|
+
rawTx: directNodeTx.toBytes(),
|
|
30304
|
+
signingNonceCommitment: directNodeSigningCommitment.commitment
|
|
30305
|
+
} : void 0;
|
|
30306
|
+
internalCreationNode.nodeTxSigningCommitment = cpfpNodeSigningCommitment;
|
|
30307
|
+
internalCreationNode.directNodeTxSigningCommitment = directNodeSigningCommitment;
|
|
30308
|
+
internalCreationNode.nodeTxSigningJob = cpfpNodeSigningJob;
|
|
30309
|
+
internalCreationNode.directNodeTxSigningJob = directNodeSigningJob;
|
|
30310
|
+
const sequence = INITIAL_SEQUENCE;
|
|
30311
|
+
const directSequence = INITIAL_DIRECT_SEQUENCE;
|
|
29213
30312
|
const childCreationNode = {
|
|
29214
30313
|
nodeTxSigningJob: void 0,
|
|
29215
|
-
refundTxSigningJob: void 0,
|
|
29216
|
-
children: [],
|
|
29217
30314
|
directNodeTxSigningJob: void 0,
|
|
30315
|
+
refundTxSigningJob: void 0,
|
|
29218
30316
|
directRefundTxSigningJob: void 0,
|
|
29219
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
30317
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
30318
|
+
children: []
|
|
29220
30319
|
};
|
|
29221
|
-
const
|
|
29222
|
-
|
|
29223
|
-
|
|
29224
|
-
index: 0,
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
|
|
29230
|
-
|
|
29231
|
-
|
|
29232
|
-
childTx.addOutput(getEphemeralAnchorOutput());
|
|
29233
|
-
const childSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29234
|
-
const childSigningJob = {
|
|
30320
|
+
const [cpfpLeafTx, directLeafTx] = createLeafNodeTx(
|
|
30321
|
+
sequence,
|
|
30322
|
+
directSequence,
|
|
30323
|
+
{ txid: (0, import_utils20.hexToBytes)(getTxId(cpfpNodeTx)), index: 0 },
|
|
30324
|
+
parentTxOutObj,
|
|
30325
|
+
true
|
|
30326
|
+
// shouldCalculateFee
|
|
30327
|
+
);
|
|
30328
|
+
const cpfpLeafSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30329
|
+
const directLeafSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30330
|
+
const cpfpLeafSigningJob = {
|
|
29235
30331
|
signingPublicKey: node.signingPublicKey,
|
|
29236
|
-
rawTx:
|
|
29237
|
-
signingNonceCommitment:
|
|
29238
|
-
};
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29242
|
-
|
|
29243
|
-
|
|
29244
|
-
|
|
29245
|
-
|
|
29246
|
-
|
|
29247
|
-
|
|
29248
|
-
|
|
30332
|
+
rawTx: cpfpLeafTx.toBytes(),
|
|
30333
|
+
signingNonceCommitment: cpfpLeafSigningCommitment.commitment
|
|
30334
|
+
};
|
|
30335
|
+
const directLeafSigningJob = {
|
|
30336
|
+
signingPublicKey: node.signingPublicKey,
|
|
30337
|
+
rawTx: directLeafTx.toBytes(),
|
|
30338
|
+
signingNonceCommitment: directLeafSigningCommitment.commitment
|
|
30339
|
+
};
|
|
30340
|
+
childCreationNode.nodeTxSigningCommitment = cpfpLeafSigningCommitment;
|
|
30341
|
+
childCreationNode.directNodeTxSigningCommitment = directLeafSigningCommitment;
|
|
30342
|
+
childCreationNode.nodeTxSigningJob = cpfpLeafSigningJob;
|
|
30343
|
+
childCreationNode.directNodeTxSigningJob = directLeafSigningJob;
|
|
30344
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
30345
|
+
sequence,
|
|
30346
|
+
directSequence,
|
|
30347
|
+
input: { txid: (0, import_utils20.hexToBytes)(getTxId(cpfpLeafTx)), index: 0 },
|
|
30348
|
+
directInput: { txid: (0, import_utils20.hexToBytes)(getTxId(directLeafTx)), index: 0 },
|
|
30349
|
+
amountSats: parentTxOut.amount,
|
|
30350
|
+
receivingPubkey: node.signingPublicKey,
|
|
29249
30351
|
network
|
|
29250
|
-
);
|
|
29251
|
-
const refundAddress = (0, import_btc_signer5.Address)(getNetwork(network)).decode(
|
|
29252
|
-
refundP2trAddress
|
|
29253
|
-
);
|
|
29254
|
-
const refundPkScript = import_btc_signer5.OutScript.encode(refundAddress);
|
|
29255
|
-
refundTx.addOutput({
|
|
29256
|
-
script: refundPkScript,
|
|
29257
|
-
amount: maybeApplyFee2(parentTxOut.amount)
|
|
29258
30352
|
});
|
|
29259
|
-
|
|
29260
|
-
const
|
|
29261
|
-
const
|
|
30353
|
+
const cpfpRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30354
|
+
const directRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30355
|
+
const directFromCpfpRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30356
|
+
const cpfpRefundSigningJob = {
|
|
29262
30357
|
signingPublicKey: node.signingPublicKey,
|
|
29263
|
-
rawTx:
|
|
29264
|
-
signingNonceCommitment:
|
|
30358
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
30359
|
+
signingNonceCommitment: cpfpRefundSigningCommitment.commitment
|
|
29265
30360
|
};
|
|
29266
|
-
|
|
29267
|
-
|
|
30361
|
+
const directRefundSigningJob = directRefundTx ? {
|
|
30362
|
+
signingPublicKey: node.signingPublicKey,
|
|
30363
|
+
rawTx: directRefundTx.toBytes(),
|
|
30364
|
+
signingNonceCommitment: directRefundSigningCommitment.commitment
|
|
30365
|
+
} : void 0;
|
|
30366
|
+
const directFromCpfpRefundSigningJob = directFromCpfpRefundTx ? {
|
|
30367
|
+
signingPublicKey: node.signingPublicKey,
|
|
30368
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
30369
|
+
signingNonceCommitment: directFromCpfpRefundSigningCommitment.commitment
|
|
30370
|
+
} : void 0;
|
|
30371
|
+
childCreationNode.refundTxSigningCommitment = cpfpRefundSigningCommitment;
|
|
30372
|
+
childCreationNode.directRefundTxSigningCommitment = directRefundSigningCommitment;
|
|
30373
|
+
childCreationNode.directFromCpfpRefundTxSigningCommitment = directFromCpfpRefundSigningCommitment;
|
|
30374
|
+
childCreationNode.refundTxSigningJob = cpfpRefundSigningJob;
|
|
30375
|
+
childCreationNode.directRefundTxSigningJob = directRefundSigningJob;
|
|
30376
|
+
childCreationNode.directFromCpfpRefundTxSigningJob = directFromCpfpRefundSigningJob;
|
|
29268
30377
|
internalCreationNode.children.push(childCreationNode);
|
|
29269
30378
|
return internalCreationNode;
|
|
29270
30379
|
}
|
|
@@ -29273,11 +30382,7 @@ var TreeCreationService = class {
|
|
|
29273
30382
|
if (!parentTxOutput?.script || !parentTxOutput?.amount) {
|
|
29274
30383
|
throw new Error("parentTxOutput is undefined");
|
|
29275
30384
|
}
|
|
29276
|
-
const
|
|
29277
|
-
rootNodeTx.addInput({
|
|
29278
|
-
txid: getTxId(parentTx),
|
|
29279
|
-
index: vout
|
|
29280
|
-
});
|
|
30385
|
+
const childTxOuts = [];
|
|
29281
30386
|
for (let i = 0; i < root.children.length; i++) {
|
|
29282
30387
|
const child = root.children[i];
|
|
29283
30388
|
if (!child || !child.address) {
|
|
@@ -29285,28 +30390,41 @@ var TreeCreationService = class {
|
|
|
29285
30390
|
}
|
|
29286
30391
|
const childAddress = (0, import_btc_signer5.Address)(getNetwork(network)).decode(child.address);
|
|
29287
30392
|
const childPkScript = import_btc_signer5.OutScript.encode(childAddress);
|
|
29288
|
-
|
|
30393
|
+
childTxOuts.push({
|
|
29289
30394
|
script: childPkScript,
|
|
29290
30395
|
amount: parentTxOutput.amount / 2n
|
|
29291
|
-
// feeAdjustedAmount / 2n,
|
|
29292
30396
|
});
|
|
29293
30397
|
}
|
|
29294
|
-
|
|
29295
|
-
|
|
29296
|
-
|
|
30398
|
+
const parentOutPoint = {
|
|
30399
|
+
txid: (0, import_utils20.hexToBytes)(getTxId(parentTx)),
|
|
30400
|
+
index: vout
|
|
30401
|
+
};
|
|
30402
|
+
const [cpfpSplitTx, directSplitTx] = createSplitTx(
|
|
30403
|
+
parentOutPoint,
|
|
30404
|
+
childTxOuts
|
|
30405
|
+
);
|
|
30406
|
+
const cpfpSplitSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30407
|
+
const directSplitSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30408
|
+
const cpfpSplitSigningJob = {
|
|
30409
|
+
signingPublicKey: root.signingPublicKey,
|
|
30410
|
+
rawTx: cpfpSplitTx.toBytes(),
|
|
30411
|
+
signingNonceCommitment: cpfpSplitSigningCommitment.commitment
|
|
30412
|
+
};
|
|
30413
|
+
const directSplitSigningJob = {
|
|
29297
30414
|
signingPublicKey: root.signingPublicKey,
|
|
29298
|
-
rawTx:
|
|
29299
|
-
signingNonceCommitment:
|
|
30415
|
+
rawTx: directSplitTx.toBytes(),
|
|
30416
|
+
signingNonceCommitment: directSplitSigningCommitment.commitment
|
|
29300
30417
|
};
|
|
29301
30418
|
const rootCreationNode = {
|
|
29302
|
-
nodeTxSigningJob:
|
|
30419
|
+
nodeTxSigningJob: cpfpSplitSigningJob,
|
|
30420
|
+
directNodeTxSigningJob: directSplitSigningJob,
|
|
29303
30421
|
refundTxSigningJob: void 0,
|
|
29304
|
-
children: [],
|
|
29305
|
-
directNodeTxSigningJob: void 0,
|
|
29306
30422
|
directRefundTxSigningJob: void 0,
|
|
29307
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
30423
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
30424
|
+
children: []
|
|
29308
30425
|
};
|
|
29309
|
-
rootCreationNode.nodeTxSigningCommitment =
|
|
30426
|
+
rootCreationNode.nodeTxSigningCommitment = cpfpSplitSigningCommitment;
|
|
30427
|
+
rootCreationNode.directNodeTxSigningCommitment = directSplitSigningCommitment;
|
|
29310
30428
|
const leftChild = root.children[0];
|
|
29311
30429
|
const rightChild = root.children[1];
|
|
29312
30430
|
if (!leftChild || !rightChild) {
|
|
@@ -29314,13 +30432,15 @@ var TreeCreationService = class {
|
|
|
29314
30432
|
}
|
|
29315
30433
|
const leftChildCreationNode = await this.buildChildCreationNode(
|
|
29316
30434
|
leftChild,
|
|
29317
|
-
|
|
30435
|
+
cpfpSplitTx,
|
|
30436
|
+
// Use CPFP version for children
|
|
29318
30437
|
0,
|
|
29319
30438
|
network
|
|
29320
30439
|
);
|
|
29321
30440
|
const rightChildCreationNode = await this.buildChildCreationNode(
|
|
29322
30441
|
rightChild,
|
|
29323
|
-
|
|
30442
|
+
cpfpSplitTx,
|
|
30443
|
+
// Use CPFP version for children
|
|
29324
30444
|
1,
|
|
29325
30445
|
network
|
|
29326
30446
|
);
|
|
@@ -29329,19 +30449,19 @@ var TreeCreationService = class {
|
|
|
29329
30449
|
return rootCreationNode;
|
|
29330
30450
|
}
|
|
29331
30451
|
async signNodeCreation(parentTx, vout, internalNode, creationNode, creationResponseNode) {
|
|
29332
|
-
if (!creationNode.nodeTxSigningJob?.signingPublicKey || !internalNode.verificationKey) {
|
|
30452
|
+
if (!creationNode.nodeTxSigningJob?.signingPublicKey || !creationNode.directNodeTxSigningJob?.signingPublicKey || !internalNode.verificationKey) {
|
|
29333
30453
|
throw new Error("signingPublicKey or verificationKey is undefined");
|
|
29334
30454
|
}
|
|
29335
30455
|
const parentTxOutput = parentTx.getOutput(vout);
|
|
29336
30456
|
if (!parentTxOutput) {
|
|
29337
30457
|
throw new Error("parentTxOutput is undefined");
|
|
29338
30458
|
}
|
|
29339
|
-
const
|
|
29340
|
-
const
|
|
29341
|
-
let
|
|
30459
|
+
const cpfpNodeTx = getTxFromRawTxBytes(creationNode.nodeTxSigningJob.rawTx);
|
|
30460
|
+
const cpfpNodeTxSighash = getSigHashFromTx(cpfpNodeTx, 0, parentTxOutput);
|
|
30461
|
+
let cpfpNodeTxSignature = new Uint8Array();
|
|
29342
30462
|
if (creationNode.nodeTxSigningCommitment) {
|
|
29343
|
-
const
|
|
29344
|
-
message:
|
|
30463
|
+
const cpfpUserSignature = await this.config.signer.signFrost({
|
|
30464
|
+
message: cpfpNodeTxSighash,
|
|
29345
30465
|
publicKey: creationNode.nodeTxSigningJob.signingPublicKey,
|
|
29346
30466
|
keyDerivation: {
|
|
29347
30467
|
type: "leaf" /* LEAF */,
|
|
@@ -29351,30 +30471,84 @@ var TreeCreationService = class {
|
|
|
29351
30471
|
statechainCommitments: creationResponseNode.nodeTxSigningResult?.signingNonceCommitments,
|
|
29352
30472
|
verifyingKey: internalNode.verificationKey
|
|
29353
30473
|
});
|
|
29354
|
-
|
|
29355
|
-
message:
|
|
30474
|
+
cpfpNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
30475
|
+
message: cpfpNodeTxSighash,
|
|
29356
30476
|
statechainSignatures: creationResponseNode.nodeTxSigningResult?.signatureShares,
|
|
29357
30477
|
statechainPublicKeys: creationResponseNode.nodeTxSigningResult?.publicKeys,
|
|
29358
30478
|
verifyingKey: internalNode.verificationKey,
|
|
29359
30479
|
statechainCommitments: creationResponseNode.nodeTxSigningResult?.signingNonceCommitments,
|
|
29360
30480
|
selfCommitment: creationNode.nodeTxSigningCommitment,
|
|
29361
|
-
selfSignature:
|
|
30481
|
+
selfSignature: cpfpUserSignature,
|
|
29362
30482
|
publicKey: internalNode.signingPublicKey
|
|
29363
30483
|
});
|
|
29364
30484
|
}
|
|
29365
|
-
|
|
29366
|
-
|
|
29367
|
-
|
|
29368
|
-
|
|
29369
|
-
|
|
29370
|
-
|
|
29371
|
-
|
|
29372
|
-
|
|
29373
|
-
|
|
29374
|
-
|
|
29375
|
-
const
|
|
29376
|
-
|
|
29377
|
-
|
|
30485
|
+
const directNodeTx = getTxFromRawTxBytes(
|
|
30486
|
+
creationNode.directNodeTxSigningJob.rawTx
|
|
30487
|
+
);
|
|
30488
|
+
const directNodeTxSighash = getSigHashFromTx(
|
|
30489
|
+
directNodeTx,
|
|
30490
|
+
0,
|
|
30491
|
+
parentTxOutput
|
|
30492
|
+
);
|
|
30493
|
+
let directNodeTxSignature = new Uint8Array();
|
|
30494
|
+
if (creationNode.directNodeTxSigningCommitment) {
|
|
30495
|
+
const directUserSignature = await this.config.signer.signFrost({
|
|
30496
|
+
message: directNodeTxSighash,
|
|
30497
|
+
publicKey: creationNode.directNodeTxSigningJob.signingPublicKey,
|
|
30498
|
+
keyDerivation: {
|
|
30499
|
+
type: "leaf" /* LEAF */,
|
|
30500
|
+
path: creationResponseNode.nodeId
|
|
30501
|
+
},
|
|
30502
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
30503
|
+
statechainCommitments: creationResponseNode.directNodeTxSigningResult?.signingNonceCommitments,
|
|
30504
|
+
verifyingKey: internalNode.verificationKey
|
|
30505
|
+
});
|
|
30506
|
+
directNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
30507
|
+
message: directNodeTxSighash,
|
|
30508
|
+
statechainSignatures: creationResponseNode.directNodeTxSigningResult?.signatureShares,
|
|
30509
|
+
statechainPublicKeys: creationResponseNode.directNodeTxSigningResult?.publicKeys,
|
|
30510
|
+
verifyingKey: internalNode.verificationKey,
|
|
30511
|
+
statechainCommitments: creationResponseNode.directNodeTxSigningResult?.signingNonceCommitments,
|
|
30512
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
30513
|
+
selfSignature: directUserSignature,
|
|
30514
|
+
publicKey: internalNode.signingPublicKey
|
|
30515
|
+
});
|
|
30516
|
+
}
|
|
30517
|
+
let cpfpRefundTxSignature = new Uint8Array();
|
|
30518
|
+
let directRefundTxSignature = new Uint8Array();
|
|
30519
|
+
let directFromCpfpRefundTxSignature = new Uint8Array();
|
|
30520
|
+
if (creationNode.refundTxSigningCommitment && creationNode.directRefundTxSigningCommitment && creationNode.directFromCpfpRefundTxSigningCommitment) {
|
|
30521
|
+
const rawCpfpRefundTx = creationNode.refundTxSigningJob?.rawTx;
|
|
30522
|
+
const rawDirectRefundTx = creationNode.directRefundTxSigningJob?.rawTx;
|
|
30523
|
+
const rawDirectFromCpfpRefundTx = creationNode.directFromCpfpRefundTxSigningJob?.rawTx;
|
|
30524
|
+
if (!rawCpfpRefundTx || !rawDirectRefundTx || !rawDirectFromCpfpRefundTx) {
|
|
30525
|
+
throw new Error("refund transaction rawTx is undefined");
|
|
30526
|
+
}
|
|
30527
|
+
if (!creationNode.refundTxSigningJob?.signingPublicKey || !creationNode.directRefundTxSigningJob?.signingPublicKey || !creationNode.directFromCpfpRefundTxSigningJob?.signingPublicKey) {
|
|
30528
|
+
throw new Error("refund transaction signingPublicKey is undefined");
|
|
30529
|
+
}
|
|
30530
|
+
const cpfpRefundTx = getTxFromRawTxBytes(rawCpfpRefundTx);
|
|
30531
|
+
const directRefundTx = getTxFromRawTxBytes(rawDirectRefundTx);
|
|
30532
|
+
const directFromCpfpRefundTx = getTxFromRawTxBytes(
|
|
30533
|
+
rawDirectFromCpfpRefundTx
|
|
30534
|
+
);
|
|
30535
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
30536
|
+
cpfpRefundTx,
|
|
30537
|
+
0,
|
|
30538
|
+
cpfpNodeTx.getOutput(0)
|
|
30539
|
+
);
|
|
30540
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
30541
|
+
directRefundTx,
|
|
30542
|
+
0,
|
|
30543
|
+
directNodeTx.getOutput(0)
|
|
30544
|
+
);
|
|
30545
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
30546
|
+
directFromCpfpRefundTx,
|
|
30547
|
+
0,
|
|
30548
|
+
cpfpNodeTx.getOutput(0)
|
|
30549
|
+
);
|
|
30550
|
+
const cpfpRefundUserSignature = await this.config.signer.signFrost({
|
|
30551
|
+
message: cpfpRefundTxSighash,
|
|
29378
30552
|
publicKey: creationNode.refundTxSigningJob.signingPublicKey,
|
|
29379
30553
|
keyDerivation: {
|
|
29380
30554
|
type: "leaf" /* LEAF */,
|
|
@@ -29384,27 +30558,69 @@ var TreeCreationService = class {
|
|
|
29384
30558
|
statechainCommitments: creationResponseNode.refundTxSigningResult?.signingNonceCommitments,
|
|
29385
30559
|
verifyingKey: internalNode.verificationKey
|
|
29386
30560
|
});
|
|
29387
|
-
|
|
29388
|
-
message:
|
|
30561
|
+
cpfpRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
30562
|
+
message: cpfpRefundTxSighash,
|
|
29389
30563
|
statechainSignatures: creationResponseNode.refundTxSigningResult?.signatureShares,
|
|
29390
30564
|
statechainPublicKeys: creationResponseNode.refundTxSigningResult?.publicKeys,
|
|
29391
30565
|
verifyingKey: internalNode.verificationKey,
|
|
29392
30566
|
statechainCommitments: creationResponseNode.refundTxSigningResult?.signingNonceCommitments,
|
|
29393
30567
|
selfCommitment: creationNode.refundTxSigningCommitment,
|
|
29394
|
-
selfSignature:
|
|
30568
|
+
selfSignature: cpfpRefundUserSignature,
|
|
30569
|
+
publicKey: internalNode.signingPublicKey
|
|
30570
|
+
});
|
|
30571
|
+
const keyDerivation = {
|
|
30572
|
+
type: "leaf" /* LEAF */,
|
|
30573
|
+
path: creationResponseNode.nodeId
|
|
30574
|
+
};
|
|
30575
|
+
const directRefundUserSignature = await this.config.signer.signFrost({
|
|
30576
|
+
message: directRefundTxSighash,
|
|
30577
|
+
publicKey: creationNode.directRefundTxSigningJob.signingPublicKey,
|
|
30578
|
+
keyDerivation,
|
|
30579
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
30580
|
+
statechainCommitments: creationResponseNode.directRefundTxSigningResult?.signingNonceCommitments,
|
|
30581
|
+
verifyingKey: internalNode.verificationKey
|
|
30582
|
+
});
|
|
30583
|
+
directRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
30584
|
+
message: directRefundTxSighash,
|
|
30585
|
+
statechainSignatures: creationResponseNode.directRefundTxSigningResult?.signatureShares,
|
|
30586
|
+
statechainPublicKeys: creationResponseNode.directRefundTxSigningResult?.publicKeys,
|
|
30587
|
+
verifyingKey: internalNode.verificationKey,
|
|
30588
|
+
statechainCommitments: creationResponseNode.directRefundTxSigningResult?.signingNonceCommitments,
|
|
30589
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
30590
|
+
selfSignature: directRefundUserSignature,
|
|
29395
30591
|
publicKey: internalNode.signingPublicKey
|
|
29396
30592
|
});
|
|
30593
|
+
const directFromCpfpRefundUserSignature = await this.config.signer.signFrost({
|
|
30594
|
+
message: directFromCpfpRefundTxSighash,
|
|
30595
|
+
publicKey: creationNode.directFromCpfpRefundTxSigningJob.signingPublicKey,
|
|
30596
|
+
keyDerivation,
|
|
30597
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
30598
|
+
statechainCommitments: creationResponseNode.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
30599
|
+
verifyingKey: internalNode.verificationKey
|
|
30600
|
+
});
|
|
30601
|
+
directFromCpfpRefundTxSignature = await this.config.signer.aggregateFrost(
|
|
30602
|
+
{
|
|
30603
|
+
message: directFromCpfpRefundTxSighash,
|
|
30604
|
+
statechainSignatures: creationResponseNode.directFromCpfpRefundTxSigningResult?.signatureShares,
|
|
30605
|
+
statechainPublicKeys: creationResponseNode.directFromCpfpRefundTxSigningResult?.publicKeys,
|
|
30606
|
+
verifyingKey: internalNode.verificationKey,
|
|
30607
|
+
statechainCommitments: creationResponseNode.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
30608
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
30609
|
+
selfSignature: directFromCpfpRefundUserSignature,
|
|
30610
|
+
publicKey: internalNode.signingPublicKey
|
|
30611
|
+
}
|
|
30612
|
+
);
|
|
29397
30613
|
}
|
|
29398
30614
|
return {
|
|
29399
|
-
tx,
|
|
30615
|
+
tx: cpfpNodeTx,
|
|
30616
|
+
// Return CPFP version for children
|
|
29400
30617
|
signature: {
|
|
29401
30618
|
nodeId: creationResponseNode.nodeId,
|
|
29402
|
-
nodeTxSignature,
|
|
29403
|
-
|
|
29404
|
-
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
directFromCpfpRefundTxSignature: new Uint8Array()
|
|
30619
|
+
nodeTxSignature: cpfpNodeTxSignature,
|
|
30620
|
+
directNodeTxSignature,
|
|
30621
|
+
refundTxSignature: cpfpRefundTxSignature,
|
|
30622
|
+
directRefundTxSignature,
|
|
30623
|
+
directFromCpfpRefundTxSignature
|
|
29408
30624
|
}
|
|
29409
30625
|
};
|
|
29410
30626
|
}
|
|
@@ -29467,8 +30683,45 @@ var SigningService = class {
|
|
|
29467
30683
|
constructor(config) {
|
|
29468
30684
|
this.config = config;
|
|
29469
30685
|
}
|
|
29470
|
-
async
|
|
30686
|
+
async signRefundsInternal(refundTx, sighash, leaf, signingCommitments) {
|
|
29471
30687
|
const leafSigningJobs = [];
|
|
30688
|
+
const signingCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
30689
|
+
if (!signingCommitments) {
|
|
30690
|
+
throw new ValidationError("Invalid signing commitments", {
|
|
30691
|
+
field: "signingNonceCommitments",
|
|
30692
|
+
value: signingCommitments,
|
|
30693
|
+
expected: "Non-null signing commitments"
|
|
30694
|
+
});
|
|
30695
|
+
}
|
|
30696
|
+
const signingResult = await this.config.signer.signFrost({
|
|
30697
|
+
message: sighash,
|
|
30698
|
+
keyDerivation: leaf.keyDerivation,
|
|
30699
|
+
publicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
30700
|
+
leaf.keyDerivation
|
|
30701
|
+
),
|
|
30702
|
+
selfCommitment: signingCommitment,
|
|
30703
|
+
statechainCommitments: signingCommitments,
|
|
30704
|
+
adaptorPubKey: new Uint8Array(),
|
|
30705
|
+
verifyingKey: leaf.leaf.verifyingPublicKey
|
|
30706
|
+
});
|
|
30707
|
+
leafSigningJobs.push({
|
|
30708
|
+
leafId: leaf.leaf.id,
|
|
30709
|
+
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
30710
|
+
leaf.keyDerivation
|
|
30711
|
+
),
|
|
30712
|
+
rawTx: refundTx.toBytes(),
|
|
30713
|
+
signingNonceCommitment: signingCommitment.commitment,
|
|
30714
|
+
userSignature: signingResult,
|
|
30715
|
+
signingCommitments: {
|
|
30716
|
+
signingCommitments
|
|
30717
|
+
}
|
|
30718
|
+
});
|
|
30719
|
+
return leafSigningJobs;
|
|
30720
|
+
}
|
|
30721
|
+
async signRefunds(leaves, receiverIdentityPubkey, cpfpSigningCommitments, directSigningCommitments, directFromCpfpSigningCommitments) {
|
|
30722
|
+
const cpfpLeafSigningJobs = [];
|
|
30723
|
+
const directLeafSigningJobs = [];
|
|
30724
|
+
const directFromCpfpLeafSigningJobs = [];
|
|
29472
30725
|
for (let i = 0; i < leaves.length; i++) {
|
|
29473
30726
|
const leaf = leaves[i];
|
|
29474
30727
|
if (!leaf?.leaf) {
|
|
@@ -29479,14 +30732,20 @@ var SigningService = class {
|
|
|
29479
30732
|
});
|
|
29480
30733
|
}
|
|
29481
30734
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
29482
|
-
const
|
|
30735
|
+
const cpfpNodeOutPoint = {
|
|
29483
30736
|
txid: (0, import_utils21.hexToBytes)(getTxId(nodeTx)),
|
|
29484
30737
|
index: 0
|
|
29485
30738
|
};
|
|
29486
30739
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
29487
|
-
const
|
|
29488
|
-
|
|
29489
|
-
|
|
30740
|
+
const sequence = currRefundTx.getInput(0).sequence;
|
|
30741
|
+
if (!sequence) {
|
|
30742
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
30743
|
+
field: "sequence",
|
|
30744
|
+
value: currRefundTx.getInput(0),
|
|
30745
|
+
expected: "Non-null sequence"
|
|
30746
|
+
});
|
|
30747
|
+
}
|
|
30748
|
+
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
29490
30749
|
const amountSats = currRefundTx.getOutput(0).amount;
|
|
29491
30750
|
if (amountSats === void 0) {
|
|
29492
30751
|
throw new ValidationError("Invalid refund transaction", {
|
|
@@ -29495,48 +30754,90 @@ var SigningService = class {
|
|
|
29495
30754
|
expected: "Non-null amount"
|
|
29496
30755
|
});
|
|
29497
30756
|
}
|
|
29498
|
-
|
|
29499
|
-
|
|
29500
|
-
|
|
30757
|
+
let directNodeTx;
|
|
30758
|
+
let directNodeOutPoint;
|
|
30759
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
30760
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
30761
|
+
directNodeOutPoint = {
|
|
30762
|
+
txid: (0, import_utils21.hexToBytes)(getTxId(directNodeTx)),
|
|
30763
|
+
index: 0
|
|
30764
|
+
};
|
|
30765
|
+
}
|
|
30766
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
30767
|
+
sequence: nextSequence,
|
|
30768
|
+
directSequence: nextDirectSequence,
|
|
30769
|
+
input: cpfpNodeOutPoint,
|
|
30770
|
+
directInput: directNodeOutPoint,
|
|
29501
30771
|
amountSats,
|
|
29502
|
-
receiverIdentityPubkey,
|
|
29503
|
-
this.config.getNetwork()
|
|
30772
|
+
receivingPubkey: receiverIdentityPubkey,
|
|
30773
|
+
network: this.config.getNetwork()
|
|
30774
|
+
});
|
|
30775
|
+
const refundSighash = getSigHashFromTx(
|
|
30776
|
+
cpfpRefundTx,
|
|
30777
|
+
0,
|
|
30778
|
+
nodeTx.getOutput(0)
|
|
29504
30779
|
);
|
|
29505
|
-
const
|
|
29506
|
-
|
|
29507
|
-
|
|
29508
|
-
|
|
29509
|
-
|
|
29510
|
-
|
|
29511
|
-
|
|
29512
|
-
|
|
29513
|
-
|
|
30780
|
+
const signingJobs = await this.signRefundsInternal(
|
|
30781
|
+
cpfpRefundTx,
|
|
30782
|
+
refundSighash,
|
|
30783
|
+
leaf,
|
|
30784
|
+
cpfpSigningCommitments[i]?.signingNonceCommitments
|
|
30785
|
+
);
|
|
30786
|
+
cpfpLeafSigningJobs.push(...signingJobs);
|
|
30787
|
+
if (directRefundTx) {
|
|
30788
|
+
if (!directNodeTx) {
|
|
30789
|
+
throw new ValidationError(
|
|
30790
|
+
"Direct node transaction undefined while direct refund transaction is defined",
|
|
30791
|
+
{
|
|
30792
|
+
field: "directNodeTx",
|
|
30793
|
+
value: directNodeTx,
|
|
30794
|
+
expected: "Non-null direct node transaction"
|
|
30795
|
+
}
|
|
30796
|
+
);
|
|
30797
|
+
}
|
|
30798
|
+
const refundSighash2 = getSigHashFromTx(
|
|
30799
|
+
directRefundTx,
|
|
30800
|
+
0,
|
|
30801
|
+
directNodeTx.getOutput(0)
|
|
30802
|
+
);
|
|
30803
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
30804
|
+
directRefundTx,
|
|
30805
|
+
refundSighash2,
|
|
30806
|
+
leaf,
|
|
30807
|
+
directSigningCommitments[i]?.signingNonceCommitments
|
|
30808
|
+
);
|
|
30809
|
+
directLeafSigningJobs.push(...signingJobs2);
|
|
29514
30810
|
}
|
|
29515
|
-
|
|
29516
|
-
|
|
29517
|
-
|
|
29518
|
-
|
|
29519
|
-
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
});
|
|
29526
|
-
leafSigningJobs.push({
|
|
29527
|
-
leafId: leaf.leaf.id,
|
|
29528
|
-
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
29529
|
-
leaf.keyDerivation
|
|
29530
|
-
),
|
|
29531
|
-
rawTx: refundTx.toBytes(),
|
|
29532
|
-
signingNonceCommitment: signingCommitment.commitment,
|
|
29533
|
-
userSignature: signingResult,
|
|
29534
|
-
signingCommitments: {
|
|
29535
|
-
signingCommitments: signingNonceCommitments
|
|
30811
|
+
if (directFromCpfpRefundTx) {
|
|
30812
|
+
if (!directNodeTx) {
|
|
30813
|
+
throw new ValidationError(
|
|
30814
|
+
"Direct node transaction undefined while direct from CPFP refund transaction is defined",
|
|
30815
|
+
{
|
|
30816
|
+
field: "directNodeTx",
|
|
30817
|
+
value: directNodeTx,
|
|
30818
|
+
expected: "Non-null direct node transaction"
|
|
30819
|
+
}
|
|
30820
|
+
);
|
|
29536
30821
|
}
|
|
29537
|
-
|
|
30822
|
+
const refundSighash2 = getSigHashFromTx(
|
|
30823
|
+
directFromCpfpRefundTx,
|
|
30824
|
+
0,
|
|
30825
|
+
nodeTx.getOutput(0)
|
|
30826
|
+
);
|
|
30827
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
30828
|
+
directFromCpfpRefundTx,
|
|
30829
|
+
refundSighash2,
|
|
30830
|
+
leaf,
|
|
30831
|
+
directFromCpfpSigningCommitments[i]?.signingNonceCommitments
|
|
30832
|
+
);
|
|
30833
|
+
directFromCpfpLeafSigningJobs.push(...signingJobs2);
|
|
30834
|
+
}
|
|
29538
30835
|
}
|
|
29539
|
-
return
|
|
30836
|
+
return {
|
|
30837
|
+
cpfpLeafSigningJobs,
|
|
30838
|
+
directLeafSigningJobs,
|
|
30839
|
+
directFromCpfpLeafSigningJobs
|
|
30840
|
+
};
|
|
29540
30841
|
}
|
|
29541
30842
|
};
|
|
29542
30843
|
|
|
@@ -29544,7 +30845,7 @@ var SigningService = class {
|
|
|
29544
30845
|
init_buffer();
|
|
29545
30846
|
var import_utils22 = require("@noble/curves/abstract/utils");
|
|
29546
30847
|
var import_secp256k114 = require("@noble/curves/secp256k1");
|
|
29547
|
-
var
|
|
30848
|
+
var btc5 = __toESM(require("@scure/btc-signer"), 1);
|
|
29548
30849
|
var import_btc_signer6 = require("@scure/btc-signer");
|
|
29549
30850
|
var import_utils23 = require("@scure/btc-signer/utils");
|
|
29550
30851
|
var STATIC_FAUCET_KEY = (0, import_utils22.hexToBytes)(
|
|
@@ -29690,7 +30991,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29690
30991
|
}
|
|
29691
30992
|
async sendFaucetCoinToP2WPKHAddress(pubKey) {
|
|
29692
30993
|
const sendToPubKeyTx = new import_btc_signer6.Transaction();
|
|
29693
|
-
const p2wpkhAddress =
|
|
30994
|
+
const p2wpkhAddress = btc5.p2wpkh(pubKey, getNetwork(4 /* LOCAL */)).address;
|
|
29694
30995
|
if (!p2wpkhAddress) {
|
|
29695
30996
|
throw new Error("Invalid P2WPKH address");
|
|
29696
30997
|
}
|
|
@@ -29746,12 +31047,13 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29746
31047
|
}
|
|
29747
31048
|
async call(method, params) {
|
|
29748
31049
|
try {
|
|
29749
|
-
const
|
|
31050
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
31051
|
+
const response = await fetch2(this.url, {
|
|
29750
31052
|
method: "POST",
|
|
29751
|
-
headers: {
|
|
31053
|
+
headers: new Headers2({
|
|
29752
31054
|
"Content-Type": "application/json",
|
|
29753
31055
|
Authorization: "Basic " + btoa(`${this.username}:${this.password}`)
|
|
29754
|
-
},
|
|
31056
|
+
}),
|
|
29755
31057
|
body: JSON.stringify({
|
|
29756
31058
|
jsonrpc: "1.0",
|
|
29757
31059
|
id: "spark-js",
|
|
@@ -30081,31 +31383,37 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30081
31383
|
}
|
|
30082
31384
|
}
|
|
30083
31385
|
async getLeaves(isBalanceCheck = false) {
|
|
30084
|
-
const
|
|
30085
|
-
|
|
30086
|
-
|
|
30087
|
-
|
|
30088
|
-
|
|
30089
|
-
|
|
30090
|
-
|
|
30091
|
-
}
|
|
31386
|
+
const operatorToLeaves = /* @__PURE__ */ new Map();
|
|
31387
|
+
const ownerIdentityPubkey = await this.config.signer.getIdentityPublicKey();
|
|
31388
|
+
let signingOperators = Object.entries(this.config.getSigningOperators());
|
|
31389
|
+
if (isBalanceCheck) {
|
|
31390
|
+
signingOperators = signingOperators.filter(
|
|
31391
|
+
([id, _]) => id === this.config.getCoordinatorIdentifier()
|
|
31392
|
+
);
|
|
31393
|
+
}
|
|
31394
|
+
await Promise.all(
|
|
31395
|
+
signingOperators.map(async ([id, operator]) => {
|
|
31396
|
+
const leaves2 = await this.queryNodes(
|
|
31397
|
+
{
|
|
31398
|
+
source: {
|
|
31399
|
+
$case: "ownerIdentityPubkey",
|
|
31400
|
+
ownerIdentityPubkey
|
|
31401
|
+
},
|
|
31402
|
+
includeParents: false,
|
|
31403
|
+
network: NetworkToProto[this.config.getNetwork()]
|
|
31404
|
+
},
|
|
31405
|
+
operator.address
|
|
31406
|
+
);
|
|
31407
|
+
operatorToLeaves.set(id, leaves2);
|
|
31408
|
+
})
|
|
31409
|
+
);
|
|
31410
|
+
const leaves = operatorToLeaves.get(
|
|
31411
|
+
this.config.getCoordinatorIdentifier()
|
|
31412
|
+
);
|
|
30092
31413
|
const leavesToIgnore = /* @__PURE__ */ new Set();
|
|
30093
31414
|
if (!isBalanceCheck) {
|
|
30094
|
-
for (const [id,
|
|
30095
|
-
this.config.getSigningOperators()
|
|
30096
|
-
)) {
|
|
31415
|
+
for (const [id, operatorLeaves] of operatorToLeaves) {
|
|
30097
31416
|
if (id !== this.config.getCoordinatorIdentifier()) {
|
|
30098
|
-
const operatorLeaves = await this.queryNodes(
|
|
30099
|
-
{
|
|
30100
|
-
source: {
|
|
30101
|
-
$case: "ownerIdentityPubkey",
|
|
30102
|
-
ownerIdentityPubkey: await this.config.signer.getIdentityPublicKey()
|
|
30103
|
-
},
|
|
30104
|
-
includeParents: false,
|
|
30105
|
-
network: NetworkToProto[this.config.getNetwork()]
|
|
30106
|
-
},
|
|
30107
|
-
operator.address
|
|
30108
|
-
);
|
|
30109
31417
|
for (const [nodeId, leaf] of Object.entries(leaves.nodes)) {
|
|
30110
31418
|
const operatorLeaf = operatorLeaves.nodes[nodeId];
|
|
30111
31419
|
if (!operatorLeaf) {
|
|
@@ -30546,21 +31854,68 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30546
31854
|
}
|
|
30547
31855
|
}))
|
|
30548
31856
|
);
|
|
30549
|
-
const {
|
|
31857
|
+
const {
|
|
31858
|
+
transfer,
|
|
31859
|
+
signatureMap,
|
|
31860
|
+
directSignatureMap,
|
|
31861
|
+
directFromCpfpSignatureMap
|
|
31862
|
+
} = await this.transferService.startSwapSignRefund(
|
|
30550
31863
|
leafKeyTweaks,
|
|
30551
31864
|
(0, import_utils24.hexToBytes)(this.config.getSspIdentityPublicKey()),
|
|
30552
31865
|
new Date(Date.now() + 2 * 60 * 1e3)
|
|
30553
31866
|
);
|
|
30554
31867
|
try {
|
|
30555
31868
|
if (!transfer.leaves[0]?.leaf) {
|
|
31869
|
+
console.error("[processSwapBatch] First leaf is missing");
|
|
30556
31870
|
throw new Error("Failed to get leaf");
|
|
30557
31871
|
}
|
|
30558
|
-
const
|
|
30559
|
-
if (!
|
|
30560
|
-
|
|
31872
|
+
const cpfpRefundSignature = signatureMap.get(transfer.leaves[0].leaf.id);
|
|
31873
|
+
if (!cpfpRefundSignature) {
|
|
31874
|
+
console.error(
|
|
31875
|
+
"[processSwapBatch] Missing CPFP refund signature for first leaf"
|
|
31876
|
+
);
|
|
31877
|
+
throw new Error("Failed to get CPFP refund signature");
|
|
31878
|
+
}
|
|
31879
|
+
const directRefundSignature = directSignatureMap.get(
|
|
31880
|
+
transfer.leaves[0].leaf.id
|
|
31881
|
+
);
|
|
31882
|
+
if (!directRefundSignature) {
|
|
31883
|
+
console.error(
|
|
31884
|
+
"[processSwapBatch] Missing direct refund signature for first leaf"
|
|
31885
|
+
);
|
|
31886
|
+
throw new Error("Failed to get direct refund signature");
|
|
31887
|
+
}
|
|
31888
|
+
const directFromCpfpRefundSignature = directFromCpfpSignatureMap.get(
|
|
31889
|
+
transfer.leaves[0].leaf.id
|
|
31890
|
+
);
|
|
31891
|
+
if (!directFromCpfpRefundSignature) {
|
|
31892
|
+
console.error(
|
|
31893
|
+
"[processSwapBatch] Missing direct from CPFP refund signature for first leaf"
|
|
31894
|
+
);
|
|
31895
|
+
throw new Error("Failed to get direct from CPFP refund signature");
|
|
31896
|
+
}
|
|
31897
|
+
const {
|
|
31898
|
+
adaptorPrivateKey: cpfpAdaptorPrivateKey,
|
|
31899
|
+
adaptorSignature: cpfpAdaptorSignature
|
|
31900
|
+
} = generateAdaptorFromSignature(cpfpRefundSignature);
|
|
31901
|
+
let directAdaptorPrivateKey = new Uint8Array();
|
|
31902
|
+
let directAdaptorSignature = new Uint8Array();
|
|
31903
|
+
let directFromCpfpAdaptorPrivateKey = new Uint8Array();
|
|
31904
|
+
let directFromCpfpAdaptorSignature = new Uint8Array();
|
|
31905
|
+
if (directRefundSignature.length > 0) {
|
|
31906
|
+
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(directRefundSignature);
|
|
31907
|
+
directAdaptorPrivateKey = adaptorPrivateKey;
|
|
31908
|
+
directAdaptorSignature = adaptorSignature;
|
|
31909
|
+
}
|
|
31910
|
+
if (directFromCpfpRefundSignature.length > 0) {
|
|
31911
|
+
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(directFromCpfpRefundSignature);
|
|
31912
|
+
directFromCpfpAdaptorPrivateKey = adaptorPrivateKey;
|
|
31913
|
+
directFromCpfpAdaptorSignature = adaptorSignature;
|
|
30561
31914
|
}
|
|
30562
|
-
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(refundSignature);
|
|
30563
31915
|
if (!transfer.leaves[0].leaf) {
|
|
31916
|
+
console.error(
|
|
31917
|
+
"[processSwapBatch] First leaf missing when preparing user leaves"
|
|
31918
|
+
);
|
|
30564
31919
|
throw new Error("Failed to get leaf");
|
|
30565
31920
|
}
|
|
30566
31921
|
const userLeaves = [];
|
|
@@ -30569,37 +31924,113 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30569
31924
|
raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
30570
31925
|
transfer.leaves[0].intermediateRefundTx
|
|
30571
31926
|
),
|
|
30572
|
-
|
|
31927
|
+
direct_raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
31928
|
+
transfer.leaves[0].intermediateDirectRefundTx
|
|
31929
|
+
),
|
|
31930
|
+
direct_from_cpfp_raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
31931
|
+
transfer.leaves[0].intermediateDirectFromCpfpRefundTx
|
|
31932
|
+
),
|
|
31933
|
+
adaptor_added_signature: (0, import_utils24.bytesToHex)(cpfpAdaptorSignature),
|
|
31934
|
+
direct_adaptor_added_signature: (0, import_utils24.bytesToHex)(directAdaptorSignature),
|
|
31935
|
+
direct_from_cpfp_adaptor_added_signature: (0, import_utils24.bytesToHex)(
|
|
31936
|
+
directFromCpfpAdaptorSignature
|
|
31937
|
+
)
|
|
30573
31938
|
});
|
|
30574
31939
|
for (let i = 1; i < transfer.leaves.length; i++) {
|
|
30575
31940
|
const leaf = transfer.leaves[i];
|
|
30576
31941
|
if (!leaf?.leaf) {
|
|
31942
|
+
console.error(`[processSwapBatch] Leaf ${i + 1} is missing`);
|
|
30577
31943
|
throw new Error("Failed to get leaf");
|
|
30578
31944
|
}
|
|
30579
|
-
const
|
|
30580
|
-
if (!
|
|
30581
|
-
|
|
31945
|
+
const cpfpRefundSignature2 = signatureMap.get(leaf.leaf.id);
|
|
31946
|
+
if (!cpfpRefundSignature2) {
|
|
31947
|
+
console.error(
|
|
31948
|
+
`[processSwapBatch] Missing CPFP refund signature for leaf ${i + 1}`
|
|
31949
|
+
);
|
|
31950
|
+
throw new Error("Failed to get CPFP refund signature");
|
|
31951
|
+
}
|
|
31952
|
+
const directRefundSignature2 = directSignatureMap.get(leaf.leaf.id);
|
|
31953
|
+
if (!directRefundSignature2) {
|
|
31954
|
+
console.error(
|
|
31955
|
+
`[processSwapBatch] Missing direct refund signature for leaf ${i + 1}`
|
|
31956
|
+
);
|
|
31957
|
+
throw new Error("Failed to get direct refund signature");
|
|
31958
|
+
}
|
|
31959
|
+
const directFromCpfpRefundSignature2 = directFromCpfpSignatureMap.get(
|
|
31960
|
+
leaf.leaf.id
|
|
31961
|
+
);
|
|
31962
|
+
if (!directFromCpfpRefundSignature2) {
|
|
31963
|
+
console.error(
|
|
31964
|
+
`[processSwapBatch] Missing direct from CPFP refund signature for leaf ${i + 1}`
|
|
31965
|
+
);
|
|
31966
|
+
throw new Error("Failed to get direct from CPFP refund signature");
|
|
30582
31967
|
}
|
|
30583
|
-
const
|
|
30584
|
-
|
|
30585
|
-
|
|
31968
|
+
const cpfpSignature = generateSignatureFromExistingAdaptor(
|
|
31969
|
+
cpfpRefundSignature2,
|
|
31970
|
+
cpfpAdaptorPrivateKey
|
|
30586
31971
|
);
|
|
31972
|
+
let directSignature = new Uint8Array();
|
|
31973
|
+
if (directRefundSignature2.length > 0) {
|
|
31974
|
+
directSignature = generateSignatureFromExistingAdaptor(
|
|
31975
|
+
directRefundSignature2,
|
|
31976
|
+
directAdaptorPrivateKey
|
|
31977
|
+
);
|
|
31978
|
+
}
|
|
31979
|
+
let directFromCpfpSignature = new Uint8Array();
|
|
31980
|
+
if (directFromCpfpRefundSignature2.length > 0) {
|
|
31981
|
+
directFromCpfpSignature = generateSignatureFromExistingAdaptor(
|
|
31982
|
+
directFromCpfpRefundSignature2,
|
|
31983
|
+
directFromCpfpAdaptorPrivateKey
|
|
31984
|
+
);
|
|
31985
|
+
}
|
|
30587
31986
|
userLeaves.push({
|
|
30588
31987
|
leaf_id: leaf.leaf.id,
|
|
30589
31988
|
raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
30590
31989
|
leaf.intermediateRefundTx
|
|
30591
31990
|
),
|
|
30592
|
-
|
|
31991
|
+
direct_raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
31992
|
+
leaf.intermediateDirectRefundTx
|
|
31993
|
+
),
|
|
31994
|
+
direct_from_cpfp_raw_unsigned_refund_transaction: (0, import_utils24.bytesToHex)(
|
|
31995
|
+
leaf.intermediateDirectFromCpfpRefundTx
|
|
31996
|
+
),
|
|
31997
|
+
adaptor_added_signature: (0, import_utils24.bytesToHex)(cpfpSignature),
|
|
31998
|
+
direct_adaptor_added_signature: (0, import_utils24.bytesToHex)(directSignature),
|
|
31999
|
+
direct_from_cpfp_adaptor_added_signature: (0, import_utils24.bytesToHex)(
|
|
32000
|
+
directFromCpfpSignature
|
|
32001
|
+
)
|
|
30593
32002
|
});
|
|
30594
32003
|
}
|
|
30595
32004
|
const sspClient = this.getSspClient();
|
|
30596
|
-
const
|
|
30597
|
-
import_secp256k115.secp256k1.getPublicKey(
|
|
32005
|
+
const cpfpAdaptorPubkey = (0, import_utils24.bytesToHex)(
|
|
32006
|
+
import_secp256k115.secp256k1.getPublicKey(cpfpAdaptorPrivateKey)
|
|
30598
32007
|
);
|
|
32008
|
+
if (!cpfpAdaptorPubkey) {
|
|
32009
|
+
throw new Error("Failed to generate CPFP adaptor pubkey");
|
|
32010
|
+
}
|
|
32011
|
+
let directAdaptorPubkey;
|
|
32012
|
+
if (directAdaptorPrivateKey.length > 0) {
|
|
32013
|
+
directAdaptorPubkey = (0, import_utils24.bytesToHex)(
|
|
32014
|
+
import_secp256k115.secp256k1.getPublicKey(directAdaptorPrivateKey)
|
|
32015
|
+
);
|
|
32016
|
+
}
|
|
32017
|
+
let directFromCpfpAdaptorPubkey;
|
|
32018
|
+
if (directFromCpfpAdaptorPrivateKey.length > 0) {
|
|
32019
|
+
directFromCpfpAdaptorPubkey = (0, import_utils24.bytesToHex)(
|
|
32020
|
+
import_secp256k115.secp256k1.getPublicKey(directFromCpfpAdaptorPrivateKey)
|
|
32021
|
+
);
|
|
32022
|
+
}
|
|
30599
32023
|
let request = null;
|
|
32024
|
+
const targetAmountSats = targetAmounts?.reduce((acc, amount) => acc + amount, 0) || leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0);
|
|
32025
|
+
const totalAmountSats = leavesBatch.reduce(
|
|
32026
|
+
(acc, leaf) => acc + leaf.value,
|
|
32027
|
+
0
|
|
32028
|
+
);
|
|
30600
32029
|
request = await sspClient.requestLeaveSwap({
|
|
30601
32030
|
userLeaves,
|
|
30602
|
-
adaptorPubkey,
|
|
32031
|
+
adaptorPubkey: cpfpAdaptorPubkey,
|
|
32032
|
+
directAdaptorPubkey,
|
|
32033
|
+
directFromCpfpAdaptorPubkey,
|
|
30603
32034
|
targetAmountSats: targetAmounts?.reduce((acc, amount) => acc + amount, 0) || leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0),
|
|
30604
32035
|
totalAmountSats: leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0),
|
|
30605
32036
|
targetAmountSatsList: targetAmounts,
|
|
@@ -30608,6 +32039,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30608
32039
|
idempotencyKey: (0, import_uuidv75.uuidv7)()
|
|
30609
32040
|
});
|
|
30610
32041
|
if (!request) {
|
|
32042
|
+
console.error("[processSwapBatch] Leave swap request returned null");
|
|
30611
32043
|
throw new Error("Failed to request leaves swap. No response returned.");
|
|
30612
32044
|
}
|
|
30613
32045
|
const nodes = await this.queryNodes({
|
|
@@ -30621,50 +32053,140 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30621
32053
|
network: NetworkToProto[this.config.getNetwork()]
|
|
30622
32054
|
});
|
|
30623
32055
|
if (Object.values(nodes.nodes).length !== request.swapLeaves.length) {
|
|
32056
|
+
console.error("[processSwapBatch] Node count mismatch:", {
|
|
32057
|
+
actual: Object.values(nodes.nodes).length,
|
|
32058
|
+
expected: request.swapLeaves.length
|
|
32059
|
+
});
|
|
30624
32060
|
throw new Error("Expected same number of nodes as swapLeaves");
|
|
30625
32061
|
}
|
|
30626
32062
|
for (const [nodeId, node] of Object.entries(nodes.nodes)) {
|
|
30627
32063
|
if (!node.nodeTx) {
|
|
32064
|
+
console.error(`[processSwapBatch] Node tx missing for ${nodeId}`);
|
|
30628
32065
|
throw new Error(`Node tx not found for leaf ${nodeId}`);
|
|
30629
32066
|
}
|
|
30630
32067
|
if (!node.verifyingPublicKey) {
|
|
32068
|
+
console.error(
|
|
32069
|
+
`[processSwapBatch] Verifying public key missing for ${nodeId}`
|
|
32070
|
+
);
|
|
30631
32071
|
throw new Error(`Node public key not found for leaf ${nodeId}`);
|
|
30632
32072
|
}
|
|
30633
32073
|
const leaf = request.swapLeaves.find((leaf2) => leaf2.leafId === nodeId);
|
|
30634
32074
|
if (!leaf) {
|
|
32075
|
+
console.error(`[processSwapBatch] Leaf not found for node ${nodeId}`);
|
|
30635
32076
|
throw new Error(`Leaf not found for node ${nodeId}`);
|
|
30636
32077
|
}
|
|
30637
|
-
const
|
|
30638
|
-
const
|
|
30639
|
-
const
|
|
30640
|
-
const
|
|
32078
|
+
const cpfpNodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
32079
|
+
const cpfpRefundTxBytes = (0, import_utils24.hexToBytes)(leaf.rawUnsignedRefundTransaction);
|
|
32080
|
+
const cpfpRefundTx = getTxFromRawTxBytes(cpfpRefundTxBytes);
|
|
32081
|
+
const cpfpSighash = getSigHashFromTx(
|
|
32082
|
+
cpfpRefundTx,
|
|
32083
|
+
0,
|
|
32084
|
+
cpfpNodeTx.getOutput(0)
|
|
32085
|
+
);
|
|
30641
32086
|
const nodePublicKey = node.verifyingPublicKey;
|
|
30642
32087
|
const taprootKey = computeTaprootKeyNoScript(nodePublicKey.slice(1));
|
|
30643
|
-
const
|
|
32088
|
+
const cpfpAdaptorSignatureBytes = (0, import_utils24.hexToBytes)(
|
|
32089
|
+
leaf.adaptorSignedSignature
|
|
32090
|
+
);
|
|
32091
|
+
applyAdaptorToSignature(
|
|
32092
|
+
taprootKey.slice(1),
|
|
32093
|
+
cpfpSighash,
|
|
32094
|
+
cpfpAdaptorSignatureBytes,
|
|
32095
|
+
cpfpAdaptorPrivateKey
|
|
32096
|
+
);
|
|
32097
|
+
if (!leaf.directRawUnsignedRefundTransaction) {
|
|
32098
|
+
throw new Error(
|
|
32099
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
32100
|
+
);
|
|
32101
|
+
}
|
|
32102
|
+
if (!leaf.directAdaptorSignedSignature) {
|
|
32103
|
+
throw new Error(
|
|
32104
|
+
`Direct adaptor signed signature missing for node ${nodeId}`
|
|
32105
|
+
);
|
|
32106
|
+
}
|
|
32107
|
+
const directNodeTx = getTxFromRawTxBytes(node.directTx);
|
|
32108
|
+
const directRefundTxBytes = (0, import_utils24.hexToBytes)(
|
|
32109
|
+
leaf.directRawUnsignedRefundTransaction
|
|
32110
|
+
);
|
|
32111
|
+
const directRefundTx = getTxFromRawTxBytes(directRefundTxBytes);
|
|
32112
|
+
const directSighash = getSigHashFromTx(
|
|
32113
|
+
directRefundTx,
|
|
32114
|
+
0,
|
|
32115
|
+
directNodeTx.getOutput(0)
|
|
32116
|
+
);
|
|
32117
|
+
if (!leaf.directFromCpfpAdaptorSignedSignature) {
|
|
32118
|
+
throw new Error(
|
|
32119
|
+
`Direct adaptor signed signature missing for node ${nodeId}`
|
|
32120
|
+
);
|
|
32121
|
+
}
|
|
32122
|
+
const directAdaptorSignatureBytes = (0, import_utils24.hexToBytes)(
|
|
32123
|
+
leaf.directAdaptorSignedSignature
|
|
32124
|
+
);
|
|
32125
|
+
applyAdaptorToSignature(
|
|
32126
|
+
taprootKey.slice(1),
|
|
32127
|
+
directSighash,
|
|
32128
|
+
directAdaptorSignatureBytes,
|
|
32129
|
+
directAdaptorPrivateKey
|
|
32130
|
+
);
|
|
32131
|
+
if (!leaf.directRawUnsignedRefundTransaction) {
|
|
32132
|
+
throw new Error(
|
|
32133
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
32134
|
+
);
|
|
32135
|
+
}
|
|
32136
|
+
if (!leaf.directFromCpfpRawUnsignedRefundTransaction) {
|
|
32137
|
+
throw new Error(
|
|
32138
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
32139
|
+
);
|
|
32140
|
+
}
|
|
32141
|
+
const directFromCpfpRefundTxBytes = (0, import_utils24.hexToBytes)(
|
|
32142
|
+
leaf.directFromCpfpRawUnsignedRefundTransaction
|
|
32143
|
+
);
|
|
32144
|
+
const directFromCpfpRefundTx = getTxFromRawTxBytes(
|
|
32145
|
+
directFromCpfpRefundTxBytes
|
|
32146
|
+
);
|
|
32147
|
+
const directFromCpfpSighash = getSigHashFromTx(
|
|
32148
|
+
directFromCpfpRefundTx,
|
|
32149
|
+
0,
|
|
32150
|
+
cpfpNodeTx.getOutput(0)
|
|
32151
|
+
);
|
|
32152
|
+
const directFromCpfpAdaptorSignatureBytes = (0, import_utils24.hexToBytes)(
|
|
32153
|
+
leaf.directFromCpfpAdaptorSignedSignature
|
|
32154
|
+
);
|
|
30644
32155
|
applyAdaptorToSignature(
|
|
30645
32156
|
taprootKey.slice(1),
|
|
30646
|
-
|
|
30647
|
-
|
|
30648
|
-
|
|
32157
|
+
directFromCpfpSighash,
|
|
32158
|
+
directFromCpfpAdaptorSignatureBytes,
|
|
32159
|
+
directFromCpfpAdaptorPrivateKey
|
|
30649
32160
|
);
|
|
30650
32161
|
}
|
|
30651
32162
|
await this.transferService.deliverTransferPackage(
|
|
30652
32163
|
transfer,
|
|
30653
32164
|
leafKeyTweaks,
|
|
30654
|
-
signatureMap
|
|
32165
|
+
signatureMap,
|
|
32166
|
+
directSignatureMap,
|
|
32167
|
+
directFromCpfpSignatureMap
|
|
30655
32168
|
);
|
|
30656
32169
|
const completeResponse = await sspClient.completeLeaveSwap({
|
|
30657
|
-
adaptorSecretKey: (0, import_utils24.bytesToHex)(
|
|
32170
|
+
adaptorSecretKey: (0, import_utils24.bytesToHex)(cpfpAdaptorPrivateKey),
|
|
32171
|
+
directAdaptorSecretKey: (0, import_utils24.bytesToHex)(directAdaptorPrivateKey),
|
|
32172
|
+
directFromCpfpAdaptorSecretKey: (0, import_utils24.bytesToHex)(
|
|
32173
|
+
directFromCpfpAdaptorPrivateKey
|
|
32174
|
+
),
|
|
30658
32175
|
userOutboundTransferExternalId: transfer.id,
|
|
30659
32176
|
leavesSwapRequestId: request.id
|
|
30660
32177
|
});
|
|
30661
32178
|
if (!completeResponse || !completeResponse.inboundTransfer?.sparkId) {
|
|
32179
|
+
console.error(
|
|
32180
|
+
"[processSwapBatch] Invalid complete response:",
|
|
32181
|
+
completeResponse
|
|
32182
|
+
);
|
|
30662
32183
|
throw new Error("Failed to complete leaves swap");
|
|
30663
32184
|
}
|
|
30664
32185
|
const incomingTransfer = await this.transferService.queryTransfer(
|
|
30665
32186
|
completeResponse.inboundTransfer.sparkId
|
|
30666
32187
|
);
|
|
30667
32188
|
if (!incomingTransfer) {
|
|
32189
|
+
console.error("[processSwapBatch] No incoming transfer found");
|
|
30668
32190
|
throw new Error("Failed to get incoming transfer");
|
|
30669
32191
|
}
|
|
30670
32192
|
return await this.claimTransfer({
|
|
@@ -30674,6 +32196,11 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30674
32196
|
optimize: false
|
|
30675
32197
|
});
|
|
30676
32198
|
} catch (e) {
|
|
32199
|
+
console.error("[processSwapBatch] Error details:", {
|
|
32200
|
+
error: e,
|
|
32201
|
+
message: e.message,
|
|
32202
|
+
stack: e.stack
|
|
32203
|
+
});
|
|
30677
32204
|
await this.cancelAllSenderInitiatedTransfers();
|
|
30678
32205
|
throw new Error(`Failed to request leaves swap: ${e}`);
|
|
30679
32206
|
}
|
|
@@ -31144,8 +32671,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31144
32671
|
field: "txid"
|
|
31145
32672
|
});
|
|
31146
32673
|
}
|
|
32674
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
31147
32675
|
const baseUrl = this.config.getElectrsUrl();
|
|
31148
|
-
const headers =
|
|
32676
|
+
const headers = new Headers2();
|
|
31149
32677
|
let txHex;
|
|
31150
32678
|
if (this.config.getNetwork() === 4 /* LOCAL */) {
|
|
31151
32679
|
const localFaucet = BitcoinFaucet.getInstance();
|
|
@@ -31156,9 +32684,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31156
32684
|
const auth = btoa(
|
|
31157
32685
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
31158
32686
|
);
|
|
31159
|
-
headers
|
|
32687
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
31160
32688
|
}
|
|
31161
|
-
const response = await
|
|
32689
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}/hex`, {
|
|
31162
32690
|
headers
|
|
31163
32691
|
});
|
|
31164
32692
|
txHex = await response.text();
|
|
@@ -31286,8 +32814,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31286
32814
|
this.mutexes.set(txid, mutex);
|
|
31287
32815
|
}
|
|
31288
32816
|
const nodes = await mutex.runExclusive(async () => {
|
|
32817
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
31289
32818
|
const baseUrl = this.config.getElectrsUrl();
|
|
31290
|
-
const headers =
|
|
32819
|
+
const headers = new Headers2();
|
|
31291
32820
|
let txHex;
|
|
31292
32821
|
if (this.config.getNetwork() === 4 /* LOCAL */) {
|
|
31293
32822
|
const localFaucet = BitcoinFaucet.getInstance();
|
|
@@ -31298,9 +32827,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31298
32827
|
const auth = btoa(
|
|
31299
32828
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
31300
32829
|
);
|
|
31301
|
-
headers
|
|
32830
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
31302
32831
|
}
|
|
31303
|
-
const response = await
|
|
32832
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}/hex`, {
|
|
31304
32833
|
headers
|
|
31305
32834
|
});
|
|
31306
32835
|
txHex = await response.text();
|
|
@@ -31542,10 +33071,16 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31542
33071
|
const validNodes = [];
|
|
31543
33072
|
for (const node of nodes) {
|
|
31544
33073
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
31545
|
-
const
|
|
31546
|
-
|
|
31547
|
-
|
|
31548
|
-
|
|
33074
|
+
const sequence = nodeTx.getInput(0).sequence;
|
|
33075
|
+
if (!sequence) {
|
|
33076
|
+
throw new ValidationError("Invalid node transaction", {
|
|
33077
|
+
field: "sequence",
|
|
33078
|
+
value: nodeTx.getInput(0),
|
|
33079
|
+
expected: "Non-null sequence"
|
|
33080
|
+
});
|
|
33081
|
+
}
|
|
33082
|
+
const needsRefresh = doesLeafNeedRefresh(sequence, true);
|
|
33083
|
+
if (needsRefresh) {
|
|
31549
33084
|
nodesToExtend.push(node);
|
|
31550
33085
|
nodeIds.push(node.id);
|
|
31551
33086
|
} else {
|
|
@@ -31582,11 +33117,16 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31582
33117
|
const validNodes = [];
|
|
31583
33118
|
for (const node of nodes) {
|
|
31584
33119
|
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
31585
|
-
const
|
|
31586
|
-
|
|
31587
|
-
|
|
31588
|
-
|
|
31589
|
-
|
|
33120
|
+
const sequence = refundTx.getInput(0).sequence;
|
|
33121
|
+
if (!sequence) {
|
|
33122
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
33123
|
+
field: "sequence",
|
|
33124
|
+
value: refundTx.getInput(0),
|
|
33125
|
+
expected: "Non-null sequence"
|
|
33126
|
+
});
|
|
33127
|
+
}
|
|
33128
|
+
const needsRefresh = doesLeafNeedRefresh(sequence);
|
|
33129
|
+
if (needsRefresh) {
|
|
31590
33130
|
nodesToRefresh.push(node);
|
|
31591
33131
|
nodeIds.push(node.id);
|
|
31592
33132
|
} else {
|
|
@@ -31620,7 +33160,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31620
33160
|
throw new Error(`parent node ${node.parentNodeId} not found`);
|
|
31621
33161
|
}
|
|
31622
33162
|
const { nodes: nodes2 } = await this.transferService.refreshTimelockNodes(
|
|
31623
|
-
|
|
33163
|
+
node,
|
|
31624
33164
|
parentNode
|
|
31625
33165
|
);
|
|
31626
33166
|
if (nodes2.length !== 1) {
|
|
@@ -31669,7 +33209,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31669
33209
|
leavesToClaim.push({
|
|
31670
33210
|
leaf: {
|
|
31671
33211
|
...leaf.leaf,
|
|
31672
|
-
refundTx: leaf.intermediateRefundTx
|
|
33212
|
+
refundTx: leaf.intermediateRefundTx,
|
|
33213
|
+
directRefundTx: leaf.intermediateDirectRefundTx,
|
|
33214
|
+
directFromCpfpRefundTx: leaf.intermediateDirectFromCpfpRefundTx
|
|
31673
33215
|
},
|
|
31674
33216
|
keyDerivation: {
|
|
31675
33217
|
type: "ecies" /* ECIES */,
|
|
@@ -31745,7 +33287,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31745
33287
|
if (type && transfer.type !== type) {
|
|
31746
33288
|
continue;
|
|
31747
33289
|
}
|
|
31748
|
-
if (transfer.status !== 2 /* TRANSFER_STATUS_SENDER_KEY_TWEAKED */ && transfer.status !== 3 /* TRANSFER_STATUS_RECEIVER_KEY_TWEAKED */ && transfer.status !== 4 /* TRANSFER_STATUS_RECEIVER_REFUND_SIGNED */ && transfer.status !== 10 /* TRANSFER_STATUS_RECEIVER_KEY_TWEAK_APPLIED */) {
|
|
33290
|
+
if (transfer.status !== 2 /* TRANSFER_STATUS_SENDER_KEY_TWEAKED */ && transfer.status !== 3 /* TRANSFER_STATUS_RECEIVER_KEY_TWEAKED */ && transfer.status !== 4 /* TRANSFER_STATUS_RECEIVER_REFUND_SIGNED */ && transfer.status !== 10 /* TRANSFER_STATUS_RECEIVER_KEY_TWEAK_APPLIED */ && transfer.status !== 9 /* TRANSFER_STATUS_RECEIVER_KEY_TWEAK_LOCKED */) {
|
|
31749
33291
|
continue;
|
|
31750
33292
|
}
|
|
31751
33293
|
promises.push(
|
|
@@ -32033,6 +33575,8 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
32033
33575
|
await this.transferService.deliverTransferPackage(
|
|
32034
33576
|
swapResponse.transfer,
|
|
32035
33577
|
leavesToSend,
|
|
33578
|
+
/* @__PURE__ */ new Map(),
|
|
33579
|
+
/* @__PURE__ */ new Map(),
|
|
32036
33580
|
/* @__PURE__ */ new Map()
|
|
32037
33581
|
);
|
|
32038
33582
|
const sspResponse = await sspClient.requestLightningSend({
|
|
@@ -32795,87 +34339,64 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
32795
34339
|
},
|
|
32796
34340
|
includeParents: true
|
|
32797
34341
|
});
|
|
32798
|
-
|
|
32799
|
-
if (!
|
|
34342
|
+
let leaf = response.nodes[nodeId];
|
|
34343
|
+
if (!leaf) {
|
|
32800
34344
|
throw new ValidationError("Node not found", {
|
|
32801
34345
|
field: "nodeId",
|
|
32802
34346
|
value: nodeId
|
|
32803
34347
|
});
|
|
32804
34348
|
}
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
32809
|
-
|
|
32810
|
-
|
|
32811
|
-
|
|
32812
|
-
|
|
32813
|
-
|
|
32814
|
-
|
|
32815
|
-
|
|
32816
|
-
});
|
|
32817
|
-
}
|
|
32818
|
-
const result = await this.transferService.refreshTimelockNodes(
|
|
32819
|
-
[node],
|
|
32820
|
-
parentNode
|
|
32821
|
-
);
|
|
32822
|
-
const leafIndex = this.leaves.findIndex((leaf) => leaf.id === node.id);
|
|
32823
|
-
if (leafIndex !== -1 && result.nodes.length > 0) {
|
|
32824
|
-
const newNode = result.nodes[0];
|
|
32825
|
-
if (newNode) {
|
|
32826
|
-
this.leaves[leafIndex] = newNode;
|
|
34349
|
+
let parentNode;
|
|
34350
|
+
let hasParentNode = false;
|
|
34351
|
+
if (!leaf.parentNodeId) {
|
|
34352
|
+
} else {
|
|
34353
|
+
hasParentNode = true;
|
|
34354
|
+
parentNode = response.nodes[leaf.parentNodeId];
|
|
34355
|
+
if (!parentNode) {
|
|
34356
|
+
throw new ValidationError("Parent node not found", {
|
|
34357
|
+
field: "parentNodeId",
|
|
34358
|
+
value: leaf.parentNodeId
|
|
34359
|
+
});
|
|
32827
34360
|
}
|
|
32828
34361
|
}
|
|
32829
|
-
|
|
32830
|
-
|
|
32831
|
-
|
|
32832
|
-
|
|
32833
|
-
|
|
32834
|
-
|
|
32835
|
-
|
|
32836
|
-
|
|
32837
|
-
|
|
32838
|
-
|
|
32839
|
-
|
|
32840
|
-
|
|
32841
|
-
|
|
32842
|
-
|
|
32843
|
-
* @returns {Promise<void>} Promise that resolves when the refund timelock is refreshed
|
|
32844
|
-
*/
|
|
32845
|
-
async testOnly_expireTimelockRefundTx(nodeId) {
|
|
32846
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
32847
|
-
this.config.getCoordinatorAddress()
|
|
32848
|
-
);
|
|
32849
|
-
try {
|
|
32850
|
-
const response = await sparkClient.query_nodes({
|
|
32851
|
-
source: {
|
|
32852
|
-
$case: "nodeIds",
|
|
32853
|
-
nodeIds: {
|
|
32854
|
-
nodeIds: [nodeId]
|
|
34362
|
+
const nodeTx = getTxFromRawTxBytes(leaf.nodeTx);
|
|
34363
|
+
const refundTx = getTxFromRawTxBytes(leaf.refundTx);
|
|
34364
|
+
if (hasParentNode) {
|
|
34365
|
+
const nodeTimelock = getCurrentTimelock(nodeTx.getInput(0).sequence);
|
|
34366
|
+
if (nodeTimelock > 100) {
|
|
34367
|
+
const expiredNodeTxLeaf = await this.transferService.testonly_expireTimeLockNodeTx(
|
|
34368
|
+
leaf,
|
|
34369
|
+
parentNode
|
|
34370
|
+
);
|
|
34371
|
+
if (!expiredNodeTxLeaf.nodes[0]) {
|
|
34372
|
+
throw new ValidationError("No expired node tx leaf", {
|
|
34373
|
+
field: "expiredNodeTxLeaf",
|
|
34374
|
+
value: expiredNodeTxLeaf
|
|
34375
|
+
});
|
|
32855
34376
|
}
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
});
|
|
32859
|
-
const node = response.nodes[nodeId];
|
|
32860
|
-
if (!node) {
|
|
32861
|
-
throw new ValidationError("Node not found", {
|
|
32862
|
-
field: "nodeId",
|
|
32863
|
-
value: nodeId
|
|
32864
|
-
});
|
|
34377
|
+
leaf = expiredNodeTxLeaf.nodes[0];
|
|
34378
|
+
}
|
|
32865
34379
|
}
|
|
32866
|
-
const
|
|
32867
|
-
|
|
32868
|
-
|
|
32869
|
-
|
|
32870
|
-
|
|
32871
|
-
|
|
34380
|
+
const refundTimelock = getCurrentTimelock(refundTx.getInput(0).sequence);
|
|
34381
|
+
if (refundTimelock > 100) {
|
|
34382
|
+
const expiredTxLeaf = await this.transferService.testonly_expireTimeLockRefundtx(leaf);
|
|
34383
|
+
if (!expiredTxLeaf.nodes[0]) {
|
|
34384
|
+
throw new ValidationError("No expired tx leaf", {
|
|
34385
|
+
field: "expiredTxLeaf",
|
|
34386
|
+
value: expiredTxLeaf
|
|
34387
|
+
});
|
|
32872
34388
|
}
|
|
34389
|
+
leaf = expiredTxLeaf.nodes[0];
|
|
34390
|
+
}
|
|
34391
|
+
const leafIndex = this.leaves.findIndex((leaf2) => leaf2.id === leaf2.id);
|
|
34392
|
+
if (leafIndex !== -1) {
|
|
34393
|
+
this.leaves[leafIndex] = leaf;
|
|
32873
34394
|
}
|
|
32874
34395
|
} catch (error) {
|
|
32875
34396
|
throw new NetworkError(
|
|
32876
|
-
"Failed to refresh
|
|
34397
|
+
"Failed to refresh timelock",
|
|
32877
34398
|
{
|
|
32878
|
-
method: "
|
|
34399
|
+
method: "refresh_timelock"
|
|
32879
34400
|
},
|
|
32880
34401
|
error
|
|
32881
34402
|
);
|
|
@@ -32935,6 +34456,106 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
32935
34456
|
}
|
|
32936
34457
|
};
|
|
32937
34458
|
|
|
34459
|
+
// src/spark-wallet/spark-wallet.node.ts
|
|
34460
|
+
var import_core13 = require("@lightsparkdev/core");
|
|
34461
|
+
var SparkWallet2 = class extends SparkWallet {
|
|
34462
|
+
tracer = null;
|
|
34463
|
+
wrapWithOtelSpan(name, fn) {
|
|
34464
|
+
return async (...args) => {
|
|
34465
|
+
if (!this.tracer) {
|
|
34466
|
+
throw new Error("Tracer not initialized");
|
|
34467
|
+
}
|
|
34468
|
+
return await this.tracer.startActiveSpan(name, async (span) => {
|
|
34469
|
+
const traceId = span.spanContext().traceId;
|
|
34470
|
+
try {
|
|
34471
|
+
const result = await fn(...args);
|
|
34472
|
+
return result;
|
|
34473
|
+
} catch (error) {
|
|
34474
|
+
if (error instanceof Error) {
|
|
34475
|
+
error.message += ` [traceId: ${traceId}]`;
|
|
34476
|
+
} else if ((0, import_core13.isObject)(error)) {
|
|
34477
|
+
error["traceId"] = traceId;
|
|
34478
|
+
}
|
|
34479
|
+
throw error;
|
|
34480
|
+
} finally {
|
|
34481
|
+
span.end();
|
|
34482
|
+
}
|
|
34483
|
+
});
|
|
34484
|
+
};
|
|
34485
|
+
}
|
|
34486
|
+
async initializeTracer(tracerName) {
|
|
34487
|
+
const { trace, propagation, context } = await import("@opentelemetry/api");
|
|
34488
|
+
const { W3CTraceContextPropagator } = await import("@opentelemetry/core");
|
|
34489
|
+
const { AsyncLocalStorageContextManager } = await import("@opentelemetry/context-async-hooks");
|
|
34490
|
+
const { BasicTracerProvider } = await import("@opentelemetry/sdk-trace-base");
|
|
34491
|
+
trace.setGlobalTracerProvider(new BasicTracerProvider());
|
|
34492
|
+
propagation.setGlobalPropagator(new W3CTraceContextPropagator());
|
|
34493
|
+
context.setGlobalContextManager(new AsyncLocalStorageContextManager());
|
|
34494
|
+
this.tracer = trace.getTracer(tracerName);
|
|
34495
|
+
}
|
|
34496
|
+
getTraceName(methodName) {
|
|
34497
|
+
return `SparkWallet.${methodName}`;
|
|
34498
|
+
}
|
|
34499
|
+
wrapPublicMethodsWithOtelSpan(methodName) {
|
|
34500
|
+
const original = this[methodName];
|
|
34501
|
+
if (typeof original !== "function") {
|
|
34502
|
+
throw new Error(`Method ${methodName} is not a function on SparkWallet.`);
|
|
34503
|
+
}
|
|
34504
|
+
const wrapped = this.wrapWithOtelSpan(
|
|
34505
|
+
this.getTraceName(methodName),
|
|
34506
|
+
original.bind(this)
|
|
34507
|
+
);
|
|
34508
|
+
this[methodName] = wrapped;
|
|
34509
|
+
}
|
|
34510
|
+
wrapSparkWalletWithTracing() {
|
|
34511
|
+
const methods = [
|
|
34512
|
+
"getLeaves",
|
|
34513
|
+
"getIdentityPublicKey",
|
|
34514
|
+
"getSparkAddress",
|
|
34515
|
+
"createSparkPaymentIntent",
|
|
34516
|
+
"getSwapFeeEstimate",
|
|
34517
|
+
"getTransfers",
|
|
34518
|
+
"getBalance",
|
|
34519
|
+
"getSingleUseDepositAddress",
|
|
34520
|
+
"getStaticDepositAddress",
|
|
34521
|
+
"queryStaticDepositAddresses",
|
|
34522
|
+
"getClaimStaticDepositQuote",
|
|
34523
|
+
"claimStaticDeposit",
|
|
34524
|
+
"refundStaticDeposit",
|
|
34525
|
+
"getUnusedDepositAddresses",
|
|
34526
|
+
"claimDeposit",
|
|
34527
|
+
"advancedDeposit",
|
|
34528
|
+
"transfer",
|
|
34529
|
+
"createLightningInvoice",
|
|
34530
|
+
"payLightningInvoice",
|
|
34531
|
+
"getLightningSendFeeEstimate",
|
|
34532
|
+
"withdraw",
|
|
34533
|
+
"getWithdrawalFeeQuote",
|
|
34534
|
+
"getTransferFromSsp",
|
|
34535
|
+
"getTransfer",
|
|
34536
|
+
"transferTokens",
|
|
34537
|
+
"batchTransferTokens",
|
|
34538
|
+
"queryTokenTransactions",
|
|
34539
|
+
"getLightningReceiveRequest",
|
|
34540
|
+
"getLightningSendRequest",
|
|
34541
|
+
"getCoopExitRequest",
|
|
34542
|
+
"checkTimelock",
|
|
34543
|
+
"testOnly_expireTimelock"
|
|
34544
|
+
];
|
|
34545
|
+
methods.forEach((m) => this.wrapPublicMethodsWithOtelSpan(m));
|
|
34546
|
+
this.initWallet = this.wrapWithOtelSpan(
|
|
34547
|
+
this.getTraceName("initWallet"),
|
|
34548
|
+
this.initWallet.bind(this)
|
|
34549
|
+
);
|
|
34550
|
+
}
|
|
34551
|
+
async initWallet(mnemonicOrSeed, accountNumber) {
|
|
34552
|
+
const res = super.initWallet(mnemonicOrSeed, accountNumber);
|
|
34553
|
+
await this.initializeTracer(this.tracerId);
|
|
34554
|
+
this.wrapSparkWalletWithTracing();
|
|
34555
|
+
return res;
|
|
34556
|
+
}
|
|
34557
|
+
};
|
|
34558
|
+
|
|
32938
34559
|
// src/spark-wallet/types.ts
|
|
32939
34560
|
init_buffer();
|
|
32940
34561
|
|
|
@@ -32946,7 +34567,10 @@ setCrypto(cryptoImpl2);
|
|
|
32946
34567
|
AuthenticationError,
|
|
32947
34568
|
ConfigurationError,
|
|
32948
34569
|
DEFAULT_FEE_SATS,
|
|
34570
|
+
DIRECT_TIMELOCK_OFFSET,
|
|
32949
34571
|
DefaultSparkSigner,
|
|
34572
|
+
INITIAL_DIRECT_SEQUENCE,
|
|
34573
|
+
INITIAL_SEQUENCE,
|
|
32950
34574
|
InternalValidationError,
|
|
32951
34575
|
KeyDerivationType,
|
|
32952
34576
|
LRC_WALLET_NETWORK,
|
|
@@ -32959,6 +34583,8 @@ setCrypto(cryptoImpl2);
|
|
|
32959
34583
|
RPCError,
|
|
32960
34584
|
SparkSDKError,
|
|
32961
34585
|
SparkWallet,
|
|
34586
|
+
TEST_UNILATERAL_DIRECT_SEQUENCE,
|
|
34587
|
+
TEST_UNILATERAL_SEQUENCE,
|
|
32962
34588
|
TaprootOutputKeysGenerator,
|
|
32963
34589
|
TaprootSparkSigner,
|
|
32964
34590
|
TokenTransactionService,
|
|
@@ -32978,13 +34604,21 @@ setCrypto(cryptoImpl2);
|
|
|
32978
34604
|
constructFeeBumpTx,
|
|
32979
34605
|
constructUnilateralExitFeeBumpPackages,
|
|
32980
34606
|
constructUnilateralExitTxs,
|
|
34607
|
+
createConnectorRefundTransactions,
|
|
34608
|
+
createLeafNodeTx,
|
|
34609
|
+
createNodeTx,
|
|
34610
|
+
createNodeTxs,
|
|
32981
34611
|
createRefundTx,
|
|
34612
|
+
createRefundTxs,
|
|
34613
|
+
createRootTx,
|
|
32982
34614
|
createSigningCommitment,
|
|
32983
34615
|
createSigningNonce,
|
|
34616
|
+
createSplitTx,
|
|
32984
34617
|
decodeBech32mTokenIdentifier,
|
|
32985
34618
|
decodeBytesToSigningCommitment,
|
|
32986
34619
|
decodeBytesToSigningNonce,
|
|
32987
34620
|
decodeSparkAddress,
|
|
34621
|
+
doesLeafNeedRefresh,
|
|
32988
34622
|
encodeBech32mTokenIdentifier,
|
|
32989
34623
|
encodeSigningCommitmentToBytes,
|
|
32990
34624
|
encodeSigningNonceToBytes,
|