@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/debug.cjs
CHANGED
|
@@ -1826,7 +1826,11 @@ var SwapLeafFromJson = (obj) => {
|
|
|
1826
1826
|
return {
|
|
1827
1827
|
leafId: obj["swap_leaf_leaf_id"],
|
|
1828
1828
|
rawUnsignedRefundTransaction: obj["swap_leaf_raw_unsigned_refund_transaction"],
|
|
1829
|
-
adaptorSignedSignature: obj["swap_leaf_adaptor_signed_signature"]
|
|
1829
|
+
adaptorSignedSignature: obj["swap_leaf_adaptor_signed_signature"],
|
|
1830
|
+
directRawUnsignedRefundTransaction: obj["swap_leaf_direct_raw_unsigned_refund_transaction"],
|
|
1831
|
+
directAdaptorSignedSignature: obj["swap_leaf_direct_adaptor_signed_signature"],
|
|
1832
|
+
directFromCpfpRawUnsignedRefundTransaction: obj["swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction"],
|
|
1833
|
+
directFromCpfpAdaptorSignedSignature: obj["swap_leaf_direct_from_cpfp_adaptor_signed_signature"]
|
|
1830
1834
|
};
|
|
1831
1835
|
};
|
|
1832
1836
|
|
|
@@ -1924,6 +1928,10 @@ fragment LeavesSwapRequestFragment on LeavesSwapRequest {
|
|
|
1924
1928
|
swap_leaf_leaf_id: leaf_id
|
|
1925
1929
|
swap_leaf_raw_unsigned_refund_transaction: raw_unsigned_refund_transaction
|
|
1926
1930
|
swap_leaf_adaptor_signed_signature: adaptor_signed_signature
|
|
1931
|
+
swap_leaf_direct_raw_unsigned_refund_transaction: direct_raw_unsigned_refund_transaction
|
|
1932
|
+
swap_leaf_direct_adaptor_signed_signature: direct_adaptor_signed_signature
|
|
1933
|
+
swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction: direct_from_cpfp_raw_unsigned_refund_transaction
|
|
1934
|
+
swap_leaf_direct_from_cpfp_adaptor_signed_signature: direct_from_cpfp_adaptor_signed_signature
|
|
1927
1935
|
}
|
|
1928
1936
|
}`;
|
|
1929
1937
|
|
|
@@ -1931,10 +1939,18 @@ fragment LeavesSwapRequestFragment on LeavesSwapRequest {
|
|
|
1931
1939
|
var CompleteLeavesSwap = `
|
|
1932
1940
|
mutation CompleteLeavesSwap(
|
|
1933
1941
|
$adaptor_secret_key: String!
|
|
1942
|
+
$direct_adaptor_secret_key: String!
|
|
1943
|
+
$direct_from_cpfp_adaptor_secret_key: String!
|
|
1934
1944
|
$user_outbound_transfer_external_id: UUID!
|
|
1935
1945
|
$leaves_swap_request_id: ID!
|
|
1936
1946
|
) {
|
|
1937
|
-
complete_leaves_swap(input: {
|
|
1947
|
+
complete_leaves_swap(input: {
|
|
1948
|
+
adaptor_secret_key: $adaptor_secret_key,
|
|
1949
|
+
direct_adaptor_secret_key: $direct_adaptor_secret_key,
|
|
1950
|
+
direct_from_cpfp_adaptor_secret_key: $direct_from_cpfp_adaptor_secret_key,
|
|
1951
|
+
user_outbound_transfer_external_id: $user_outbound_transfer_external_id,
|
|
1952
|
+
leaves_swap_request_id: $leaves_swap_request_id
|
|
1953
|
+
}) {
|
|
1938
1954
|
request {
|
|
1939
1955
|
...LeavesSwapRequestFragment
|
|
1940
1956
|
}
|
|
@@ -2235,6 +2251,8 @@ init_buffer();
|
|
|
2235
2251
|
var RequestSwapLeaves = `
|
|
2236
2252
|
mutation RequestSwapLeaves(
|
|
2237
2253
|
$adaptor_pubkey: PublicKey!
|
|
2254
|
+
$direct_adaptor_pubkey: PublicKey
|
|
2255
|
+
$direct_from_cpfp_adaptor_pubkey: PublicKey
|
|
2238
2256
|
$total_amount_sats: Long!
|
|
2239
2257
|
$target_amount_sats: Long!
|
|
2240
2258
|
$fee_sats: Long!
|
|
@@ -2244,6 +2262,8 @@ var RequestSwapLeaves = `
|
|
|
2244
2262
|
) {
|
|
2245
2263
|
request_leaves_swap(input: {
|
|
2246
2264
|
adaptor_pubkey: $adaptor_pubkey
|
|
2265
|
+
direct_adaptor_pubkey: $direct_adaptor_pubkey
|
|
2266
|
+
direct_from_cpfp_adaptor_pubkey: $direct_from_cpfp_adaptor_pubkey
|
|
2247
2267
|
total_amount_sats: $total_amount_sats
|
|
2248
2268
|
target_amount_sats: $target_amount_sats
|
|
2249
2269
|
fee_sats: $fee_sats
|
|
@@ -2815,6 +2835,10 @@ fragment UserRequestFragment on UserRequest {
|
|
|
2815
2835
|
swap_leaf_leaf_id: leaf_id
|
|
2816
2836
|
swap_leaf_raw_unsigned_refund_transaction: raw_unsigned_refund_transaction
|
|
2817
2837
|
swap_leaf_adaptor_signed_signature: adaptor_signed_signature
|
|
2838
|
+
swap_leaf_direct_raw_unsigned_refund_transaction: direct_raw_unsigned_refund_transaction
|
|
2839
|
+
swap_leaf_direct_adaptor_signed_signature: direct_adaptor_signed_signature
|
|
2840
|
+
swap_leaf_direct_from_cpfp_raw_unsigned_refund_transaction: direct_from_cpfp_raw_unsigned_refund_transaction
|
|
2841
|
+
swap_leaf_direct_from_cpfp_adaptor_signed_signature: direct_from_cpfp_adaptor_signed_signature
|
|
2818
2842
|
}
|
|
2819
2843
|
}
|
|
2820
2844
|
... on LightningReceiveRequest {
|
|
@@ -3097,6 +3121,8 @@ var SspClient = class {
|
|
|
3097
3121
|
}
|
|
3098
3122
|
async requestLeaveSwap({
|
|
3099
3123
|
adaptorPubkey,
|
|
3124
|
+
directAdaptorPubkey,
|
|
3125
|
+
directFromCpfpAdaptorPubkey,
|
|
3100
3126
|
totalAmountSats,
|
|
3101
3127
|
targetAmountSats,
|
|
3102
3128
|
feeSats,
|
|
@@ -3108,6 +3134,8 @@ var SspClient = class {
|
|
|
3108
3134
|
queryPayload: RequestSwapLeaves,
|
|
3109
3135
|
variables: {
|
|
3110
3136
|
adaptor_pubkey: adaptorPubkey,
|
|
3137
|
+
direct_adaptor_pubkey: directAdaptorPubkey,
|
|
3138
|
+
direct_from_cpfp_adaptor_pubkey: directFromCpfpAdaptorPubkey,
|
|
3111
3139
|
total_amount_sats: totalAmountSats,
|
|
3112
3140
|
target_amount_sats: targetAmountSats,
|
|
3113
3141
|
fee_sats: feeSats,
|
|
@@ -3126,6 +3154,8 @@ var SspClient = class {
|
|
|
3126
3154
|
}
|
|
3127
3155
|
async completeLeaveSwap({
|
|
3128
3156
|
adaptorSecretKey,
|
|
3157
|
+
directAdaptorSecretKey,
|
|
3158
|
+
directFromCpfpAdaptorSecretKey,
|
|
3129
3159
|
userOutboundTransferExternalId,
|
|
3130
3160
|
leavesSwapRequestId
|
|
3131
3161
|
}) {
|
|
@@ -3133,6 +3163,8 @@ var SspClient = class {
|
|
|
3133
3163
|
queryPayload: CompleteLeavesSwap,
|
|
3134
3164
|
variables: {
|
|
3135
3165
|
adaptor_secret_key: adaptorSecretKey,
|
|
3166
|
+
direct_adaptor_secret_key: directAdaptorSecretKey,
|
|
3167
|
+
direct_from_cpfp_adaptor_secret_key: directFromCpfpAdaptorSecretKey,
|
|
3136
3168
|
user_outbound_transfer_external_id: userOutboundTransferExternalId,
|
|
3137
3169
|
leaves_swap_request_id: leavesSwapRequestId
|
|
3138
3170
|
},
|
|
@@ -17948,7 +17980,7 @@ init_buffer();
|
|
|
17948
17980
|
var import_core10 = require("@lightsparkdev/core");
|
|
17949
17981
|
var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
|
|
17950
17982
|
var isBun = globalThis.Bun !== void 0;
|
|
17951
|
-
var packageVersion = true ? "0.2.
|
|
17983
|
+
var packageVersion = true ? "0.2.4" : "unknown";
|
|
17952
17984
|
var baseEnvStr = "unknown";
|
|
17953
17985
|
if (isBun) {
|
|
17954
17986
|
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
@@ -23174,7 +23206,14 @@ function getTxIdNoReverse(tx) {
|
|
|
23174
23206
|
// src/utils/transaction.ts
|
|
23175
23207
|
init_buffer();
|
|
23176
23208
|
var import_btc_signer = require("@scure/btc-signer");
|
|
23209
|
+
var INITIAL_TIMELOCK = 2e3;
|
|
23210
|
+
var TEST_UNILATERAL_TIMELOCK = 100;
|
|
23177
23211
|
var TIME_LOCK_INTERVAL = 100;
|
|
23212
|
+
var DIRECT_TIMELOCK_OFFSET = 50;
|
|
23213
|
+
var INITIAL_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK;
|
|
23214
|
+
var INITIAL_DIRECT_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
23215
|
+
var TEST_UNILATERAL_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK;
|
|
23216
|
+
var TEST_UNILATERAL_DIRECT_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
23178
23217
|
var ESTIMATED_TX_SIZE = 191;
|
|
23179
23218
|
var DEFAULT_SATS_PER_VBYTE = 5;
|
|
23180
23219
|
var DEFAULT_FEE_SATS = ESTIMATED_TX_SIZE * DEFAULT_SATS_PER_VBYTE;
|
|
@@ -23184,29 +23223,270 @@ function maybeApplyFee(amount) {
|
|
|
23184
23223
|
}
|
|
23185
23224
|
return amount;
|
|
23186
23225
|
}
|
|
23187
|
-
function
|
|
23188
|
-
const
|
|
23226
|
+
function createRootTx(depositOutPoint, depositTxOut) {
|
|
23227
|
+
const cpfpRootTx = new import_btc_signer.Transaction({
|
|
23228
|
+
version: 3,
|
|
23229
|
+
allowUnknownOutputs: true
|
|
23230
|
+
});
|
|
23231
|
+
cpfpRootTx.addInput(depositOutPoint);
|
|
23232
|
+
cpfpRootTx.addOutput(depositTxOut);
|
|
23233
|
+
cpfpRootTx.addOutput(getEphemeralAnchorOutput());
|
|
23234
|
+
const directRootTx = new import_btc_signer.Transaction({
|
|
23235
|
+
version: 3,
|
|
23236
|
+
allowUnknownOutputs: true
|
|
23237
|
+
});
|
|
23238
|
+
directRootTx.addInput(depositOutPoint);
|
|
23239
|
+
directRootTx.addOutput({
|
|
23240
|
+
script: depositTxOut.script,
|
|
23241
|
+
amount: maybeApplyFee(depositTxOut.amount ?? 0n)
|
|
23242
|
+
});
|
|
23243
|
+
return [cpfpRootTx, directRootTx];
|
|
23244
|
+
}
|
|
23245
|
+
function createSplitTx(parentOutPoint, childTxOuts) {
|
|
23246
|
+
const cpfpSplitTx = new import_btc_signer.Transaction({
|
|
23247
|
+
version: 3,
|
|
23248
|
+
allowUnknownOutputs: true
|
|
23249
|
+
});
|
|
23250
|
+
cpfpSplitTx.addInput(parentOutPoint);
|
|
23251
|
+
for (const txOut of childTxOuts) {
|
|
23252
|
+
cpfpSplitTx.addOutput(txOut);
|
|
23253
|
+
}
|
|
23254
|
+
cpfpSplitTx.addOutput(getEphemeralAnchorOutput());
|
|
23255
|
+
const directSplitTx = new import_btc_signer.Transaction({
|
|
23256
|
+
version: 3,
|
|
23257
|
+
allowUnknownOutputs: true
|
|
23258
|
+
});
|
|
23259
|
+
directSplitTx.addInput(parentOutPoint);
|
|
23260
|
+
let totalOutputAmount = 0n;
|
|
23261
|
+
for (const txOut of childTxOuts) {
|
|
23262
|
+
totalOutputAmount += txOut.amount ?? 0n;
|
|
23263
|
+
}
|
|
23264
|
+
if (totalOutputAmount > BigInt(DEFAULT_FEE_SATS)) {
|
|
23265
|
+
const feeRatio = Number(DEFAULT_FEE_SATS) / Number(totalOutputAmount);
|
|
23266
|
+
for (const txOut of childTxOuts) {
|
|
23267
|
+
const adjustedAmount = BigInt(
|
|
23268
|
+
Math.floor(Number(txOut.amount ?? 0n) * (1 - feeRatio))
|
|
23269
|
+
);
|
|
23270
|
+
directSplitTx.addOutput({
|
|
23271
|
+
script: txOut.script,
|
|
23272
|
+
amount: adjustedAmount
|
|
23273
|
+
});
|
|
23274
|
+
}
|
|
23275
|
+
} else {
|
|
23276
|
+
for (const txOut of childTxOuts) {
|
|
23277
|
+
directSplitTx.addOutput(txOut);
|
|
23278
|
+
}
|
|
23279
|
+
}
|
|
23280
|
+
return [cpfpSplitTx, directSplitTx];
|
|
23281
|
+
}
|
|
23282
|
+
function createNodeTx({
|
|
23283
|
+
txOut,
|
|
23284
|
+
parentOutPoint,
|
|
23285
|
+
applyFee,
|
|
23286
|
+
includeAnchor
|
|
23287
|
+
}) {
|
|
23288
|
+
const nodeTx = new import_btc_signer.Transaction({
|
|
23289
|
+
version: 3,
|
|
23290
|
+
allowUnknownOutputs: true
|
|
23291
|
+
});
|
|
23292
|
+
nodeTx.addInput(parentOutPoint);
|
|
23293
|
+
if (applyFee) {
|
|
23294
|
+
nodeTx.addOutput({
|
|
23295
|
+
script: txOut.script,
|
|
23296
|
+
amount: maybeApplyFee(txOut.amount ?? 0n)
|
|
23297
|
+
});
|
|
23298
|
+
} else {
|
|
23299
|
+
nodeTx.addOutput(txOut);
|
|
23300
|
+
}
|
|
23301
|
+
if (includeAnchor) {
|
|
23302
|
+
nodeTx.addOutput(getEphemeralAnchorOutput());
|
|
23303
|
+
}
|
|
23304
|
+
return nodeTx;
|
|
23305
|
+
}
|
|
23306
|
+
function createNodeTxs(txOut, txIn, directTxIn) {
|
|
23307
|
+
const cpfpNodeTx = createNodeTx({
|
|
23308
|
+
txOut,
|
|
23309
|
+
parentOutPoint: txIn,
|
|
23310
|
+
includeAnchor: true
|
|
23311
|
+
});
|
|
23312
|
+
let directNodeTx;
|
|
23313
|
+
if (directTxIn) {
|
|
23314
|
+
directNodeTx = createNodeTx({
|
|
23315
|
+
txOut,
|
|
23316
|
+
parentOutPoint: directTxIn,
|
|
23317
|
+
includeAnchor: false,
|
|
23318
|
+
applyFee: true
|
|
23319
|
+
});
|
|
23320
|
+
}
|
|
23321
|
+
return { cpfpNodeTx, directNodeTx };
|
|
23322
|
+
}
|
|
23323
|
+
function createLeafNodeTx(sequence, directSequence, parentOutPoint, txOut, shouldCalculateFee) {
|
|
23324
|
+
const cpfpLeafTx = new import_btc_signer.Transaction({
|
|
23325
|
+
version: 3,
|
|
23326
|
+
allowUnknownOutputs: true
|
|
23327
|
+
});
|
|
23328
|
+
cpfpLeafTx.addInput({
|
|
23329
|
+
...parentOutPoint,
|
|
23330
|
+
sequence
|
|
23331
|
+
});
|
|
23332
|
+
cpfpLeafTx.addOutput(txOut);
|
|
23333
|
+
cpfpLeafTx.addOutput(getEphemeralAnchorOutput());
|
|
23334
|
+
const directLeafTx = new import_btc_signer.Transaction({
|
|
23335
|
+
version: 3,
|
|
23336
|
+
allowUnknownOutputs: true
|
|
23337
|
+
});
|
|
23338
|
+
directLeafTx.addInput({
|
|
23339
|
+
...parentOutPoint,
|
|
23340
|
+
sequence: directSequence
|
|
23341
|
+
});
|
|
23342
|
+
const amountSats = txOut.amount ?? 0n;
|
|
23343
|
+
let outputAmount = amountSats;
|
|
23344
|
+
if (shouldCalculateFee) {
|
|
23345
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
23346
|
+
}
|
|
23347
|
+
directLeafTx.addOutput({
|
|
23348
|
+
script: txOut.script,
|
|
23349
|
+
amount: outputAmount
|
|
23350
|
+
});
|
|
23351
|
+
return [cpfpLeafTx, directLeafTx];
|
|
23352
|
+
}
|
|
23353
|
+
function createRefundTx({
|
|
23354
|
+
sequence,
|
|
23355
|
+
input,
|
|
23356
|
+
amountSats,
|
|
23357
|
+
receivingPubkey,
|
|
23358
|
+
network,
|
|
23359
|
+
shouldCalculateFee,
|
|
23360
|
+
includeAnchor
|
|
23361
|
+
}) {
|
|
23362
|
+
const refundTx = new import_btc_signer.Transaction({
|
|
23189
23363
|
version: 3,
|
|
23190
23364
|
allowUnknownOutputs: true
|
|
23191
23365
|
});
|
|
23192
|
-
|
|
23193
|
-
...
|
|
23366
|
+
refundTx.addInput({
|
|
23367
|
+
...input,
|
|
23194
23368
|
sequence
|
|
23195
23369
|
});
|
|
23196
23370
|
const refundPkScript = getP2TRScriptFromPublicKey(receivingPubkey, network);
|
|
23197
|
-
|
|
23371
|
+
let outputAmount = amountSats;
|
|
23372
|
+
if (shouldCalculateFee) {
|
|
23373
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
23374
|
+
}
|
|
23375
|
+
refundTx.addOutput({
|
|
23198
23376
|
script: refundPkScript,
|
|
23377
|
+
amount: outputAmount
|
|
23378
|
+
});
|
|
23379
|
+
if (includeAnchor) {
|
|
23380
|
+
refundTx.addOutput(getEphemeralAnchorOutput());
|
|
23381
|
+
}
|
|
23382
|
+
return refundTx;
|
|
23383
|
+
}
|
|
23384
|
+
function createRefundTxs({
|
|
23385
|
+
sequence,
|
|
23386
|
+
directSequence,
|
|
23387
|
+
input,
|
|
23388
|
+
directInput,
|
|
23389
|
+
amountSats,
|
|
23390
|
+
receivingPubkey,
|
|
23391
|
+
network
|
|
23392
|
+
}) {
|
|
23393
|
+
const cpfpRefundTx = createRefundTx({
|
|
23394
|
+
sequence,
|
|
23395
|
+
input,
|
|
23396
|
+
amountSats,
|
|
23397
|
+
receivingPubkey,
|
|
23398
|
+
network,
|
|
23399
|
+
shouldCalculateFee: false,
|
|
23400
|
+
includeAnchor: true
|
|
23401
|
+
});
|
|
23402
|
+
let directRefundTx;
|
|
23403
|
+
let directFromCpfpRefundTx;
|
|
23404
|
+
if (directSequence && directInput) {
|
|
23405
|
+
directRefundTx = createRefundTx({
|
|
23406
|
+
sequence: directSequence,
|
|
23407
|
+
input: directInput,
|
|
23408
|
+
amountSats,
|
|
23409
|
+
receivingPubkey,
|
|
23410
|
+
network,
|
|
23411
|
+
shouldCalculateFee: true,
|
|
23412
|
+
includeAnchor: false
|
|
23413
|
+
});
|
|
23414
|
+
directFromCpfpRefundTx = createRefundTx({
|
|
23415
|
+
sequence: directSequence,
|
|
23416
|
+
input,
|
|
23417
|
+
amountSats,
|
|
23418
|
+
receivingPubkey,
|
|
23419
|
+
network,
|
|
23420
|
+
shouldCalculateFee: true,
|
|
23421
|
+
includeAnchor: false
|
|
23422
|
+
});
|
|
23423
|
+
} else if (directInput && !directSequence) {
|
|
23424
|
+
throw new ValidationError(
|
|
23425
|
+
"directSequence must be provided if directInput is",
|
|
23426
|
+
{
|
|
23427
|
+
field: "directSequence",
|
|
23428
|
+
value: directSequence
|
|
23429
|
+
}
|
|
23430
|
+
);
|
|
23431
|
+
}
|
|
23432
|
+
return { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx };
|
|
23433
|
+
}
|
|
23434
|
+
function createConnectorRefundTransactions(sequence, cpfpNodeOutPoint, directNodeOutPoint, connectorOutput, amountSats, receiverPubKey, network, shouldCalculateFee) {
|
|
23435
|
+
const cpfpRefundTx = new import_btc_signer.Transaction({
|
|
23436
|
+
version: 3,
|
|
23437
|
+
allowUnknownOutputs: true
|
|
23438
|
+
});
|
|
23439
|
+
cpfpRefundTx.addInput({
|
|
23440
|
+
...cpfpNodeOutPoint,
|
|
23441
|
+
sequence
|
|
23442
|
+
});
|
|
23443
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
23444
|
+
const receiverScript = getP2TRScriptFromPublicKey(receiverPubKey, network);
|
|
23445
|
+
cpfpRefundTx.addOutput({
|
|
23446
|
+
script: receiverScript,
|
|
23199
23447
|
amount: amountSats
|
|
23200
23448
|
});
|
|
23201
|
-
|
|
23202
|
-
|
|
23449
|
+
const directRefundTx = new import_btc_signer.Transaction({
|
|
23450
|
+
version: 3,
|
|
23451
|
+
allowUnknownOutputs: true
|
|
23452
|
+
});
|
|
23453
|
+
directRefundTx.addInput({
|
|
23454
|
+
...directNodeOutPoint,
|
|
23455
|
+
sequence
|
|
23456
|
+
});
|
|
23457
|
+
directRefundTx.addInput(connectorOutput);
|
|
23458
|
+
let outputAmount = amountSats;
|
|
23459
|
+
if (shouldCalculateFee) {
|
|
23460
|
+
outputAmount = maybeApplyFee(amountSats);
|
|
23461
|
+
}
|
|
23462
|
+
directRefundTx.addOutput({
|
|
23463
|
+
script: receiverScript,
|
|
23464
|
+
amount: outputAmount
|
|
23465
|
+
});
|
|
23466
|
+
const directFromCpfpTx = new import_btc_signer.Transaction({
|
|
23467
|
+
version: 3,
|
|
23468
|
+
allowUnknownOutputs: true
|
|
23469
|
+
});
|
|
23470
|
+
directFromCpfpTx.addInput({
|
|
23471
|
+
...cpfpNodeOutPoint,
|
|
23472
|
+
sequence
|
|
23473
|
+
});
|
|
23474
|
+
directFromCpfpTx.addInput(connectorOutput);
|
|
23475
|
+
directFromCpfpTx.addOutput({
|
|
23476
|
+
script: receiverScript,
|
|
23477
|
+
amount: outputAmount
|
|
23478
|
+
});
|
|
23479
|
+
return [cpfpRefundTx, directRefundTx, directFromCpfpTx];
|
|
23203
23480
|
}
|
|
23204
23481
|
function getCurrentTimelock(currSequence) {
|
|
23205
23482
|
return (currSequence || 0) & 65535;
|
|
23206
23483
|
}
|
|
23207
23484
|
function getTransactionSequence(currSequence) {
|
|
23208
23485
|
const timelock = getCurrentTimelock(currSequence);
|
|
23209
|
-
return
|
|
23486
|
+
return {
|
|
23487
|
+
nextSequence: 1 << 30 | timelock,
|
|
23488
|
+
nextDirectSequence: 1 << 30 | timelock + DIRECT_TIMELOCK_OFFSET
|
|
23489
|
+
};
|
|
23210
23490
|
}
|
|
23211
23491
|
function checkIfValidSequence(currSequence) {
|
|
23212
23492
|
const TIME_LOCK_ACTIVE = (currSequence || 0) & 2147483648;
|
|
@@ -23224,24 +23504,32 @@ function checkIfValidSequence(currSequence) {
|
|
|
23224
23504
|
});
|
|
23225
23505
|
}
|
|
23226
23506
|
}
|
|
23227
|
-
function
|
|
23507
|
+
function doesLeafNeedRefresh(currSequence, isNodeTx) {
|
|
23228
23508
|
const currentTimelock = getCurrentTimelock(currSequence);
|
|
23229
|
-
|
|
23230
|
-
|
|
23231
|
-
return {
|
|
23232
|
-
nextSequence: 1 << 30 | nextTimelock,
|
|
23233
|
-
needRefresh: true
|
|
23234
|
-
};
|
|
23509
|
+
if (isNodeTx) {
|
|
23510
|
+
return currentTimelock === 0;
|
|
23235
23511
|
}
|
|
23236
|
-
|
|
23512
|
+
return currentTimelock <= 100;
|
|
23513
|
+
}
|
|
23514
|
+
function getNextTransactionSequence(currSequence, isNodeTx) {
|
|
23515
|
+
const currentTimelock = getCurrentTimelock(currSequence);
|
|
23516
|
+
const nextTimelock = currentTimelock - TIME_LOCK_INTERVAL;
|
|
23517
|
+
if (isNodeTx && nextTimelock < 0) {
|
|
23237
23518
|
throw new ValidationError("timelock interval is less than 0", {
|
|
23238
23519
|
field: "nextTimelock",
|
|
23239
|
-
value: nextTimelock
|
|
23520
|
+
value: nextTimelock,
|
|
23521
|
+
expected: "Non-negative timelock interval"
|
|
23522
|
+
});
|
|
23523
|
+
} else if (!isNodeTx && nextTimelock <= 0) {
|
|
23524
|
+
throw new ValidationError("timelock interval is less than or equal to 0", {
|
|
23525
|
+
field: "nextTimelock",
|
|
23526
|
+
value: nextTimelock,
|
|
23527
|
+
expected: "Timelock greater than 0"
|
|
23240
23528
|
});
|
|
23241
23529
|
}
|
|
23242
23530
|
return {
|
|
23243
23531
|
nextSequence: 1 << 30 | nextTimelock,
|
|
23244
|
-
|
|
23532
|
+
nextDirectSequence: 1 << 30 | nextTimelock + DIRECT_TIMELOCK_OFFSET
|
|
23245
23533
|
};
|
|
23246
23534
|
}
|
|
23247
23535
|
function getEphemeralAnchorOutput() {
|
|
@@ -23287,11 +23575,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
23287
23575
|
}
|
|
23288
23576
|
|
|
23289
23577
|
// src/services/transfer.ts
|
|
23290
|
-
var INITIAL_TIME_LOCK = 2e3;
|
|
23291
23578
|
var DEFAULT_EXPIRY_TIME = 10 * 60 * 1e3;
|
|
23292
|
-
function initialSequence() {
|
|
23293
|
-
return 1 << 30 | INITIAL_TIME_LOCK;
|
|
23294
|
-
}
|
|
23295
23579
|
function getSigningJobProto(signingJob) {
|
|
23296
23580
|
return {
|
|
23297
23581
|
signingPublicKey: signingJob.signingPublicKey,
|
|
@@ -23308,12 +23592,14 @@ var BaseTransferService = class {
|
|
|
23308
23592
|
this.connectionManager = connectionManager;
|
|
23309
23593
|
this.signingService = signingService;
|
|
23310
23594
|
}
|
|
23311
|
-
async sendTransferTweakKey(transfer, leaves,
|
|
23595
|
+
async sendTransferTweakKey(transfer, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
23312
23596
|
const keyTweakInputMap = await this.prepareSendTransferKeyTweaks(
|
|
23313
23597
|
transfer.id,
|
|
23314
23598
|
transfer.receiverIdentityPublicKey,
|
|
23315
23599
|
leaves,
|
|
23316
|
-
|
|
23600
|
+
cpfpRefundSignatureMap,
|
|
23601
|
+
directRefundSignatureMap,
|
|
23602
|
+
directFromCpfpRefundSignatureMap
|
|
23317
23603
|
);
|
|
23318
23604
|
let updatedTransfer;
|
|
23319
23605
|
const coordinatorOperator = this.config.getSigningOperators()[this.config.getCoordinatorIdentifier()];
|
|
@@ -23351,13 +23637,26 @@ var BaseTransferService = class {
|
|
|
23351
23637
|
}
|
|
23352
23638
|
return updatedTransfer;
|
|
23353
23639
|
}
|
|
23354
|
-
async deliverTransferPackage(transfer, leaves,
|
|
23640
|
+
async deliverTransferPackage(transfer, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
23355
23641
|
const keyTweakInputMap = await this.prepareSendTransferKeyTweaks(
|
|
23356
23642
|
transfer.id,
|
|
23357
23643
|
transfer.receiverIdentityPublicKey,
|
|
23358
23644
|
leaves,
|
|
23359
|
-
|
|
23645
|
+
cpfpRefundSignatureMap,
|
|
23646
|
+
directRefundSignatureMap,
|
|
23647
|
+
directFromCpfpRefundSignatureMap
|
|
23360
23648
|
);
|
|
23649
|
+
for (const [key, operator] of Object.entries(
|
|
23650
|
+
this.config.getSigningOperators()
|
|
23651
|
+
)) {
|
|
23652
|
+
const tweaks = keyTweakInputMap.get(key);
|
|
23653
|
+
if (!tweaks) {
|
|
23654
|
+
throw new ValidationError("No tweaks for operator", {
|
|
23655
|
+
field: "operator",
|
|
23656
|
+
value: key
|
|
23657
|
+
});
|
|
23658
|
+
}
|
|
23659
|
+
}
|
|
23361
23660
|
const transferPackage = await this.prepareTransferPackage(
|
|
23362
23661
|
transfer.id,
|
|
23363
23662
|
keyTweakInputMap,
|
|
@@ -23383,6 +23682,8 @@ var BaseTransferService = class {
|
|
|
23383
23682
|
transferID,
|
|
23384
23683
|
receiverIdentityPubkey,
|
|
23385
23684
|
leaves,
|
|
23685
|
+
/* @__PURE__ */ new Map(),
|
|
23686
|
+
/* @__PURE__ */ new Map(),
|
|
23386
23687
|
/* @__PURE__ */ new Map()
|
|
23387
23688
|
);
|
|
23388
23689
|
const transferPackage = await this.prepareTransferPackage(
|
|
@@ -23396,7 +23697,7 @@ var BaseTransferService = class {
|
|
|
23396
23697
|
);
|
|
23397
23698
|
let response;
|
|
23398
23699
|
try {
|
|
23399
|
-
response = await sparkClient.
|
|
23700
|
+
response = await sparkClient.start_transfer_v2({
|
|
23400
23701
|
transferId: transferID,
|
|
23401
23702
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
23402
23703
|
receiverIdentityPublicKey: receiverIdentityPubkey,
|
|
@@ -23425,12 +23726,22 @@ var BaseTransferService = class {
|
|
|
23425
23726
|
nodes.push(leaf.leaf.id);
|
|
23426
23727
|
}
|
|
23427
23728
|
const signingCommitments = await sparkClient.get_signing_commitments({
|
|
23428
|
-
nodeIds: nodes
|
|
23729
|
+
nodeIds: nodes,
|
|
23730
|
+
count: 3
|
|
23429
23731
|
});
|
|
23430
|
-
const
|
|
23732
|
+
const {
|
|
23733
|
+
cpfpLeafSigningJobs,
|
|
23734
|
+
directLeafSigningJobs,
|
|
23735
|
+
directFromCpfpLeafSigningJobs
|
|
23736
|
+
} = await this.signingService.signRefunds(
|
|
23431
23737
|
leaves,
|
|
23432
|
-
|
|
23433
|
-
|
|
23738
|
+
receiverIdentityPubkey,
|
|
23739
|
+
signingCommitments.signingCommitments.slice(0, leaves.length),
|
|
23740
|
+
signingCommitments.signingCommitments.slice(
|
|
23741
|
+
leaves.length,
|
|
23742
|
+
2 * leaves.length
|
|
23743
|
+
),
|
|
23744
|
+
signingCommitments.signingCommitments.slice(2 * leaves.length)
|
|
23434
23745
|
);
|
|
23435
23746
|
const encryptedKeyTweaks = {};
|
|
23436
23747
|
for (const [key, value] of keyTweakInputMap) {
|
|
@@ -23450,12 +23761,11 @@ var BaseTransferService = class {
|
|
|
23450
23761
|
encryptedKeyTweaks[key] = Uint8Array.from(encryptedProto);
|
|
23451
23762
|
}
|
|
23452
23763
|
const transferPackage = {
|
|
23453
|
-
leavesToSend:
|
|
23764
|
+
leavesToSend: cpfpLeafSigningJobs,
|
|
23454
23765
|
keyTweakPackage: encryptedKeyTweaks,
|
|
23455
23766
|
userSignature: new Uint8Array(),
|
|
23456
|
-
|
|
23457
|
-
|
|
23458
|
-
directFromCpfpLeavesToSend: []
|
|
23767
|
+
directLeavesToSend: directLeafSigningJobs,
|
|
23768
|
+
directFromCpfpLeavesToSend: directFromCpfpLeafSigningJobs
|
|
23459
23769
|
};
|
|
23460
23770
|
const transferPackageSigningPayload = getTransferPackageSigningPayload(
|
|
23461
23771
|
transferID,
|
|
@@ -23515,7 +23825,7 @@ var BaseTransferService = class {
|
|
|
23515
23825
|
}
|
|
23516
23826
|
return updatedTransfer;
|
|
23517
23827
|
}
|
|
23518
|
-
async signRefunds(leafDataMap, operatorSigningResults,
|
|
23828
|
+
async signRefunds(leafDataMap, operatorSigningResults, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
23519
23829
|
const nodeSignatures = [];
|
|
23520
23830
|
for (const operatorSigningResult of operatorSigningResults) {
|
|
23521
23831
|
const leafData = leafDataMap.get(operatorSigningResult.leafId);
|
|
@@ -23530,54 +23840,120 @@ var BaseTransferService = class {
|
|
|
23530
23840
|
`Output not found for leaf ${operatorSigningResult.leafId}`
|
|
23531
23841
|
);
|
|
23532
23842
|
}
|
|
23533
|
-
const
|
|
23843
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
23844
|
+
leafData.refundTx,
|
|
23845
|
+
0,
|
|
23846
|
+
txOutput
|
|
23847
|
+
);
|
|
23534
23848
|
const publicKey = await this.config.signer.getPublicKeyFromDerivation(
|
|
23535
23849
|
leafData.keyDerivation
|
|
23536
23850
|
);
|
|
23537
|
-
const
|
|
23538
|
-
message:
|
|
23851
|
+
const cpfpUserSignature = await this.config.signer.signFrost({
|
|
23852
|
+
message: cpfpRefundTxSighash,
|
|
23539
23853
|
publicKey,
|
|
23540
23854
|
keyDerivation: leafData.keyDerivation,
|
|
23541
23855
|
selfCommitment: leafData.signingNonceCommitment,
|
|
23542
23856
|
statechainCommitments: operatorSigningResult.refundTxSigningResult?.signingNonceCommitments,
|
|
23543
|
-
adaptorPubKey,
|
|
23857
|
+
adaptorPubKey: cpfpAdaptorPubKey,
|
|
23544
23858
|
verifyingKey: operatorSigningResult.verifyingKey
|
|
23545
23859
|
});
|
|
23546
|
-
const
|
|
23547
|
-
message:
|
|
23860
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
23861
|
+
message: cpfpRefundTxSighash,
|
|
23548
23862
|
statechainSignatures: operatorSigningResult.refundTxSigningResult?.signatureShares,
|
|
23549
23863
|
statechainPublicKeys: operatorSigningResult.refundTxSigningResult?.publicKeys,
|
|
23550
23864
|
verifyingKey: operatorSigningResult.verifyingKey,
|
|
23551
23865
|
statechainCommitments: operatorSigningResult.refundTxSigningResult?.signingNonceCommitments,
|
|
23552
23866
|
selfCommitment: leafData.signingNonceCommitment,
|
|
23553
23867
|
publicKey,
|
|
23554
|
-
selfSignature:
|
|
23555
|
-
adaptorPubKey
|
|
23868
|
+
selfSignature: cpfpUserSignature,
|
|
23869
|
+
adaptorPubKey: cpfpAdaptorPubKey
|
|
23556
23870
|
});
|
|
23871
|
+
let directRefundAggregate;
|
|
23872
|
+
let directFromCpfpRefundAggregate;
|
|
23873
|
+
if (leafData.directTx) {
|
|
23874
|
+
const directTxOutput = leafData.directTx.getOutput(0);
|
|
23875
|
+
if (leafData.directRefundTx) {
|
|
23876
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
23877
|
+
leafData.directRefundTx,
|
|
23878
|
+
0,
|
|
23879
|
+
directTxOutput
|
|
23880
|
+
);
|
|
23881
|
+
const directUserSignature = await this.config.signer.signFrost({
|
|
23882
|
+
message: directRefundTxSighash,
|
|
23883
|
+
publicKey,
|
|
23884
|
+
keyDerivation: leafData.keyDerivation,
|
|
23885
|
+
selfCommitment: leafData.directSigningNonceCommitment,
|
|
23886
|
+
statechainCommitments: operatorSigningResult.directRefundTxSigningResult?.signingNonceCommitments,
|
|
23887
|
+
adaptorPubKey: directAdaptorPubKey,
|
|
23888
|
+
verifyingKey: operatorSigningResult.verifyingKey
|
|
23889
|
+
});
|
|
23890
|
+
directRefundAggregate = await this.config.signer.aggregateFrost({
|
|
23891
|
+
message: directRefundTxSighash,
|
|
23892
|
+
statechainSignatures: operatorSigningResult.directRefundTxSigningResult?.signatureShares,
|
|
23893
|
+
statechainPublicKeys: operatorSigningResult.directRefundTxSigningResult?.publicKeys,
|
|
23894
|
+
verifyingKey: operatorSigningResult.verifyingKey,
|
|
23895
|
+
statechainCommitments: operatorSigningResult.directRefundTxSigningResult?.signingNonceCommitments,
|
|
23896
|
+
selfCommitment: leafData.directSigningNonceCommitment,
|
|
23897
|
+
publicKey,
|
|
23898
|
+
selfSignature: directUserSignature,
|
|
23899
|
+
adaptorPubKey: directAdaptorPubKey
|
|
23900
|
+
});
|
|
23901
|
+
}
|
|
23902
|
+
if (leafData.directFromCpfpRefundTx) {
|
|
23903
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
23904
|
+
leafData.directFromCpfpRefundTx,
|
|
23905
|
+
0,
|
|
23906
|
+
txOutput
|
|
23907
|
+
);
|
|
23908
|
+
const directFromCpfpUserSignature = await this.config.signer.signFrost({
|
|
23909
|
+
message: directFromCpfpRefundTxSighash,
|
|
23910
|
+
publicKey,
|
|
23911
|
+
keyDerivation: leafData.keyDerivation,
|
|
23912
|
+
selfCommitment: leafData.directFromCpfpRefundSigningNonceCommitment,
|
|
23913
|
+
statechainCommitments: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
23914
|
+
adaptorPubKey: directFromCpfpAdaptorPubKey,
|
|
23915
|
+
verifyingKey: operatorSigningResult.verifyingKey
|
|
23916
|
+
});
|
|
23917
|
+
directFromCpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
23918
|
+
message: directFromCpfpRefundTxSighash,
|
|
23919
|
+
statechainSignatures: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signatureShares,
|
|
23920
|
+
statechainPublicKeys: operatorSigningResult.directFromCpfpRefundTxSigningResult?.publicKeys,
|
|
23921
|
+
verifyingKey: operatorSigningResult.verifyingKey,
|
|
23922
|
+
statechainCommitments: operatorSigningResult.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
23923
|
+
selfCommitment: leafData.directFromCpfpRefundSigningNonceCommitment,
|
|
23924
|
+
publicKey,
|
|
23925
|
+
selfSignature: directFromCpfpUserSignature,
|
|
23926
|
+
adaptorPubKey: directFromCpfpAdaptorPubKey
|
|
23927
|
+
});
|
|
23928
|
+
}
|
|
23929
|
+
}
|
|
23557
23930
|
nodeSignatures.push({
|
|
23558
23931
|
nodeId: operatorSigningResult.leafId,
|
|
23559
|
-
refundTxSignature: refundAggregate,
|
|
23560
23932
|
nodeTxSignature: new Uint8Array(),
|
|
23561
|
-
// TODO: Add direct refund signature
|
|
23562
23933
|
directNodeTxSignature: new Uint8Array(),
|
|
23563
|
-
|
|
23564
|
-
|
|
23934
|
+
refundTxSignature: cpfpRefundAggregate,
|
|
23935
|
+
directRefundTxSignature: directRefundAggregate ?? new Uint8Array(),
|
|
23936
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundAggregate ?? new Uint8Array()
|
|
23565
23937
|
});
|
|
23566
23938
|
}
|
|
23567
23939
|
return nodeSignatures;
|
|
23568
23940
|
}
|
|
23569
|
-
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves,
|
|
23941
|
+
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
23570
23942
|
const receiverEciesPubKey = ecies2.PublicKey.fromHex(
|
|
23571
23943
|
(0, import_utils8.bytesToHex)(receiverIdentityPubkey)
|
|
23572
23944
|
);
|
|
23573
23945
|
const leavesTweaksMap = /* @__PURE__ */ new Map();
|
|
23574
23946
|
for (const leaf of leaves) {
|
|
23575
|
-
const
|
|
23947
|
+
const cpfpRefundSignature = cpfpRefundSignatureMap.get(leaf.leaf.id);
|
|
23948
|
+
const directRefundSignature = directRefundSignatureMap.get(leaf.leaf.id);
|
|
23949
|
+
const directFromCpfpRefundSignature = directFromCpfpRefundSignatureMap.get(leaf.leaf.id);
|
|
23576
23950
|
const leafTweaksMap = await this.prepareSingleSendTransferKeyTweak(
|
|
23577
23951
|
transferID,
|
|
23578
23952
|
leaf,
|
|
23579
23953
|
receiverEciesPubKey,
|
|
23580
|
-
|
|
23954
|
+
cpfpRefundSignature,
|
|
23955
|
+
directRefundSignature,
|
|
23956
|
+
directFromCpfpRefundSignature
|
|
23581
23957
|
);
|
|
23582
23958
|
for (const [identifier, leafTweak] of leafTweaksMap) {
|
|
23583
23959
|
leavesTweaksMap.set(identifier, [
|
|
@@ -23588,7 +23964,7 @@ var BaseTransferService = class {
|
|
|
23588
23964
|
}
|
|
23589
23965
|
return leavesTweaksMap;
|
|
23590
23966
|
}
|
|
23591
|
-
async prepareSingleSendTransferKeyTweak(transferID, leaf, receiverEciesPubKey,
|
|
23967
|
+
async prepareSingleSendTransferKeyTweak(transferID, leaf, receiverEciesPubKey, cpfpRefundSignature, directRefundSignature, directFromCpfpRefundSignature) {
|
|
23592
23968
|
const signingOperators = this.config.getSigningOperators();
|
|
23593
23969
|
const { shares, secretCipher } = await this.config.signer.subtractSplitAndEncrypt({
|
|
23594
23970
|
first: leaf.keyDerivation,
|
|
@@ -23636,10 +24012,9 @@ var BaseTransferService = class {
|
|
|
23636
24012
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak),
|
|
23637
24013
|
secretCipher,
|
|
23638
24014
|
signature,
|
|
23639
|
-
refundSignature:
|
|
23640
|
-
|
|
23641
|
-
|
|
23642
|
-
directFromCpfpRefundSignature: new Uint8Array()
|
|
24015
|
+
refundSignature: cpfpRefundSignature ?? new Uint8Array(),
|
|
24016
|
+
directRefundSignature: directRefundSignature ?? new Uint8Array(),
|
|
24017
|
+
directFromCpfpRefundSignature: directFromCpfpRefundSignature ?? new Uint8Array()
|
|
23643
24018
|
});
|
|
23644
24019
|
}
|
|
23645
24020
|
return leafTweaksMap;
|
|
@@ -23669,7 +24044,12 @@ var TransferService = class extends BaseTransferService {
|
|
|
23669
24044
|
* Deprecated in v0.1.32
|
|
23670
24045
|
*/
|
|
23671
24046
|
async sendTransfer(leaves, receiverIdentityPubkey) {
|
|
23672
|
-
const {
|
|
24047
|
+
const {
|
|
24048
|
+
transfer,
|
|
24049
|
+
signatureMap,
|
|
24050
|
+
directSignatureMap,
|
|
24051
|
+
directFromCpfpSignatureMap
|
|
24052
|
+
} = await this.sendTransferSignRefund(
|
|
23673
24053
|
leaves,
|
|
23674
24054
|
receiverIdentityPubkey,
|
|
23675
24055
|
new Date(Date.now() + DEFAULT_EXPIRY_TIME)
|
|
@@ -23677,7 +24057,9 @@ var TransferService = class extends BaseTransferService {
|
|
|
23677
24057
|
const transferWithTweakedKeys = await this.sendTransferTweakKey(
|
|
23678
24058
|
transfer,
|
|
23679
24059
|
leaves,
|
|
23680
|
-
signatureMap
|
|
24060
|
+
signatureMap,
|
|
24061
|
+
directSignatureMap,
|
|
24062
|
+
directFromCpfpSignatureMap
|
|
23681
24063
|
);
|
|
23682
24064
|
return transferWithTweakedKeys;
|
|
23683
24065
|
}
|
|
@@ -23781,7 +24163,13 @@ var TransferService = class extends BaseTransferService {
|
|
|
23781
24163
|
return transferResp.transfers[0];
|
|
23782
24164
|
}
|
|
23783
24165
|
async sendTransferSignRefund(leaves, receiverIdentityPubkey, expiryTime) {
|
|
23784
|
-
const {
|
|
24166
|
+
const {
|
|
24167
|
+
transfer,
|
|
24168
|
+
signatureMap,
|
|
24169
|
+
directSignatureMap,
|
|
24170
|
+
directFromCpfpSignatureMap,
|
|
24171
|
+
leafDataMap
|
|
24172
|
+
} = await this.sendTransferSignRefundInternal(
|
|
23785
24173
|
leaves,
|
|
23786
24174
|
receiverIdentityPubkey,
|
|
23787
24175
|
expiryTime,
|
|
@@ -23790,11 +24178,19 @@ var TransferService = class extends BaseTransferService {
|
|
|
23790
24178
|
return {
|
|
23791
24179
|
transfer,
|
|
23792
24180
|
signatureMap,
|
|
24181
|
+
directSignatureMap,
|
|
24182
|
+
directFromCpfpSignatureMap,
|
|
23793
24183
|
leafDataMap
|
|
23794
24184
|
};
|
|
23795
24185
|
}
|
|
23796
24186
|
async startSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime) {
|
|
23797
|
-
const {
|
|
24187
|
+
const {
|
|
24188
|
+
transfer,
|
|
24189
|
+
signatureMap,
|
|
24190
|
+
directSignatureMap,
|
|
24191
|
+
directFromCpfpSignatureMap,
|
|
24192
|
+
leafDataMap
|
|
24193
|
+
} = await this.sendTransferSignRefundInternal(
|
|
23798
24194
|
leaves,
|
|
23799
24195
|
receiverIdentityPubkey,
|
|
23800
24196
|
expiryTime,
|
|
@@ -23803,31 +24199,45 @@ var TransferService = class extends BaseTransferService {
|
|
|
23803
24199
|
return {
|
|
23804
24200
|
transfer,
|
|
23805
24201
|
signatureMap,
|
|
24202
|
+
directSignatureMap,
|
|
24203
|
+
directFromCpfpSignatureMap,
|
|
23806
24204
|
leafDataMap
|
|
23807
24205
|
};
|
|
23808
24206
|
}
|
|
23809
|
-
async counterSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime,
|
|
24207
|
+
async counterSwapSignRefund(leaves, receiverIdentityPubkey, expiryTime, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
23810
24208
|
return this.sendTransferSignRefundInternal(
|
|
23811
24209
|
leaves,
|
|
23812
24210
|
receiverIdentityPubkey,
|
|
23813
24211
|
expiryTime,
|
|
23814
24212
|
true,
|
|
23815
|
-
|
|
24213
|
+
cpfpAdaptorPubKey,
|
|
24214
|
+
directAdaptorPubKey,
|
|
24215
|
+
directFromCpfpAdaptorPubKey
|
|
23816
24216
|
);
|
|
23817
24217
|
}
|
|
23818
|
-
async sendTransferSignRefundInternal(leaves, receiverIdentityPubkey, expiryTime, forSwap,
|
|
24218
|
+
async sendTransferSignRefundInternal(leaves, receiverIdentityPubkey, expiryTime, forSwap, cpfpAdaptorPubKey, directAdaptorPubKey, directFromCpfpAdaptorPubKey) {
|
|
23819
24219
|
const transferId = (0, import_uuidv7.uuidv7)();
|
|
23820
24220
|
const leafDataMap = /* @__PURE__ */ new Map();
|
|
23821
24221
|
for (const leaf of leaves) {
|
|
23822
24222
|
const signingNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
24223
|
+
const directSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
24224
|
+
const directFromCpfpRefundSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
23823
24225
|
const tx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
23824
24226
|
const refundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
24227
|
+
const directTx = leaf.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directTx) : void 0;
|
|
24228
|
+
const directRefundTx = leaf.leaf.directRefundTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directRefundTx) : void 0;
|
|
24229
|
+
const directFromCpfpRefundTx = leaf.leaf.directFromCpfpRefundTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directFromCpfpRefundTx) : void 0;
|
|
23825
24230
|
leafDataMap.set(leaf.leaf.id, {
|
|
23826
24231
|
keyDerivation: leaf.keyDerivation,
|
|
23827
24232
|
receivingPubkey: receiverIdentityPubkey,
|
|
23828
24233
|
signingNonceCommitment,
|
|
24234
|
+
directSigningNonceCommitment,
|
|
23829
24235
|
tx,
|
|
24236
|
+
directTx,
|
|
23830
24237
|
refundTx,
|
|
24238
|
+
directRefundTx,
|
|
24239
|
+
directFromCpfpRefundTx,
|
|
24240
|
+
directFromCpfpRefundSigningNonceCommitment,
|
|
23831
24241
|
vout: leaf.leaf.vout
|
|
23832
24242
|
});
|
|
23833
24243
|
}
|
|
@@ -23840,8 +24250,8 @@ var TransferService = class extends BaseTransferService {
|
|
|
23840
24250
|
);
|
|
23841
24251
|
let response;
|
|
23842
24252
|
try {
|
|
23843
|
-
if (
|
|
23844
|
-
response = await sparkClient.
|
|
24253
|
+
if (cpfpAdaptorPubKey !== void 0 || directAdaptorPubKey !== void 0 || directFromCpfpAdaptorPubKey !== void 0) {
|
|
24254
|
+
response = await sparkClient.counter_leaf_swap_v2({
|
|
23845
24255
|
transfer: {
|
|
23846
24256
|
transferId,
|
|
23847
24257
|
leavesToSend: signingJobs,
|
|
@@ -23850,10 +24260,12 @@ var TransferService = class extends BaseTransferService {
|
|
|
23850
24260
|
expiryTime
|
|
23851
24261
|
},
|
|
23852
24262
|
swapId: (0, import_uuidv7.uuidv7)(),
|
|
23853
|
-
adaptorPublicKey:
|
|
24263
|
+
adaptorPublicKey: cpfpAdaptorPubKey,
|
|
24264
|
+
directAdaptorPublicKey: directAdaptorPubKey,
|
|
24265
|
+
directFromCpfpAdaptorPublicKey: directFromCpfpAdaptorPubKey
|
|
23854
24266
|
});
|
|
23855
24267
|
} else if (forSwap) {
|
|
23856
|
-
response = await sparkClient.
|
|
24268
|
+
response = await sparkClient.start_leaf_swap_v2({
|
|
23857
24269
|
transferId,
|
|
23858
24270
|
leavesToSend: signingJobs,
|
|
23859
24271
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
@@ -23861,7 +24273,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
23861
24273
|
expiryTime
|
|
23862
24274
|
});
|
|
23863
24275
|
} else {
|
|
23864
|
-
response = await sparkClient.
|
|
24276
|
+
response = await sparkClient.start_transfer_v2({
|
|
23865
24277
|
transferId,
|
|
23866
24278
|
leavesToSend: signingJobs,
|
|
23867
24279
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
@@ -23878,15 +24290,29 @@ var TransferService = class extends BaseTransferService {
|
|
|
23878
24290
|
const signatures = await this.signRefunds(
|
|
23879
24291
|
leafDataMap,
|
|
23880
24292
|
response.signingResults,
|
|
23881
|
-
|
|
24293
|
+
cpfpAdaptorPubKey,
|
|
24294
|
+
directAdaptorPubKey,
|
|
24295
|
+
directFromCpfpAdaptorPubKey
|
|
23882
24296
|
);
|
|
23883
|
-
const
|
|
24297
|
+
const cpfpSignatureMap = /* @__PURE__ */ new Map();
|
|
24298
|
+
const directSignatureMap = /* @__PURE__ */ new Map();
|
|
24299
|
+
const directFromCpfpSignatureMap = /* @__PURE__ */ new Map();
|
|
23884
24300
|
for (const signature of signatures) {
|
|
23885
|
-
|
|
24301
|
+
cpfpSignatureMap.set(signature.nodeId, signature.refundTxSignature);
|
|
24302
|
+
directSignatureMap.set(
|
|
24303
|
+
signature.nodeId,
|
|
24304
|
+
signature.directRefundTxSignature
|
|
24305
|
+
);
|
|
24306
|
+
directFromCpfpSignatureMap.set(
|
|
24307
|
+
signature.nodeId,
|
|
24308
|
+
signature.directFromCpfpRefundTxSignature
|
|
24309
|
+
);
|
|
23886
24310
|
}
|
|
23887
24311
|
return {
|
|
23888
24312
|
transfer: response.transfer,
|
|
23889
|
-
signatureMap,
|
|
24313
|
+
signatureMap: cpfpSignatureMap,
|
|
24314
|
+
directSignatureMap,
|
|
24315
|
+
directFromCpfpSignatureMap,
|
|
23890
24316
|
leafDataMap,
|
|
23891
24317
|
signingResults: response.signingResults
|
|
23892
24318
|
};
|
|
@@ -23899,38 +24325,68 @@ var TransferService = class extends BaseTransferService {
|
|
|
23899
24325
|
throw new Error(`Leaf data not found for leaf ${leaf.leaf.id}`);
|
|
23900
24326
|
}
|
|
23901
24327
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
23902
|
-
const
|
|
24328
|
+
const cpfpNodeOutPoint = {
|
|
23903
24329
|
txid: (0, import_utils8.hexToBytes)(getTxId(nodeTx)),
|
|
23904
24330
|
index: 0
|
|
23905
24331
|
};
|
|
24332
|
+
let directNodeTx;
|
|
24333
|
+
let directNodeOutPoint;
|
|
24334
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
24335
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
24336
|
+
directNodeOutPoint = {
|
|
24337
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(directNodeTx)),
|
|
24338
|
+
index: 0
|
|
24339
|
+
};
|
|
24340
|
+
}
|
|
23906
24341
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
23907
|
-
const
|
|
24342
|
+
const sequence = currRefundTx.getInput(0).sequence;
|
|
24343
|
+
if (!sequence) {
|
|
24344
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
24345
|
+
field: "sequence",
|
|
24346
|
+
value: currRefundTx.getInput(0),
|
|
24347
|
+
expected: "Non-null sequence"
|
|
24348
|
+
});
|
|
24349
|
+
}
|
|
24350
|
+
const { nextSequence, nextDirectSequence } = isForClaim ? getTransactionSequence(sequence) : getNextTransactionSequence(sequence);
|
|
23908
24351
|
const amountSats = currRefundTx.getOutput(0).amount;
|
|
23909
24352
|
if (amountSats === void 0) {
|
|
23910
24353
|
throw new Error("Amount not found in signRefunds");
|
|
23911
24354
|
}
|
|
23912
|
-
const
|
|
23913
|
-
nextSequence,
|
|
23914
|
-
|
|
24355
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
24356
|
+
sequence: nextSequence,
|
|
24357
|
+
directSequence: nextDirectSequence,
|
|
24358
|
+
input: cpfpNodeOutPoint,
|
|
24359
|
+
directInput: directNodeOutPoint,
|
|
23915
24360
|
amountSats,
|
|
23916
|
-
refundSigningData.receivingPubkey,
|
|
23917
|
-
this.config.getNetwork()
|
|
24361
|
+
receivingPubkey: refundSigningData.receivingPubkey,
|
|
24362
|
+
network: this.config.getNetwork()
|
|
24363
|
+
});
|
|
24364
|
+
refundSigningData.refundTx = cpfpRefundTx;
|
|
24365
|
+
refundSigningData.directRefundTx = directRefundTx;
|
|
24366
|
+
refundSigningData.directFromCpfpRefundTx = directFromCpfpRefundTx;
|
|
24367
|
+
const cpfpRefundNonceCommitmentProto = refundSigningData.signingNonceCommitment;
|
|
24368
|
+
const directRefundNonceCommitmentProto = refundSigningData.directSigningNonceCommitment;
|
|
24369
|
+
const directFromCpfpRefundNonceCommitmentProto = refundSigningData.directFromCpfpRefundSigningNonceCommitment;
|
|
24370
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(
|
|
24371
|
+
refundSigningData.keyDerivation
|
|
23918
24372
|
);
|
|
23919
|
-
refundSigningData.refundTx = refundTx;
|
|
23920
|
-
const refundNonceCommitmentProto = refundSigningData.signingNonceCommitment;
|
|
23921
24373
|
signingJobs.push({
|
|
23922
24374
|
leafId: leaf.leaf.id,
|
|
23923
24375
|
refundTxSigningJob: {
|
|
23924
|
-
signingPublicKey
|
|
23925
|
-
|
|
23926
|
-
|
|
23927
|
-
rawTx: refundTx.toBytes(),
|
|
23928
|
-
signingNonceCommitment: refundNonceCommitmentProto.commitment
|
|
24376
|
+
signingPublicKey,
|
|
24377
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
24378
|
+
signingNonceCommitment: cpfpRefundNonceCommitmentProto.commitment
|
|
23929
24379
|
},
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
|
|
24380
|
+
directRefundTxSigningJob: directRefundTx ? {
|
|
24381
|
+
signingPublicKey,
|
|
24382
|
+
rawTx: directRefundTx.toBytes(),
|
|
24383
|
+
signingNonceCommitment: directRefundNonceCommitmentProto.commitment
|
|
24384
|
+
} : void 0,
|
|
24385
|
+
directFromCpfpRefundTxSigningJob: directFromCpfpRefundTx ? {
|
|
24386
|
+
signingPublicKey,
|
|
24387
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
24388
|
+
signingNonceCommitment: directFromCpfpRefundNonceCommitmentProto.commitment
|
|
24389
|
+
} : void 0
|
|
23934
24390
|
});
|
|
23935
24391
|
}
|
|
23936
24392
|
return signingJobs;
|
|
@@ -24051,13 +24507,17 @@ var TransferService = class extends BaseTransferService {
|
|
|
24051
24507
|
const leafDataMap = /* @__PURE__ */ new Map();
|
|
24052
24508
|
for (const leafKey of leafKeys) {
|
|
24053
24509
|
const tx = getTxFromRawTxBytes(leafKey.leaf.nodeTx);
|
|
24510
|
+
const directTx = leafKey.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leafKey.leaf.directTx) : void 0;
|
|
24054
24511
|
leafDataMap.set(leafKey.leaf.id, {
|
|
24055
24512
|
keyDerivation: leafKey.newKeyDerivation,
|
|
24056
24513
|
receivingPubkey: await this.config.signer.getPublicKeyFromDerivation(
|
|
24057
24514
|
leafKey.newKeyDerivation
|
|
24058
24515
|
),
|
|
24059
24516
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24517
|
+
directSigningNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24518
|
+
directFromCpfpRefundSigningNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24060
24519
|
tx,
|
|
24520
|
+
directTx,
|
|
24061
24521
|
vout: leafKey.leaf.vout
|
|
24062
24522
|
});
|
|
24063
24523
|
}
|
|
@@ -24079,7 +24539,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
24079
24539
|
}
|
|
24080
24540
|
}
|
|
24081
24541
|
try {
|
|
24082
|
-
resp = await sparkClient.
|
|
24542
|
+
resp = await sparkClient.claim_transfer_sign_refunds_v2({
|
|
24083
24543
|
transferId: transfer.id,
|
|
24084
24544
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
24085
24545
|
signingJobs
|
|
@@ -24094,7 +24554,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
24094
24554
|
this.config.getCoordinatorAddress()
|
|
24095
24555
|
);
|
|
24096
24556
|
try {
|
|
24097
|
-
return await sparkClient.
|
|
24557
|
+
return await sparkClient.finalize_node_signatures_v2({
|
|
24098
24558
|
intent: 1 /* TRANSFER */,
|
|
24099
24559
|
nodeSignatures
|
|
24100
24560
|
});
|
|
@@ -24133,109 +24593,134 @@ var TransferService = class extends BaseTransferService {
|
|
|
24133
24593
|
throw new Error(`Error querying pending transfers by sender: ${error}`);
|
|
24134
24594
|
}
|
|
24135
24595
|
}
|
|
24136
|
-
async
|
|
24137
|
-
if (nodes.length === 0) {
|
|
24138
|
-
throw Error("no nodes to refresh");
|
|
24139
|
-
}
|
|
24596
|
+
async refreshTimelockNodesInternal(node, parentNode, useTestUnilateralSequence) {
|
|
24140
24597
|
const signingJobs = [];
|
|
24141
|
-
const
|
|
24142
|
-
|
|
24143
|
-
|
|
24144
|
-
|
|
24145
|
-
|
|
24146
|
-
|
|
24147
|
-
|
|
24148
|
-
|
|
24149
|
-
|
|
24150
|
-
|
|
24151
|
-
|
|
24152
|
-
|
|
24153
|
-
|
|
24154
|
-
|
|
24155
|
-
|
|
24156
|
-
|
|
24157
|
-
|
|
24158
|
-
|
|
24159
|
-
|
|
24160
|
-
|
|
24161
|
-
|
|
24162
|
-
|
|
24163
|
-
|
|
24164
|
-
newTx.addOutput(additionalOutput);
|
|
24165
|
-
}
|
|
24166
|
-
}
|
|
24167
|
-
if (i === 0) {
|
|
24168
|
-
const currSequence = input.sequence;
|
|
24169
|
-
newTx.addInput({
|
|
24170
|
-
...input,
|
|
24171
|
-
sequence: getNextTransactionSequence(currSequence).nextSequence
|
|
24172
|
-
});
|
|
24173
|
-
} else {
|
|
24174
|
-
newTx.addInput({
|
|
24175
|
-
...input,
|
|
24176
|
-
sequence: initialSequence(),
|
|
24177
|
-
txid: newNodeTxs[i - 1]?.id
|
|
24178
|
-
});
|
|
24179
|
-
}
|
|
24180
|
-
signingJobs.push({
|
|
24181
|
-
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation({
|
|
24182
|
-
type: "leaf" /* LEAF */,
|
|
24183
|
-
path: node.id
|
|
24184
|
-
}),
|
|
24185
|
-
rawTx: newTx.toBytes(),
|
|
24186
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24598
|
+
const parentNodeTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
24599
|
+
const parentNodeOutput = parentNodeTx.getOutput(0);
|
|
24600
|
+
if (!parentNodeOutput) {
|
|
24601
|
+
throw Error("Could not get parent node output");
|
|
24602
|
+
}
|
|
24603
|
+
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
24604
|
+
const nodeInput = nodeTx.getInput(0);
|
|
24605
|
+
const nodeOutput = nodeTx.getOutput(0);
|
|
24606
|
+
if (!nodeOutput) {
|
|
24607
|
+
throw Error("Could not get node output");
|
|
24608
|
+
}
|
|
24609
|
+
let directNodeTx;
|
|
24610
|
+
let directNodeInput;
|
|
24611
|
+
if (node.directTx.length > 0) {
|
|
24612
|
+
directNodeTx = getTxFromRawTxBytes(node.directTx);
|
|
24613
|
+
directNodeInput = directNodeTx.getInput(0);
|
|
24614
|
+
}
|
|
24615
|
+
const currSequence = nodeInput.sequence;
|
|
24616
|
+
if (!currSequence) {
|
|
24617
|
+
throw new ValidationError("Invalid node transaction", {
|
|
24618
|
+
field: "sequence",
|
|
24619
|
+
value: nodeInput,
|
|
24620
|
+
expected: "Non-null sequence"
|
|
24187
24621
|
});
|
|
24188
|
-
newNodeTxs[i] = newTx;
|
|
24189
24622
|
}
|
|
24190
|
-
|
|
24191
|
-
|
|
24192
|
-
|
|
24623
|
+
let { nextSequence, nextDirectSequence } = getNextTransactionSequence(
|
|
24624
|
+
currSequence,
|
|
24625
|
+
true
|
|
24626
|
+
);
|
|
24627
|
+
const output = {
|
|
24628
|
+
script: parentNodeOutput.script,
|
|
24629
|
+
amount: parentNodeOutput.amount
|
|
24630
|
+
};
|
|
24631
|
+
const newNodeInput = {
|
|
24632
|
+
txid: nodeInput.txid,
|
|
24633
|
+
index: nodeInput.index,
|
|
24634
|
+
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_SEQUENCE : nextSequence
|
|
24635
|
+
};
|
|
24636
|
+
const newDirectInput = directNodeTx && directNodeInput ? {
|
|
24637
|
+
txid: directNodeInput.txid,
|
|
24638
|
+
index: directNodeInput.index,
|
|
24639
|
+
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_DIRECT_SEQUENCE : nextDirectSequence
|
|
24640
|
+
} : void 0;
|
|
24641
|
+
const { cpfpNodeTx, directNodeTx: newDirectNodeTx } = createNodeTxs(
|
|
24642
|
+
output,
|
|
24643
|
+
newNodeInput,
|
|
24644
|
+
newDirectInput
|
|
24645
|
+
);
|
|
24646
|
+
const newCpfpNodeOutput = cpfpNodeTx.getOutput(0);
|
|
24647
|
+
if (!newCpfpNodeOutput) {
|
|
24648
|
+
throw Error("Could not get new cpfp node output");
|
|
24193
24649
|
}
|
|
24194
|
-
const
|
|
24195
|
-
const
|
|
24196
|
-
|
|
24197
|
-
|
|
24650
|
+
const newDirectNodeOutput = newDirectNodeTx?.getOutput(0);
|
|
24651
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
24652
|
+
type: "leaf" /* LEAF */,
|
|
24653
|
+
path: node.id
|
|
24198
24654
|
});
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24203
|
-
|
|
24204
|
-
|
|
24205
|
-
amount: originalRefundOutput.amount
|
|
24655
|
+
signingJobs.push({
|
|
24656
|
+
signingPublicKey,
|
|
24657
|
+
rawTx: cpfpNodeTx.toBytes(),
|
|
24658
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24659
|
+
type: "node",
|
|
24660
|
+
parentTxOut: parentNodeOutput
|
|
24206
24661
|
});
|
|
24207
|
-
|
|
24208
|
-
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
|
|
24213
|
-
|
|
24214
|
-
|
|
24215
|
-
throw Error("refund tx doesn't have input");
|
|
24662
|
+
if (newDirectNodeTx) {
|
|
24663
|
+
signingJobs.push({
|
|
24664
|
+
signingPublicKey,
|
|
24665
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
24666
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24667
|
+
type: "directNode",
|
|
24668
|
+
parentTxOut: parentNodeOutput
|
|
24669
|
+
});
|
|
24216
24670
|
}
|
|
24217
|
-
|
|
24218
|
-
|
|
24671
|
+
const newCpfpRefundOutPoint = {
|
|
24672
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(cpfpNodeTx)),
|
|
24673
|
+
index: 0
|
|
24674
|
+
};
|
|
24675
|
+
let newDirectRefundOutPoint;
|
|
24676
|
+
if (newDirectNodeTx) {
|
|
24677
|
+
newDirectRefundOutPoint = {
|
|
24678
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
24679
|
+
index: 0
|
|
24680
|
+
};
|
|
24219
24681
|
}
|
|
24220
|
-
|
|
24221
|
-
|
|
24222
|
-
|
|
24223
|
-
|
|
24224
|
-
|
|
24225
|
-
|
|
24226
|
-
|
|
24682
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
24683
|
+
sequence: INITIAL_SEQUENCE,
|
|
24684
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
24685
|
+
input: newCpfpRefundOutPoint,
|
|
24686
|
+
directInput: newDirectRefundOutPoint,
|
|
24687
|
+
amountSats: nodeOutput.amount,
|
|
24688
|
+
receivingPubkey: await this.config.signer.getPublicKeyFromDerivation({
|
|
24227
24689
|
type: "leaf" /* LEAF */,
|
|
24228
|
-
path:
|
|
24690
|
+
path: node.id
|
|
24229
24691
|
}),
|
|
24230
|
-
|
|
24231
|
-
|
|
24232
|
-
|
|
24233
|
-
|
|
24692
|
+
network: this.config.getNetwork()
|
|
24693
|
+
});
|
|
24694
|
+
signingJobs.push({
|
|
24695
|
+
signingPublicKey,
|
|
24696
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
24697
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24698
|
+
type: "cpfp",
|
|
24699
|
+
parentTxOut: newCpfpNodeOutput
|
|
24700
|
+
});
|
|
24701
|
+
if (directRefundTx && newDirectNodeOutput) {
|
|
24702
|
+
signingJobs.push({
|
|
24703
|
+
signingPublicKey,
|
|
24704
|
+
rawTx: directRefundTx.toBytes(),
|
|
24705
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24706
|
+
type: "direct",
|
|
24707
|
+
parentTxOut: newDirectNodeOutput
|
|
24708
|
+
});
|
|
24709
|
+
}
|
|
24710
|
+
if (directFromCpfpRefundTx && newCpfpNodeOutput) {
|
|
24711
|
+
signingJobs.push({
|
|
24712
|
+
signingPublicKey,
|
|
24713
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
24714
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
24715
|
+
type: "directFromCpfp",
|
|
24716
|
+
parentTxOut: newCpfpNodeOutput
|
|
24717
|
+
});
|
|
24718
|
+
}
|
|
24234
24719
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
24235
24720
|
this.config.getCoordinatorAddress()
|
|
24236
24721
|
);
|
|
24237
|
-
const response = await sparkClient.
|
|
24238
|
-
leafId:
|
|
24722
|
+
const response = await sparkClient.refresh_timelock_v2({
|
|
24723
|
+
leafId: node.id,
|
|
24239
24724
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
24240
24725
|
signingJobs: signingJobs.map(getSigningJobProto)
|
|
24241
24726
|
});
|
|
@@ -24245,45 +24730,27 @@ var TransferService = class extends BaseTransferService {
|
|
|
24245
24730
|
);
|
|
24246
24731
|
}
|
|
24247
24732
|
let nodeSignatures = [];
|
|
24248
|
-
let
|
|
24249
|
-
let
|
|
24250
|
-
let
|
|
24251
|
-
|
|
24252
|
-
|
|
24733
|
+
let leafCpfpSignature;
|
|
24734
|
+
let leafDirectSignature;
|
|
24735
|
+
let cpfpRefundSignature;
|
|
24736
|
+
let directRefundSignature;
|
|
24737
|
+
let directFromCpfpRefundSignature;
|
|
24738
|
+
for (const [i, signingResult] of response.signingResults.entries()) {
|
|
24253
24739
|
const signingJob = signingJobs[i];
|
|
24254
24740
|
if (!signingJob || !signingResult) {
|
|
24255
24741
|
throw Error("Signing job does not exist");
|
|
24256
24742
|
}
|
|
24257
|
-
if (!signingJob.signingNonceCommitment) {
|
|
24258
|
-
throw Error("nonce commitment does not exist");
|
|
24259
|
-
}
|
|
24260
24743
|
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24264
|
-
if (i === nodes.length) {
|
|
24265
|
-
nodeId = nodes[i - 1]?.id;
|
|
24266
|
-
parentTx = newNodeTxs[i - 1];
|
|
24267
|
-
vout = 0;
|
|
24268
|
-
} else if (i === 0) {
|
|
24269
|
-
nodeId = nodes[i]?.id;
|
|
24270
|
-
parentTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
24271
|
-
vout = nodes[i]?.vout;
|
|
24272
|
-
} else {
|
|
24273
|
-
nodeId = nodes[i]?.id;
|
|
24274
|
-
parentTx = newNodeTxs[i - 1];
|
|
24275
|
-
vout = nodes[i]?.vout;
|
|
24744
|
+
const txOut = signingJob.parentTxOut;
|
|
24745
|
+
if (!txOut) {
|
|
24746
|
+
throw Error("Could not get tx out");
|
|
24276
24747
|
}
|
|
24277
|
-
if (!parentTx || !nodeId || vout === void 0) {
|
|
24278
|
-
throw Error("Could not parse signing results");
|
|
24279
|
-
}
|
|
24280
|
-
const txOut = parentTx.getOutput(vout);
|
|
24281
24748
|
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
24282
24749
|
const userSignature = await this.config.signer.signFrost({
|
|
24283
24750
|
message: rawTxSighash,
|
|
24284
24751
|
keyDerivation: {
|
|
24285
24752
|
type: "leaf" /* LEAF */,
|
|
24286
|
-
path:
|
|
24753
|
+
path: node.id
|
|
24287
24754
|
},
|
|
24288
24755
|
publicKey: signingJob.signingPublicKey,
|
|
24289
24756
|
verifyingKey: signingResult.verifyingKey,
|
|
@@ -24302,41 +24769,35 @@ var TransferService = class extends BaseTransferService {
|
|
|
24302
24769
|
selfSignature: userSignature,
|
|
24303
24770
|
adaptorPubKey: new Uint8Array()
|
|
24304
24771
|
});
|
|
24305
|
-
if (
|
|
24306
|
-
|
|
24307
|
-
|
|
24308
|
-
|
|
24309
|
-
|
|
24310
|
-
|
|
24311
|
-
|
|
24312
|
-
|
|
24313
|
-
|
|
24314
|
-
|
|
24315
|
-
} else if (i === nodes.length) {
|
|
24316
|
-
refundSignature = signature;
|
|
24317
|
-
} else if (i === nodes.length - 1) {
|
|
24318
|
-
leafNodeId = nodeId;
|
|
24319
|
-
leafSignature = signature;
|
|
24772
|
+
if (signingJob.type === "node") {
|
|
24773
|
+
leafCpfpSignature = signature;
|
|
24774
|
+
} else if (signingJob.type === "directNode") {
|
|
24775
|
+
leafDirectSignature = signature;
|
|
24776
|
+
} else if (signingJob.type === "cpfp") {
|
|
24777
|
+
cpfpRefundSignature = signature;
|
|
24778
|
+
} else if (signingJob.type === "direct") {
|
|
24779
|
+
directRefundSignature = signature;
|
|
24780
|
+
} else if (signingJob.type === "directFromCpfp") {
|
|
24781
|
+
directFromCpfpRefundSignature = signature;
|
|
24320
24782
|
}
|
|
24321
24783
|
}
|
|
24322
|
-
if (!leafSignature || !refundSignature || !leafNodeId) {
|
|
24323
|
-
throw Error("leaf or refund signature does not exist");
|
|
24324
|
-
}
|
|
24325
24784
|
nodeSignatures.push({
|
|
24326
|
-
nodeId:
|
|
24327
|
-
nodeTxSignature:
|
|
24328
|
-
|
|
24329
|
-
|
|
24330
|
-
|
|
24331
|
-
|
|
24332
|
-
directFromCpfpRefundTxSignature: new Uint8Array()
|
|
24785
|
+
nodeId: node.id,
|
|
24786
|
+
nodeTxSignature: leafCpfpSignature || new Uint8Array(),
|
|
24787
|
+
directNodeTxSignature: leafDirectSignature || new Uint8Array(),
|
|
24788
|
+
refundTxSignature: cpfpRefundSignature || new Uint8Array(),
|
|
24789
|
+
directRefundTxSignature: directRefundSignature || new Uint8Array(),
|
|
24790
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSignature || new Uint8Array()
|
|
24333
24791
|
});
|
|
24334
|
-
const result = await sparkClient.
|
|
24792
|
+
const result = await sparkClient.finalize_node_signatures_v2({
|
|
24335
24793
|
intent: 3 /* REFRESH */,
|
|
24336
24794
|
nodeSignatures
|
|
24337
24795
|
});
|
|
24338
24796
|
return result;
|
|
24339
24797
|
}
|
|
24798
|
+
async refreshTimelockNodes(node, parentNode) {
|
|
24799
|
+
return await this.refreshTimelockNodesInternal(node, parentNode);
|
|
24800
|
+
}
|
|
24340
24801
|
async extendTimelock(node) {
|
|
24341
24802
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
24342
24803
|
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
@@ -24345,7 +24806,10 @@ var TransferService = class extends BaseTransferService {
|
|
|
24345
24806
|
txid: (0, import_utils8.hexToBytes)(getTxId(nodeTx)),
|
|
24346
24807
|
index: 0
|
|
24347
24808
|
};
|
|
24348
|
-
const {
|
|
24809
|
+
const {
|
|
24810
|
+
nextSequence: newNodeSequence,
|
|
24811
|
+
nextDirectSequence: newDirectNodeSequence
|
|
24812
|
+
} = getNextTransactionSequence(refundSequence);
|
|
24349
24813
|
const newNodeTx = new import_btc_signer2.Transaction({
|
|
24350
24814
|
version: 3,
|
|
24351
24815
|
allowUnknownOutputs: true
|
|
@@ -24358,81 +24822,122 @@ var TransferService = class extends BaseTransferService {
|
|
|
24358
24822
|
newNodeTx.addOutput({
|
|
24359
24823
|
script: originalOutput.script,
|
|
24360
24824
|
amount: originalOutput.amount
|
|
24361
|
-
// feeReducedAmount,
|
|
24362
24825
|
});
|
|
24363
24826
|
newNodeTx.addOutput(getEphemeralAnchorOutput());
|
|
24364
|
-
|
|
24827
|
+
let newDirectNodeTx;
|
|
24828
|
+
if (node.directTx.length > 0) {
|
|
24829
|
+
newDirectNodeTx = new import_btc_signer2.Transaction({
|
|
24830
|
+
version: 3,
|
|
24831
|
+
allowUnknownOutputs: true
|
|
24832
|
+
});
|
|
24833
|
+
newDirectNodeTx.addInput({
|
|
24834
|
+
...newNodeOutPoint,
|
|
24835
|
+
sequence: newDirectNodeSequence
|
|
24836
|
+
});
|
|
24837
|
+
newDirectNodeTx.addOutput({
|
|
24838
|
+
script: originalOutput.script,
|
|
24839
|
+
amount: maybeApplyFee(originalOutput.amount)
|
|
24840
|
+
});
|
|
24841
|
+
}
|
|
24842
|
+
const newCpfpRefundOutPoint = {
|
|
24365
24843
|
txid: (0, import_utils8.hexToBytes)(getTxId(newNodeTx)),
|
|
24366
24844
|
index: 0
|
|
24367
24845
|
};
|
|
24846
|
+
let newDirectRefundOutPoint;
|
|
24847
|
+
if (newDirectNodeTx) {
|
|
24848
|
+
newDirectRefundOutPoint = {
|
|
24849
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
24850
|
+
index: 0
|
|
24851
|
+
};
|
|
24852
|
+
}
|
|
24368
24853
|
const amountSats = refundTx.getOutput(0).amount;
|
|
24369
24854
|
if (amountSats === void 0) {
|
|
24370
24855
|
throw new Error("Amount not found in extendTimelock");
|
|
24371
24856
|
}
|
|
24372
|
-
const
|
|
24857
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
24373
24858
|
type: "leaf" /* LEAF */,
|
|
24374
24859
|
path: node.id
|
|
24375
24860
|
});
|
|
24376
|
-
const
|
|
24377
|
-
|
|
24378
|
-
|
|
24861
|
+
const {
|
|
24862
|
+
cpfpRefundTx: newCpfpRefundTx,
|
|
24863
|
+
directRefundTx: newDirectRefundTx,
|
|
24864
|
+
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
24865
|
+
} = createRefundTxs({
|
|
24866
|
+
sequence: INITIAL_SEQUENCE,
|
|
24867
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
24868
|
+
input: newCpfpRefundOutPoint,
|
|
24869
|
+
directInput: newDirectRefundOutPoint,
|
|
24379
24870
|
amountSats,
|
|
24380
|
-
|
|
24381
|
-
|
|
24382
|
-
|
|
24383
|
-
)
|
|
24871
|
+
receivingPubkey: signingPublicKey,
|
|
24872
|
+
network: this.config.getNetwork()
|
|
24873
|
+
});
|
|
24874
|
+
if (!newCpfpRefundTx) {
|
|
24875
|
+
throw new ValidationError(
|
|
24876
|
+
"Failed to create refund transactions in extendTimelock"
|
|
24877
|
+
);
|
|
24878
|
+
}
|
|
24384
24879
|
const nodeSighash = getSigHashFromTx(newNodeTx, 0, nodeTx.getOutput(0));
|
|
24385
|
-
const
|
|
24386
|
-
|
|
24880
|
+
const directNodeSighash = newDirectNodeTx ? getSigHashFromTx(newDirectNodeTx, 0, nodeTx.getOutput(0)) : void 0;
|
|
24881
|
+
const cpfpRefundSighash = getSigHashFromTx(
|
|
24882
|
+
newCpfpRefundTx,
|
|
24387
24883
|
0,
|
|
24388
24884
|
newNodeTx.getOutput(0)
|
|
24389
24885
|
);
|
|
24886
|
+
const directRefundSighash = newDirectNodeTx && newDirectRefundTx ? getSigHashFromTx(newDirectRefundTx, 0, newDirectNodeTx.getOutput(0)) : void 0;
|
|
24887
|
+
const directFromCpfpRefundSighash = newDirectFromCpfpRefundTx ? getSigHashFromTx(newDirectFromCpfpRefundTx, 0, newNodeTx.getOutput(0)) : void 0;
|
|
24390
24888
|
const newNodeSigningJob = {
|
|
24391
|
-
signingPublicKey
|
|
24889
|
+
signingPublicKey,
|
|
24392
24890
|
rawTx: newNodeTx.toBytes(),
|
|
24393
24891
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24394
24892
|
};
|
|
24395
|
-
const
|
|
24396
|
-
signingPublicKey
|
|
24397
|
-
rawTx:
|
|
24893
|
+
const newDirectNodeSigningJob = newDirectNodeTx ? {
|
|
24894
|
+
signingPublicKey,
|
|
24895
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
24896
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24897
|
+
} : void 0;
|
|
24898
|
+
const newCpfpRefundSigningJob = {
|
|
24899
|
+
signingPublicKey,
|
|
24900
|
+
rawTx: newCpfpRefundTx.toBytes(),
|
|
24398
24901
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24399
24902
|
};
|
|
24903
|
+
const newDirectRefundSigningJob = newDirectRefundTx ? {
|
|
24904
|
+
signingPublicKey,
|
|
24905
|
+
rawTx: newDirectRefundTx.toBytes(),
|
|
24906
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24907
|
+
} : void 0;
|
|
24908
|
+
const newDirectFromCpfpRefundSigningJob = newDirectFromCpfpRefundTx ? {
|
|
24909
|
+
signingPublicKey,
|
|
24910
|
+
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
24911
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24912
|
+
} : void 0;
|
|
24400
24913
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
24401
24914
|
this.config.getCoordinatorAddress()
|
|
24402
24915
|
);
|
|
24403
|
-
const response = await sparkClient.
|
|
24916
|
+
const response = await sparkClient.extend_leaf_v2({
|
|
24404
24917
|
leafId: node.id,
|
|
24405
24918
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
24406
24919
|
nodeTxSigningJob: getSigningJobProto(newNodeSigningJob),
|
|
24407
|
-
|
|
24920
|
+
directNodeTxSigningJob: newDirectNodeSigningJob ? getSigningJobProto(newDirectNodeSigningJob) : void 0,
|
|
24921
|
+
refundTxSigningJob: getSigningJobProto(newCpfpRefundSigningJob),
|
|
24922
|
+
directRefundTxSigningJob: newDirectRefundSigningJob ? getSigningJobProto(newDirectRefundSigningJob) : void 0,
|
|
24923
|
+
directFromCpfpRefundTxSigningJob: newDirectFromCpfpRefundSigningJob ? getSigningJobProto(newDirectFromCpfpRefundSigningJob) : void 0
|
|
24408
24924
|
});
|
|
24409
24925
|
if (!response.nodeTxSigningResult || !response.refundTxSigningResult) {
|
|
24410
24926
|
throw new Error("Signing result does not exist");
|
|
24411
24927
|
}
|
|
24928
|
+
const keyDerivation = {
|
|
24929
|
+
type: "leaf" /* LEAF */,
|
|
24930
|
+
path: node.id
|
|
24931
|
+
};
|
|
24412
24932
|
const nodeUserSig = await this.config.signer.signFrost({
|
|
24413
24933
|
message: nodeSighash,
|
|
24414
|
-
keyDerivation
|
|
24415
|
-
|
|
24416
|
-
path: node.id
|
|
24417
|
-
},
|
|
24418
|
-
publicKey: signingPubKey,
|
|
24934
|
+
keyDerivation,
|
|
24935
|
+
publicKey: signingPublicKey,
|
|
24419
24936
|
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
24420
24937
|
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
24421
24938
|
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24422
24939
|
adaptorPubKey: new Uint8Array()
|
|
24423
24940
|
});
|
|
24424
|
-
const refundUserSig = await this.config.signer.signFrost({
|
|
24425
|
-
message: refundSighash,
|
|
24426
|
-
keyDerivation: {
|
|
24427
|
-
type: "leaf" /* LEAF */,
|
|
24428
|
-
path: node.id
|
|
24429
|
-
},
|
|
24430
|
-
publicKey: signingPubKey,
|
|
24431
|
-
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
24432
|
-
selfCommitment: newRefundSigningJob.signingNonceCommitment,
|
|
24433
|
-
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24434
|
-
adaptorPubKey: new Uint8Array()
|
|
24435
|
-
});
|
|
24436
24941
|
const nodeSig = await this.config.signer.aggregateFrost({
|
|
24437
24942
|
message: nodeSighash,
|
|
24438
24943
|
statechainSignatures: response.nodeTxSigningResult.signingResult?.signatureShares,
|
|
@@ -24440,122 +24945,253 @@ var TransferService = class extends BaseTransferService {
|
|
|
24440
24945
|
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
24441
24946
|
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24442
24947
|
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
24443
|
-
publicKey:
|
|
24948
|
+
publicKey: signingPublicKey,
|
|
24444
24949
|
selfSignature: nodeUserSig,
|
|
24445
24950
|
adaptorPubKey: new Uint8Array()
|
|
24446
24951
|
});
|
|
24447
|
-
|
|
24448
|
-
|
|
24952
|
+
let directNodeSig;
|
|
24953
|
+
if (directNodeSighash && newDirectNodeSigningJob && response.directNodeTxSigningResult) {
|
|
24954
|
+
const directNodeUserSig = await this.config.signer.signFrost({
|
|
24955
|
+
message: directNodeSighash,
|
|
24956
|
+
keyDerivation,
|
|
24957
|
+
publicKey: signingPublicKey,
|
|
24958
|
+
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
24959
|
+
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
24960
|
+
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24961
|
+
adaptorPubKey: new Uint8Array()
|
|
24962
|
+
});
|
|
24963
|
+
directNodeSig = await this.config.signer.aggregateFrost({
|
|
24964
|
+
message: directNodeSighash,
|
|
24965
|
+
statechainSignatures: response.directNodeTxSigningResult.signingResult?.signatureShares,
|
|
24966
|
+
statechainPublicKeys: response.directNodeTxSigningResult.signingResult?.publicKeys,
|
|
24967
|
+
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
24968
|
+
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24969
|
+
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
24970
|
+
publicKey: signingPublicKey,
|
|
24971
|
+
selfSignature: directNodeUserSig,
|
|
24972
|
+
adaptorPubKey: new Uint8Array()
|
|
24973
|
+
});
|
|
24974
|
+
}
|
|
24975
|
+
const cpfpRefundUserSig = await this.config.signer.signFrost({
|
|
24976
|
+
message: cpfpRefundSighash,
|
|
24977
|
+
keyDerivation,
|
|
24978
|
+
publicKey: signingPublicKey,
|
|
24979
|
+
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
24980
|
+
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
24981
|
+
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24982
|
+
adaptorPubKey: new Uint8Array()
|
|
24983
|
+
});
|
|
24984
|
+
const cpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
24985
|
+
message: cpfpRefundSighash,
|
|
24449
24986
|
statechainSignatures: response.refundTxSigningResult.signingResult?.signatureShares,
|
|
24450
24987
|
statechainPublicKeys: response.refundTxSigningResult.signingResult?.publicKeys,
|
|
24451
24988
|
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
24452
24989
|
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
24453
|
-
selfCommitment:
|
|
24454
|
-
publicKey:
|
|
24455
|
-
selfSignature:
|
|
24990
|
+
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
24991
|
+
publicKey: signingPublicKey,
|
|
24992
|
+
selfSignature: cpfpRefundUserSig,
|
|
24456
24993
|
adaptorPubKey: new Uint8Array()
|
|
24457
24994
|
});
|
|
24458
|
-
|
|
24459
|
-
|
|
24995
|
+
let directRefundSig;
|
|
24996
|
+
if (directRefundSighash && newDirectRefundSigningJob && response.directRefundTxSigningResult) {
|
|
24997
|
+
const directRefundUserSig = await this.config.signer.signFrost({
|
|
24998
|
+
message: directRefundSighash,
|
|
24999
|
+
keyDerivation,
|
|
25000
|
+
publicKey: signingPublicKey,
|
|
25001
|
+
verifyingKey: response.directRefundTxSigningResult.verifyingKey,
|
|
25002
|
+
selfCommitment: newDirectRefundSigningJob.signingNonceCommitment,
|
|
25003
|
+
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25004
|
+
adaptorPubKey: new Uint8Array()
|
|
25005
|
+
});
|
|
25006
|
+
directRefundSig = await this.config.signer.aggregateFrost({
|
|
25007
|
+
message: directRefundSighash,
|
|
25008
|
+
statechainSignatures: response.directRefundTxSigningResult.signingResult?.signatureShares,
|
|
25009
|
+
statechainPublicKeys: response.directRefundTxSigningResult.signingResult?.publicKeys,
|
|
25010
|
+
verifyingKey: response.directRefundTxSigningResult.verifyingKey,
|
|
25011
|
+
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25012
|
+
selfCommitment: newDirectRefundSigningJob.signingNonceCommitment,
|
|
25013
|
+
publicKey: signingPublicKey,
|
|
25014
|
+
selfSignature: directRefundUserSig,
|
|
25015
|
+
adaptorPubKey: new Uint8Array()
|
|
25016
|
+
});
|
|
25017
|
+
}
|
|
25018
|
+
let directFromCpfpRefundSig;
|
|
25019
|
+
if (directFromCpfpRefundSighash && newDirectFromCpfpRefundSigningJob && response.directFromCpfpRefundTxSigningResult) {
|
|
25020
|
+
const directFromCpfpRefundUserSig = await this.config.signer.signFrost({
|
|
25021
|
+
message: directFromCpfpRefundSighash,
|
|
25022
|
+
keyDerivation,
|
|
25023
|
+
publicKey: signingPublicKey,
|
|
25024
|
+
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
25025
|
+
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
25026
|
+
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25027
|
+
adaptorPubKey: new Uint8Array()
|
|
25028
|
+
});
|
|
25029
|
+
directFromCpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
25030
|
+
message: directFromCpfpRefundSighash,
|
|
25031
|
+
statechainSignatures: response.directFromCpfpRefundTxSigningResult.signingResult?.signatureShares,
|
|
25032
|
+
statechainPublicKeys: response.directFromCpfpRefundTxSigningResult.signingResult?.publicKeys,
|
|
25033
|
+
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
25034
|
+
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
25035
|
+
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
25036
|
+
publicKey: signingPublicKey,
|
|
25037
|
+
selfSignature: directFromCpfpRefundUserSig,
|
|
25038
|
+
adaptorPubKey: new Uint8Array()
|
|
25039
|
+
});
|
|
25040
|
+
}
|
|
25041
|
+
return await sparkClient.finalize_node_signatures_v2({
|
|
25042
|
+
intent: 4 /* EXTEND */,
|
|
24460
25043
|
nodeSignatures: [
|
|
24461
25044
|
{
|
|
24462
25045
|
nodeId: response.leafId,
|
|
24463
25046
|
nodeTxSignature: nodeSig,
|
|
24464
|
-
|
|
25047
|
+
directNodeTxSignature: directNodeSig,
|
|
25048
|
+
refundTxSignature: cpfpRefundSig,
|
|
25049
|
+
directRefundTxSignature: directRefundSig,
|
|
25050
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSig
|
|
24465
25051
|
}
|
|
24466
25052
|
]
|
|
24467
25053
|
});
|
|
24468
25054
|
}
|
|
24469
|
-
async
|
|
25055
|
+
async testonly_expireTimeLockNodeTx(node, parentNode) {
|
|
25056
|
+
return await this.refreshTimelockNodesInternal(node, parentNode, true);
|
|
25057
|
+
}
|
|
25058
|
+
async testonly_expireTimeLockRefundtx(node) {
|
|
24470
25059
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
24471
|
-
const
|
|
24472
|
-
const
|
|
24473
|
-
const
|
|
24474
|
-
const
|
|
25060
|
+
const directNodeTx = node.directTx.length > 0 ? getTxFromRawTxBytes(node.directTx) : void 0;
|
|
25061
|
+
const cpfpRefundTx = getTxFromRawTxBytes(node.refundTx);
|
|
25062
|
+
const currSequence = cpfpRefundTx.getInput(0).sequence || 0;
|
|
25063
|
+
const currTimelock = getCurrentTimelock(currSequence);
|
|
25064
|
+
if (currTimelock <= 100) {
|
|
25065
|
+
throw new ValidationError("Cannot expire timelock below 100", {
|
|
25066
|
+
field: "currTimelock",
|
|
25067
|
+
value: currTimelock,
|
|
25068
|
+
expected: "Timelock greater than 100"
|
|
25069
|
+
});
|
|
25070
|
+
}
|
|
25071
|
+
const nextSequence = TEST_UNILATERAL_SEQUENCE;
|
|
25072
|
+
const nextDirectSequence = TEST_UNILATERAL_SEQUENCE + DIRECT_TIMELOCK_OFFSET;
|
|
25073
|
+
const nodeOutput = nodeTx.getOutput(0);
|
|
25074
|
+
if (!nodeOutput) {
|
|
25075
|
+
throw Error("Could not get node output");
|
|
25076
|
+
}
|
|
25077
|
+
const keyDerivation = {
|
|
24475
25078
|
type: "leaf" /* LEAF */,
|
|
24476
25079
|
path: node.id
|
|
24477
|
-
}
|
|
24478
|
-
const
|
|
24479
|
-
|
|
24480
|
-
|
|
24481
|
-
|
|
24482
|
-
|
|
24483
|
-
|
|
24484
|
-
|
|
25080
|
+
};
|
|
25081
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
25082
|
+
const cpfpRefundOutPoint = {
|
|
25083
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(nodeTx)),
|
|
25084
|
+
index: 0
|
|
25085
|
+
};
|
|
25086
|
+
let directRefundOutPoint;
|
|
25087
|
+
if (directNodeTx) {
|
|
25088
|
+
directRefundOutPoint = {
|
|
25089
|
+
txid: (0, import_utils8.hexToBytes)(getTxId(directNodeTx)),
|
|
25090
|
+
index: 0
|
|
25091
|
+
};
|
|
24485
25092
|
}
|
|
24486
|
-
|
|
24487
|
-
|
|
24488
|
-
|
|
25093
|
+
const {
|
|
25094
|
+
cpfpRefundTx: newCpfpRefundTx,
|
|
25095
|
+
directRefundTx: newDirectRefundTx,
|
|
25096
|
+
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
25097
|
+
} = createRefundTxs({
|
|
25098
|
+
sequence: nextSequence,
|
|
25099
|
+
directSequence: nextDirectSequence,
|
|
25100
|
+
input: cpfpRefundOutPoint,
|
|
25101
|
+
directInput: directRefundOutPoint,
|
|
25102
|
+
amountSats: nodeOutput.amount,
|
|
25103
|
+
receivingPubkey: signingPublicKey,
|
|
25104
|
+
network: this.config.getNetwork()
|
|
24489
25105
|
});
|
|
24490
|
-
|
|
24491
|
-
|
|
24492
|
-
|
|
24493
|
-
|
|
24494
|
-
|
|
25106
|
+
const signingJobs = [];
|
|
25107
|
+
signingJobs.push({
|
|
25108
|
+
signingPublicKey,
|
|
25109
|
+
rawTx: newCpfpRefundTx.toBytes(),
|
|
25110
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25111
|
+
type: "cpfp",
|
|
25112
|
+
parentTxOut: nodeOutput
|
|
25113
|
+
});
|
|
25114
|
+
const directNodeTxOut = directNodeTx?.getOutput(0);
|
|
25115
|
+
if (newDirectRefundTx && directNodeTxOut) {
|
|
25116
|
+
signingJobs.push({
|
|
25117
|
+
signingPublicKey,
|
|
25118
|
+
rawTx: newDirectRefundTx.toBytes(),
|
|
25119
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25120
|
+
type: "direct",
|
|
25121
|
+
parentTxOut: directNodeTxOut
|
|
25122
|
+
});
|
|
24495
25123
|
}
|
|
24496
|
-
|
|
24497
|
-
|
|
24498
|
-
|
|
25124
|
+
if (newDirectFromCpfpRefundTx) {
|
|
25125
|
+
signingJobs.push({
|
|
25126
|
+
signingPublicKey,
|
|
25127
|
+
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
25128
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
25129
|
+
type: "directFromCpfp",
|
|
25130
|
+
parentTxOut: nodeOutput
|
|
25131
|
+
});
|
|
24499
25132
|
}
|
|
24500
|
-
newRefundTx.addInput({
|
|
24501
|
-
...refundTxInput,
|
|
24502
|
-
sequence: nextSequence
|
|
24503
|
-
});
|
|
24504
|
-
const refundSigningJob = {
|
|
24505
|
-
signingPublicKey: signingPubKey,
|
|
24506
|
-
rawTx: newRefundTx.toBytes(),
|
|
24507
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
24508
|
-
};
|
|
24509
25133
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
24510
25134
|
this.config.getCoordinatorAddress()
|
|
24511
25135
|
);
|
|
24512
|
-
const response = await sparkClient.
|
|
25136
|
+
const response = await sparkClient.refresh_timelock_v2({
|
|
24513
25137
|
leafId: node.id,
|
|
24514
25138
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
24515
|
-
signingJobs:
|
|
25139
|
+
signingJobs: signingJobs.map(getSigningJobProto)
|
|
24516
25140
|
});
|
|
24517
|
-
if (response.signingResults.length !==
|
|
25141
|
+
if (response.signingResults.length !== signingJobs.length) {
|
|
24518
25142
|
throw Error(
|
|
24519
|
-
`Expected
|
|
25143
|
+
`Expected ${signingJobs.length} signing results, got ${response.signingResults.length}`
|
|
24520
25144
|
);
|
|
24521
25145
|
}
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
|
|
25146
|
+
let cpfpRefundSignature;
|
|
25147
|
+
let directRefundSignature;
|
|
25148
|
+
let directFromCpfpRefundSignature;
|
|
25149
|
+
for (const [i, signingJob] of signingJobs.entries()) {
|
|
25150
|
+
const signingResult = response.signingResults[i];
|
|
25151
|
+
if (!signingResult) {
|
|
25152
|
+
throw Error("Signing result does not exist");
|
|
25153
|
+
}
|
|
25154
|
+
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
25155
|
+
const txOut = signingJob.parentTxOut;
|
|
25156
|
+
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
25157
|
+
const userSignature = await this.config.signer.signFrost({
|
|
25158
|
+
message: rawTxSighash,
|
|
25159
|
+
keyDerivation,
|
|
25160
|
+
publicKey: signingPublicKey,
|
|
25161
|
+
verifyingKey: signingResult.verifyingKey,
|
|
25162
|
+
selfCommitment: signingJob.signingNonceCommitment,
|
|
25163
|
+
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
25164
|
+
adaptorPubKey: new Uint8Array()
|
|
25165
|
+
});
|
|
25166
|
+
const signature = await this.config.signer.aggregateFrost({
|
|
25167
|
+
message: rawTxSighash,
|
|
25168
|
+
statechainSignatures: signingResult.signingResult?.signatureShares,
|
|
25169
|
+
statechainPublicKeys: signingResult.signingResult?.publicKeys,
|
|
25170
|
+
verifyingKey: signingResult.verifyingKey,
|
|
25171
|
+
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
25172
|
+
selfCommitment: signingJob.signingNonceCommitment,
|
|
25173
|
+
publicKey: signingPublicKey,
|
|
25174
|
+
selfSignature: userSignature,
|
|
25175
|
+
adaptorPubKey: new Uint8Array()
|
|
25176
|
+
});
|
|
25177
|
+
if (signingJob.type === "cpfp") {
|
|
25178
|
+
cpfpRefundSignature = signature;
|
|
25179
|
+
} else if (signingJob.type === "direct") {
|
|
25180
|
+
directRefundSignature = signature;
|
|
25181
|
+
} else if (signingJob.type === "directFromCpfp") {
|
|
25182
|
+
directFromCpfpRefundSignature = signature;
|
|
25183
|
+
}
|
|
24525
25184
|
}
|
|
24526
|
-
const
|
|
24527
|
-
const txOut = nodeTx.getOutput(0);
|
|
24528
|
-
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
24529
|
-
const userSignature = await this.config.signer.signFrost({
|
|
24530
|
-
message: rawTxSighash,
|
|
24531
|
-
keyDerivation: {
|
|
24532
|
-
type: "leaf" /* LEAF */,
|
|
24533
|
-
path: node.id
|
|
24534
|
-
},
|
|
24535
|
-
publicKey: signingPubKey,
|
|
24536
|
-
verifyingKey: signingResult.verifyingKey,
|
|
24537
|
-
selfCommitment: refundSigningJob.signingNonceCommitment,
|
|
24538
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
24539
|
-
adaptorPubKey: new Uint8Array()
|
|
24540
|
-
});
|
|
24541
|
-
const signature = await this.config.signer.aggregateFrost({
|
|
24542
|
-
message: rawTxSighash,
|
|
24543
|
-
statechainSignatures: signingResult.signingResult?.signatureShares,
|
|
24544
|
-
statechainPublicKeys: signingResult.signingResult?.publicKeys,
|
|
24545
|
-
verifyingKey: signingResult.verifyingKey,
|
|
24546
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
24547
|
-
selfCommitment: refundSigningJob.signingNonceCommitment,
|
|
24548
|
-
publicKey: signingPubKey,
|
|
24549
|
-
selfSignature: userSignature,
|
|
24550
|
-
adaptorPubKey: new Uint8Array()
|
|
24551
|
-
});
|
|
24552
|
-
const result = await sparkClient.finalize_node_signatures({
|
|
25185
|
+
const result = await sparkClient.finalize_node_signatures_v2({
|
|
24553
25186
|
intent: 3 /* REFRESH */,
|
|
24554
25187
|
nodeSignatures: [
|
|
24555
25188
|
{
|
|
24556
25189
|
nodeId: node.id,
|
|
24557
25190
|
nodeTxSignature: new Uint8Array(),
|
|
24558
|
-
|
|
25191
|
+
directNodeTxSignature: new Uint8Array(),
|
|
25192
|
+
refundTxSignature: cpfpRefundSignature,
|
|
25193
|
+
directRefundTxSignature: directRefundSignature,
|
|
25194
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundSignature
|
|
24559
25195
|
}
|
|
24560
25196
|
]
|
|
24561
25197
|
});
|
|
@@ -24574,7 +25210,12 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
24574
25210
|
connectorOutputs,
|
|
24575
25211
|
receiverPubKey
|
|
24576
25212
|
}) {
|
|
24577
|
-
const {
|
|
25213
|
+
const {
|
|
25214
|
+
transfer,
|
|
25215
|
+
signaturesMap,
|
|
25216
|
+
directSignaturesMap,
|
|
25217
|
+
directFromCpfpSignaturesMap
|
|
25218
|
+
} = await this.signCoopExitRefunds(
|
|
24578
25219
|
leaves,
|
|
24579
25220
|
exitTxId,
|
|
24580
25221
|
connectorOutputs,
|
|
@@ -24583,34 +25224,81 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
24583
25224
|
const transferTweak = await this.deliverTransferPackage(
|
|
24584
25225
|
transfer,
|
|
24585
25226
|
leaves,
|
|
24586
|
-
signaturesMap
|
|
25227
|
+
signaturesMap,
|
|
25228
|
+
directSignaturesMap,
|
|
25229
|
+
directFromCpfpSignaturesMap
|
|
24587
25230
|
);
|
|
24588
|
-
return {
|
|
24589
|
-
|
|
24590
|
-
|
|
24591
|
-
|
|
24592
|
-
|
|
24593
|
-
|
|
24594
|
-
|
|
24595
|
-
|
|
25231
|
+
return {
|
|
25232
|
+
transfer: transferTweak,
|
|
25233
|
+
signaturesMap,
|
|
25234
|
+
directSignaturesMap,
|
|
25235
|
+
directFromCpfpSignaturesMap
|
|
25236
|
+
};
|
|
25237
|
+
}
|
|
25238
|
+
createConnectorRefundTransactions(sequence, directSequence, cpfpNodeOutPoint, directNodeOutPoint, connectorOutput, amountSats, receiverPubKey) {
|
|
25239
|
+
const cpfpRefundTx = new import_btc_signer3.Transaction();
|
|
25240
|
+
if (!cpfpNodeOutPoint.txid || cpfpNodeOutPoint.index === void 0) {
|
|
25241
|
+
throw new ValidationError("Invalid CPFP node outpoint", {
|
|
25242
|
+
field: "cpfpNodeOutPoint",
|
|
25243
|
+
value: { txid: cpfpNodeOutPoint.txid, index: cpfpNodeOutPoint.index },
|
|
24596
25244
|
expected: "Both txid and index must be defined"
|
|
24597
25245
|
});
|
|
24598
25246
|
}
|
|
24599
|
-
|
|
24600
|
-
txid:
|
|
24601
|
-
index:
|
|
25247
|
+
cpfpRefundTx.addInput({
|
|
25248
|
+
txid: cpfpNodeOutPoint.txid,
|
|
25249
|
+
index: cpfpNodeOutPoint.index,
|
|
24602
25250
|
sequence
|
|
24603
25251
|
});
|
|
24604
|
-
|
|
25252
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
24605
25253
|
const receiverScript = getP2TRScriptFromPublicKey(
|
|
24606
25254
|
receiverPubKey,
|
|
24607
25255
|
this.config.getNetwork()
|
|
24608
25256
|
);
|
|
24609
|
-
|
|
25257
|
+
cpfpRefundTx.addOutput({
|
|
24610
25258
|
script: receiverScript,
|
|
24611
25259
|
amount: amountSats
|
|
24612
25260
|
});
|
|
24613
|
-
|
|
25261
|
+
let directRefundTx;
|
|
25262
|
+
let directFromCpfpRefundTx;
|
|
25263
|
+
if (directNodeOutPoint) {
|
|
25264
|
+
if (!directNodeOutPoint.txid || directNodeOutPoint.index === void 0) {
|
|
25265
|
+
throw new ValidationError("Invalid direct node outpoint", {
|
|
25266
|
+
field: "directNodeOutPoint",
|
|
25267
|
+
value: {
|
|
25268
|
+
txid: directNodeOutPoint.txid,
|
|
25269
|
+
index: directNodeOutPoint.index
|
|
25270
|
+
},
|
|
25271
|
+
expected: "Both txid and index must be defined"
|
|
25272
|
+
});
|
|
25273
|
+
}
|
|
25274
|
+
directRefundTx = new import_btc_signer3.Transaction();
|
|
25275
|
+
directRefundTx.addInput({
|
|
25276
|
+
txid: directNodeOutPoint.txid,
|
|
25277
|
+
index: directNodeOutPoint.index,
|
|
25278
|
+
sequence: directSequence
|
|
25279
|
+
});
|
|
25280
|
+
directRefundTx.addInput(connectorOutput);
|
|
25281
|
+
directRefundTx.addOutput({
|
|
25282
|
+
script: receiverScript,
|
|
25283
|
+
amount: maybeApplyFee(amountSats)
|
|
25284
|
+
});
|
|
25285
|
+
directFromCpfpRefundTx = new import_btc_signer3.Transaction();
|
|
25286
|
+
directFromCpfpRefundTx.addInput({
|
|
25287
|
+
txid: cpfpNodeOutPoint.txid,
|
|
25288
|
+
index: cpfpNodeOutPoint.index,
|
|
25289
|
+
sequence: directSequence
|
|
25290
|
+
});
|
|
25291
|
+
directFromCpfpRefundTx.addInput(connectorOutput);
|
|
25292
|
+
directFromCpfpRefundTx.addOutput({
|
|
25293
|
+
script: receiverScript,
|
|
25294
|
+
amount: maybeApplyFee(amountSats)
|
|
25295
|
+
});
|
|
25296
|
+
}
|
|
25297
|
+
return {
|
|
25298
|
+
cpfpRefundTx,
|
|
25299
|
+
directRefundTx,
|
|
25300
|
+
directFromCpfpRefundTx
|
|
25301
|
+
};
|
|
24614
25302
|
}
|
|
24615
25303
|
async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey) {
|
|
24616
25304
|
if (leaves.length !== connectorOutputs.length) {
|
|
@@ -24646,39 +25334,67 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
24646
25334
|
});
|
|
24647
25335
|
}
|
|
24648
25336
|
const currentRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
24649
|
-
const
|
|
24650
|
-
|
|
24651
|
-
|
|
24652
|
-
|
|
25337
|
+
const sequence = currentRefundTx.getInput(0).sequence;
|
|
25338
|
+
if (!sequence) {
|
|
25339
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
25340
|
+
field: "sequence",
|
|
25341
|
+
value: currentRefundTx.getInput(0),
|
|
25342
|
+
expected: "Non-null sequence"
|
|
25343
|
+
});
|
|
25344
|
+
}
|
|
25345
|
+
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
25346
|
+
let currentDirectRefundTx;
|
|
25347
|
+
if (leaf.leaf.directRefundTx.length > 0) {
|
|
25348
|
+
currentDirectRefundTx = getTxFromRawTxBytes(leaf.leaf.directRefundTx);
|
|
25349
|
+
}
|
|
25350
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = this.createConnectorRefundTransactions(
|
|
24653
25351
|
nextSequence,
|
|
25352
|
+
nextDirectSequence,
|
|
24654
25353
|
currentRefundTx.getInput(0),
|
|
25354
|
+
currentDirectRefundTx?.getInput(0),
|
|
24655
25355
|
connectorOutput,
|
|
24656
25356
|
BigInt(leaf.leaf.value),
|
|
24657
25357
|
receiverPubKey
|
|
24658
25358
|
);
|
|
24659
25359
|
const signingNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25360
|
+
const directSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25361
|
+
const directFromCpfpSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25362
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(leaf.keyDerivation);
|
|
24660
25363
|
const signingJob = {
|
|
24661
25364
|
leafId: leaf.leaf.id,
|
|
24662
25365
|
refundTxSigningJob: {
|
|
24663
25366
|
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
24664
25367
|
leaf.keyDerivation
|
|
24665
25368
|
),
|
|
24666
|
-
rawTx:
|
|
25369
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
24667
25370
|
signingNonceCommitment: signingNonceCommitment.commitment
|
|
24668
25371
|
},
|
|
24669
|
-
|
|
24670
|
-
|
|
24671
|
-
|
|
25372
|
+
directRefundTxSigningJob: directRefundTx ? {
|
|
25373
|
+
signingPublicKey,
|
|
25374
|
+
rawTx: directRefundTx.toBytes(),
|
|
25375
|
+
signingNonceCommitment: directSigningNonceCommitment.commitment
|
|
25376
|
+
} : void 0,
|
|
25377
|
+
directFromCpfpRefundTxSigningJob: directFromCpfpRefundTx ? {
|
|
25378
|
+
signingPublicKey,
|
|
25379
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
25380
|
+
signingNonceCommitment: directFromCpfpSigningNonceCommitment.commitment
|
|
25381
|
+
} : void 0
|
|
24672
25382
|
};
|
|
24673
25383
|
signingJobs.push(signingJob);
|
|
24674
25384
|
const tx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
25385
|
+
const directTx = leaf.leaf.directTx.length > 0 ? getTxFromRawTxBytes(leaf.leaf.directTx) : void 0;
|
|
24675
25386
|
leafDataMap.set(leaf.leaf.id, {
|
|
24676
25387
|
keyDerivation: leaf.keyDerivation,
|
|
24677
|
-
|
|
25388
|
+
receivingPubkey: receiverPubKey,
|
|
24678
25389
|
signingNonceCommitment,
|
|
25390
|
+
directSigningNonceCommitment,
|
|
24679
25391
|
tx,
|
|
24680
|
-
|
|
24681
|
-
|
|
25392
|
+
directTx,
|
|
25393
|
+
refundTx: cpfpRefundTx,
|
|
25394
|
+
directRefundTx,
|
|
25395
|
+
directFromCpfpRefundTx,
|
|
25396
|
+
directFromCpfpRefundSigningNonceCommitment: directFromCpfpSigningNonceCommitment,
|
|
25397
|
+
vout: leaf.leaf.vout
|
|
24682
25398
|
});
|
|
24683
25399
|
}
|
|
24684
25400
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
@@ -24686,7 +25402,7 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
24686
25402
|
);
|
|
24687
25403
|
let response;
|
|
24688
25404
|
try {
|
|
24689
|
-
response = await sparkClient.
|
|
25405
|
+
response = await sparkClient.cooperative_exit_v2({
|
|
24690
25406
|
transfer: {
|
|
24691
25407
|
transferId: (0, import_uuidv72.uuidv7)(),
|
|
24692
25408
|
leavesToSend: signingJobs,
|
|
@@ -24720,10 +25436,25 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
24720
25436
|
response.signingResults
|
|
24721
25437
|
);
|
|
24722
25438
|
const signaturesMap = /* @__PURE__ */ new Map();
|
|
25439
|
+
const directSignaturesMap = /* @__PURE__ */ new Map();
|
|
25440
|
+
const directFromCpfpSignaturesMap = /* @__PURE__ */ new Map();
|
|
24723
25441
|
for (const signature of signatures) {
|
|
24724
25442
|
signaturesMap.set(signature.nodeId, signature.refundTxSignature);
|
|
25443
|
+
directSignaturesMap.set(
|
|
25444
|
+
signature.nodeId,
|
|
25445
|
+
signature.directRefundTxSignature
|
|
25446
|
+
);
|
|
25447
|
+
directFromCpfpSignaturesMap.set(
|
|
25448
|
+
signature.nodeId,
|
|
25449
|
+
signature.directFromCpfpRefundTxSignature
|
|
25450
|
+
);
|
|
24725
25451
|
}
|
|
24726
|
-
return {
|
|
25452
|
+
return {
|
|
25453
|
+
transfer: response.transfer,
|
|
25454
|
+
signaturesMap,
|
|
25455
|
+
directSignaturesMap,
|
|
25456
|
+
directFromCpfpSignaturesMap
|
|
25457
|
+
};
|
|
24727
25458
|
}
|
|
24728
25459
|
};
|
|
24729
25460
|
|
|
@@ -24732,7 +25463,6 @@ init_buffer();
|
|
|
24732
25463
|
var import_secp256k18 = require("@noble/curves/secp256k1");
|
|
24733
25464
|
var import_sha28 = require("@noble/hashes/sha2");
|
|
24734
25465
|
var import_utils9 = require("@noble/hashes/utils");
|
|
24735
|
-
var btc3 = __toESM(require("@scure/btc-signer"), 1);
|
|
24736
25466
|
var import_btc_signer4 = require("@scure/btc-signer");
|
|
24737
25467
|
var import_utils10 = require("@scure/btc-signer/utils");
|
|
24738
25468
|
|
|
@@ -24751,7 +25481,6 @@ function proofOfPossessionMessageHashForDepositAddress(userPubkey, operatorPubke
|
|
|
24751
25481
|
}
|
|
24752
25482
|
|
|
24753
25483
|
// src/services/deposit.ts
|
|
24754
|
-
var INITIAL_TIME_LOCK2 = 2e3;
|
|
24755
25484
|
var DepositService = class {
|
|
24756
25485
|
config;
|
|
24757
25486
|
connectionManager;
|
|
@@ -24869,7 +25598,6 @@ var DepositService = class {
|
|
|
24869
25598
|
depositTx,
|
|
24870
25599
|
vout
|
|
24871
25600
|
}) {
|
|
24872
|
-
const rootTx = new import_btc_signer4.Transaction({ version: 3 });
|
|
24873
25601
|
const output = depositTx.getOutput(vout);
|
|
24874
25602
|
if (!output) {
|
|
24875
25603
|
throw new ValidationError("Invalid deposit transaction output", {
|
|
@@ -24887,39 +25615,345 @@ var DepositService = class {
|
|
|
24887
25615
|
expected: "Output with script and amount"
|
|
24888
25616
|
});
|
|
24889
25617
|
}
|
|
24890
|
-
|
|
24891
|
-
|
|
24892
|
-
txid: getTxId(depositTx),
|
|
25618
|
+
const depositOutPoint = {
|
|
25619
|
+
txid: (0, import_utils9.hexToBytes)(getTxId(depositTx)),
|
|
24893
25620
|
index: vout
|
|
24894
|
-
}
|
|
24895
|
-
|
|
25621
|
+
};
|
|
25622
|
+
const depositTxOut = {
|
|
24896
25623
|
script,
|
|
24897
|
-
amount
|
|
25624
|
+
amount
|
|
25625
|
+
};
|
|
25626
|
+
const [cpfpRootTx, directRootTx] = createRootTx(
|
|
25627
|
+
depositOutPoint,
|
|
25628
|
+
depositTxOut
|
|
25629
|
+
);
|
|
25630
|
+
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25631
|
+
const directRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25632
|
+
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
25633
|
+
const directRootTxSighash = getSigHashFromTx(directRootTx, 0, output);
|
|
25634
|
+
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
25635
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
25636
|
+
sequence: INITIAL_SEQUENCE,
|
|
25637
|
+
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
25638
|
+
input: { txid: (0, import_utils9.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
25639
|
+
directInput: { txid: (0, import_utils9.hexToBytes)(getTxId(directRootTx)), index: 0 },
|
|
25640
|
+
amountSats: amount,
|
|
25641
|
+
receivingPubkey: signingPubKey,
|
|
25642
|
+
network: this.config.getNetwork()
|
|
24898
25643
|
});
|
|
24899
|
-
|
|
24900
|
-
const
|
|
24901
|
-
const
|
|
24902
|
-
const
|
|
24903
|
-
|
|
24904
|
-
|
|
24905
|
-
|
|
24906
|
-
|
|
24907
|
-
|
|
25644
|
+
const cpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25645
|
+
const directRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25646
|
+
const directFromCpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25647
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
25648
|
+
cpfpRefundTx,
|
|
25649
|
+
0,
|
|
25650
|
+
cpfpRootTx.getOutput(0)
|
|
25651
|
+
);
|
|
25652
|
+
if (!directRefundTx || !directFromCpfpRefundTx) {
|
|
25653
|
+
throw new ValidationError(
|
|
25654
|
+
"Expected direct refund transactions for tree creation",
|
|
25655
|
+
{
|
|
25656
|
+
field: "directRefundTx",
|
|
25657
|
+
value: directRefundTx
|
|
25658
|
+
}
|
|
25659
|
+
);
|
|
25660
|
+
}
|
|
25661
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
25662
|
+
directRefundTx,
|
|
25663
|
+
0,
|
|
25664
|
+
directRootTx.getOutput(0)
|
|
25665
|
+
);
|
|
25666
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
25667
|
+
directFromCpfpRefundTx,
|
|
25668
|
+
0,
|
|
25669
|
+
cpfpRootTx.getOutput(0)
|
|
25670
|
+
);
|
|
25671
|
+
const sparkClient = await this.connectionManager.createSparkClient(
|
|
25672
|
+
this.config.getCoordinatorAddress()
|
|
25673
|
+
);
|
|
25674
|
+
let treeResp;
|
|
25675
|
+
try {
|
|
25676
|
+
treeResp = await sparkClient.start_deposit_tree_creation({
|
|
25677
|
+
identityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25678
|
+
onChainUtxo: {
|
|
25679
|
+
vout,
|
|
25680
|
+
rawTx: depositTx.toBytes(true),
|
|
25681
|
+
network: this.config.getNetworkProto()
|
|
25682
|
+
},
|
|
25683
|
+
rootTxSigningJob: {
|
|
25684
|
+
rawTx: cpfpRootTx.toBytes(),
|
|
25685
|
+
signingPublicKey: signingPubKey,
|
|
25686
|
+
signingNonceCommitment: cpfpRootNonceCommitment.commitment
|
|
25687
|
+
},
|
|
25688
|
+
refundTxSigningJob: {
|
|
25689
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
25690
|
+
signingPublicKey: signingPubKey,
|
|
25691
|
+
signingNonceCommitment: cpfpRefundNonceCommitment.commitment
|
|
25692
|
+
},
|
|
25693
|
+
directRootTxSigningJob: {
|
|
25694
|
+
rawTx: directRootTx.toBytes(),
|
|
25695
|
+
signingPublicKey: signingPubKey,
|
|
25696
|
+
signingNonceCommitment: directRootNonceCommitment.commitment
|
|
25697
|
+
},
|
|
25698
|
+
directRefundTxSigningJob: {
|
|
25699
|
+
rawTx: directRefundTx.toBytes(),
|
|
25700
|
+
signingPublicKey: signingPubKey,
|
|
25701
|
+
signingNonceCommitment: directRefundNonceCommitment.commitment
|
|
25702
|
+
},
|
|
25703
|
+
directFromCpfpRefundTxSigningJob: {
|
|
25704
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
25705
|
+
signingPublicKey: signingPubKey,
|
|
25706
|
+
signingNonceCommitment: directFromCpfpRefundNonceCommitment.commitment
|
|
25707
|
+
}
|
|
25708
|
+
});
|
|
25709
|
+
} catch (error) {
|
|
25710
|
+
throw new NetworkError(
|
|
25711
|
+
"Failed to start deposit tree creation",
|
|
25712
|
+
{
|
|
25713
|
+
operation: "start_deposit_tree_creation",
|
|
25714
|
+
errorCount: 1,
|
|
25715
|
+
errors: error instanceof Error ? error.message : String(error)
|
|
25716
|
+
},
|
|
25717
|
+
error
|
|
25718
|
+
);
|
|
25719
|
+
}
|
|
25720
|
+
if (!treeResp.rootNodeSignatureShares?.verifyingKey) {
|
|
25721
|
+
throw new ValidationError("No verifying key found in tree response", {
|
|
25722
|
+
field: "verifyingKey",
|
|
25723
|
+
value: treeResp.rootNodeSignatureShares,
|
|
25724
|
+
expected: "Non-null verifying key"
|
|
25725
|
+
});
|
|
25726
|
+
}
|
|
25727
|
+
if (!treeResp.rootNodeSignatureShares.nodeTxSigningResult?.signingNonceCommitments) {
|
|
25728
|
+
throw new ValidationError(
|
|
25729
|
+
"No signing nonce commitments found in tree response",
|
|
25730
|
+
{
|
|
25731
|
+
field: "nodeTxSigningResult.signingNonceCommitments",
|
|
25732
|
+
value: treeResp.rootNodeSignatureShares.nodeTxSigningResult,
|
|
25733
|
+
expected: "Non-null signing nonce commitments"
|
|
25734
|
+
}
|
|
25735
|
+
);
|
|
25736
|
+
}
|
|
25737
|
+
if (!treeResp.rootNodeSignatureShares.refundTxSigningResult?.signingNonceCommitments) {
|
|
25738
|
+
throw new ValidationError(
|
|
25739
|
+
"No signing nonce commitments found in tree response",
|
|
25740
|
+
{
|
|
25741
|
+
field: "refundTxSigningResult.signingNonceCommitments"
|
|
25742
|
+
}
|
|
25743
|
+
);
|
|
25744
|
+
}
|
|
25745
|
+
if (!treeResp.rootNodeSignatureShares.directNodeTxSigningResult?.signingNonceCommitments) {
|
|
25746
|
+
throw new ValidationError(
|
|
25747
|
+
"No direct node signing nonce commitments found in tree response",
|
|
25748
|
+
{
|
|
25749
|
+
field: "directNodeTxSigningResult.signingNonceCommitments"
|
|
25750
|
+
}
|
|
25751
|
+
);
|
|
25752
|
+
}
|
|
25753
|
+
if (!treeResp.rootNodeSignatureShares.directRefundTxSigningResult?.signingNonceCommitments) {
|
|
25754
|
+
throw new ValidationError(
|
|
25755
|
+
"No direct refund signing nonce commitments found in tree response",
|
|
25756
|
+
{
|
|
25757
|
+
field: "directRefundTxSigningResult.signingNonceCommitments"
|
|
25758
|
+
}
|
|
25759
|
+
);
|
|
25760
|
+
}
|
|
25761
|
+
if (!treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult?.signingNonceCommitments) {
|
|
25762
|
+
throw new ValidationError(
|
|
25763
|
+
"No direct from CPFP refund signing nonce commitments found in tree response",
|
|
25764
|
+
{
|
|
25765
|
+
field: "directFromCpfpRefundTxSigningResult.signingNonceCommitments"
|
|
25766
|
+
}
|
|
25767
|
+
);
|
|
25768
|
+
}
|
|
25769
|
+
if (!(0, import_utils10.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
25770
|
+
throw new ValidationError("Verifying key mismatch", {
|
|
25771
|
+
field: "verifyingKey",
|
|
25772
|
+
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25773
|
+
expected: verifyingKey
|
|
25774
|
+
});
|
|
25775
|
+
}
|
|
25776
|
+
const cpfpRootSignature = await this.config.signer.signFrost({
|
|
25777
|
+
message: cpfpRootTxSighash,
|
|
25778
|
+
publicKey: signingPubKey,
|
|
25779
|
+
keyDerivation,
|
|
25780
|
+
verifyingKey,
|
|
25781
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
25782
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
25783
|
+
adaptorPubKey: new Uint8Array()
|
|
25784
|
+
});
|
|
25785
|
+
const directRootSignature = await this.config.signer.signFrost({
|
|
25786
|
+
message: directRootTxSighash,
|
|
25787
|
+
publicKey: signingPubKey,
|
|
25788
|
+
keyDerivation,
|
|
25789
|
+
verifyingKey,
|
|
25790
|
+
selfCommitment: directRootNonceCommitment,
|
|
25791
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signingNonceCommitments,
|
|
25792
|
+
adaptorPubKey: new Uint8Array()
|
|
24908
25793
|
});
|
|
25794
|
+
const cpfpRefundSignature = await this.config.signer.signFrost({
|
|
25795
|
+
message: cpfpRefundTxSighash,
|
|
25796
|
+
publicKey: signingPubKey,
|
|
25797
|
+
keyDerivation,
|
|
25798
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25799
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
25800
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
25801
|
+
adaptorPubKey: new Uint8Array()
|
|
25802
|
+
});
|
|
25803
|
+
const directRefundSignature = await this.config.signer.signFrost({
|
|
25804
|
+
message: directRefundTxSighash,
|
|
25805
|
+
publicKey: signingPubKey,
|
|
25806
|
+
keyDerivation,
|
|
25807
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25808
|
+
selfCommitment: directRefundNonceCommitment,
|
|
25809
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signingNonceCommitments,
|
|
25810
|
+
adaptorPubKey: new Uint8Array()
|
|
25811
|
+
});
|
|
25812
|
+
const directFromCpfpRefundSignature = await this.config.signer.signFrost({
|
|
25813
|
+
message: directFromCpfpRefundTxSighash,
|
|
25814
|
+
publicKey: signingPubKey,
|
|
25815
|
+
keyDerivation,
|
|
25816
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25817
|
+
selfCommitment: directFromCpfpRefundNonceCommitment,
|
|
25818
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signingNonceCommitments,
|
|
25819
|
+
adaptorPubKey: new Uint8Array()
|
|
25820
|
+
});
|
|
25821
|
+
const cpfpRootAggregate = await this.config.signer.aggregateFrost({
|
|
25822
|
+
message: cpfpRootTxSighash,
|
|
25823
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signatureShares,
|
|
25824
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.nodeTxSigningResult.publicKeys,
|
|
25825
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25826
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
25827
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
25828
|
+
publicKey: signingPubKey,
|
|
25829
|
+
selfSignature: cpfpRootSignature,
|
|
25830
|
+
adaptorPubKey: new Uint8Array()
|
|
25831
|
+
});
|
|
25832
|
+
const directRootAggregate = await this.config.signer.aggregateFrost({
|
|
25833
|
+
message: directRootTxSighash,
|
|
25834
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signatureShares,
|
|
25835
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.publicKeys,
|
|
25836
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25837
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directNodeTxSigningResult.signingNonceCommitments,
|
|
25838
|
+
selfCommitment: directRootNonceCommitment,
|
|
25839
|
+
publicKey: signingPubKey,
|
|
25840
|
+
selfSignature: directRootSignature,
|
|
25841
|
+
adaptorPubKey: new Uint8Array()
|
|
25842
|
+
});
|
|
25843
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25844
|
+
message: cpfpRefundTxSighash,
|
|
25845
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.refundTxSigningResult.signatureShares,
|
|
25846
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.refundTxSigningResult.publicKeys,
|
|
25847
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25848
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
25849
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
25850
|
+
publicKey: signingPubKey,
|
|
25851
|
+
selfSignature: cpfpRefundSignature,
|
|
25852
|
+
adaptorPubKey: new Uint8Array()
|
|
25853
|
+
});
|
|
25854
|
+
const directRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25855
|
+
message: directRefundTxSighash,
|
|
25856
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signatureShares,
|
|
25857
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.publicKeys,
|
|
25858
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25859
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directRefundTxSigningResult.signingNonceCommitments,
|
|
25860
|
+
selfCommitment: directRefundNonceCommitment,
|
|
25861
|
+
publicKey: signingPubKey,
|
|
25862
|
+
selfSignature: directRefundSignature,
|
|
25863
|
+
adaptorPubKey: new Uint8Array()
|
|
25864
|
+
});
|
|
25865
|
+
const directFromCpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
25866
|
+
message: directFromCpfpRefundTxSighash,
|
|
25867
|
+
statechainSignatures: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signatureShares,
|
|
25868
|
+
statechainPublicKeys: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.publicKeys,
|
|
25869
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25870
|
+
statechainCommitments: treeResp.rootNodeSignatureShares.directFromCpfpRefundTxSigningResult.signingNonceCommitments,
|
|
25871
|
+
selfCommitment: directFromCpfpRefundNonceCommitment,
|
|
25872
|
+
publicKey: signingPubKey,
|
|
25873
|
+
selfSignature: directFromCpfpRefundSignature,
|
|
25874
|
+
adaptorPubKey: new Uint8Array()
|
|
25875
|
+
});
|
|
25876
|
+
let finalizeResp;
|
|
25877
|
+
try {
|
|
25878
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
25879
|
+
intent: 0 /* CREATION */,
|
|
25880
|
+
nodeSignatures: [
|
|
25881
|
+
{
|
|
25882
|
+
nodeId: treeResp.rootNodeSignatureShares.nodeId,
|
|
25883
|
+
nodeTxSignature: cpfpRootAggregate,
|
|
25884
|
+
refundTxSignature: cpfpRefundAggregate,
|
|
25885
|
+
directNodeTxSignature: directRootAggregate,
|
|
25886
|
+
directRefundTxSignature: directRefundAggregate,
|
|
25887
|
+
directFromCpfpRefundTxSignature: directFromCpfpRefundAggregate
|
|
25888
|
+
}
|
|
25889
|
+
]
|
|
25890
|
+
});
|
|
25891
|
+
} catch (error) {
|
|
25892
|
+
throw new NetworkError(
|
|
25893
|
+
"Failed to finalize node signatures",
|
|
25894
|
+
{
|
|
25895
|
+
operation: "finalize_node_signatures",
|
|
25896
|
+
errorCount: 1,
|
|
25897
|
+
errors: error instanceof Error ? error.message : String(error)
|
|
25898
|
+
},
|
|
25899
|
+
error
|
|
25900
|
+
);
|
|
25901
|
+
}
|
|
25902
|
+
return finalizeResp;
|
|
25903
|
+
}
|
|
25904
|
+
/**
|
|
25905
|
+
* @deprecated
|
|
25906
|
+
* Use createTreeRoot instead.
|
|
25907
|
+
* This is currently only used to test backwards compatibility.
|
|
25908
|
+
*/
|
|
25909
|
+
async createTreeWithoutDirectTx({
|
|
25910
|
+
keyDerivation,
|
|
25911
|
+
verifyingKey,
|
|
25912
|
+
depositTx,
|
|
25913
|
+
vout
|
|
25914
|
+
}) {
|
|
25915
|
+
const output = depositTx.getOutput(vout);
|
|
25916
|
+
if (!output) {
|
|
25917
|
+
throw new ValidationError("Invalid deposit transaction output", {
|
|
25918
|
+
field: "vout",
|
|
25919
|
+
value: vout,
|
|
25920
|
+
expected: "Valid output index"
|
|
25921
|
+
});
|
|
25922
|
+
}
|
|
25923
|
+
const script = output.script;
|
|
25924
|
+
const amount = output.amount;
|
|
25925
|
+
if (!script || !amount) {
|
|
25926
|
+
throw new ValidationError("No script or amount found in deposit tx", {
|
|
25927
|
+
field: "output",
|
|
25928
|
+
value: output,
|
|
25929
|
+
expected: "Output with script and amount"
|
|
25930
|
+
});
|
|
25931
|
+
}
|
|
25932
|
+
const depositOutPoint = {
|
|
25933
|
+
txid: (0, import_utils9.hexToBytes)(getTxId(depositTx)),
|
|
25934
|
+
index: vout
|
|
25935
|
+
};
|
|
25936
|
+
const depositTxOut = {
|
|
25937
|
+
script,
|
|
25938
|
+
amount
|
|
25939
|
+
};
|
|
25940
|
+
const [cpfpRootTx, _] = createRootTx(depositOutPoint, depositTxOut);
|
|
25941
|
+
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25942
|
+
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
24909
25943
|
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
24910
|
-
const
|
|
24911
|
-
|
|
24912
|
-
|
|
24913
|
-
|
|
24914
|
-
|
|
24915
|
-
|
|
24916
|
-
refundTx.addOutput({
|
|
24917
|
-
script: refundPkScript,
|
|
24918
|
-
amount: outputAmount
|
|
25944
|
+
const { cpfpRefundTx } = createRefundTxs({
|
|
25945
|
+
sequence: INITIAL_SEQUENCE,
|
|
25946
|
+
input: { txid: (0, import_utils9.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
25947
|
+
amountSats: amount,
|
|
25948
|
+
receivingPubkey: signingPubKey,
|
|
25949
|
+
network: this.config.getNetwork()
|
|
24919
25950
|
});
|
|
24920
|
-
|
|
24921
|
-
const
|
|
24922
|
-
|
|
25951
|
+
const cpfpRefundNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
25952
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
25953
|
+
cpfpRefundTx,
|
|
25954
|
+
0,
|
|
25955
|
+
cpfpRootTx.getOutput(0)
|
|
25956
|
+
);
|
|
24923
25957
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
24924
25958
|
this.config.getCoordinatorAddress()
|
|
24925
25959
|
);
|
|
@@ -24933,14 +25967,14 @@ var DepositService = class {
|
|
|
24933
25967
|
network: this.config.getNetworkProto()
|
|
24934
25968
|
},
|
|
24935
25969
|
rootTxSigningJob: {
|
|
24936
|
-
rawTx:
|
|
25970
|
+
rawTx: cpfpRootTx.toBytes(),
|
|
24937
25971
|
signingPublicKey: signingPubKey,
|
|
24938
|
-
signingNonceCommitment:
|
|
25972
|
+
signingNonceCommitment: cpfpRootNonceCommitment.commitment
|
|
24939
25973
|
},
|
|
24940
25974
|
refundTxSigningJob: {
|
|
24941
|
-
rawTx:
|
|
25975
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
24942
25976
|
signingPublicKey: signingPubKey,
|
|
24943
|
-
signingNonceCommitment:
|
|
25977
|
+
signingNonceCommitment: cpfpRefundNonceCommitment.commitment
|
|
24944
25978
|
}
|
|
24945
25979
|
});
|
|
24946
25980
|
} catch (error) {
|
|
@@ -24986,55 +26020,55 @@ var DepositService = class {
|
|
|
24986
26020
|
expected: verifyingKey
|
|
24987
26021
|
});
|
|
24988
26022
|
}
|
|
24989
|
-
const
|
|
24990
|
-
message:
|
|
26023
|
+
const cpfpRootSignature = await this.config.signer.signFrost({
|
|
26024
|
+
message: cpfpRootTxSighash,
|
|
24991
26025
|
publicKey: signingPubKey,
|
|
24992
26026
|
keyDerivation,
|
|
24993
26027
|
verifyingKey,
|
|
24994
|
-
selfCommitment:
|
|
26028
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
24995
26029
|
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
24996
26030
|
adaptorPubKey: new Uint8Array()
|
|
24997
26031
|
});
|
|
24998
|
-
const
|
|
24999
|
-
message:
|
|
26032
|
+
const cpfpRefundSignature = await this.config.signer.signFrost({
|
|
26033
|
+
message: cpfpRefundTxSighash,
|
|
25000
26034
|
publicKey: signingPubKey,
|
|
25001
26035
|
keyDerivation,
|
|
25002
|
-
verifyingKey,
|
|
25003
|
-
selfCommitment:
|
|
26036
|
+
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
26037
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
25004
26038
|
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
25005
26039
|
adaptorPubKey: new Uint8Array()
|
|
25006
26040
|
});
|
|
25007
|
-
const
|
|
25008
|
-
message:
|
|
26041
|
+
const cpfpRootAggregate = await this.config.signer.aggregateFrost({
|
|
26042
|
+
message: cpfpRootTxSighash,
|
|
25009
26043
|
statechainSignatures: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signatureShares,
|
|
25010
26044
|
statechainPublicKeys: treeResp.rootNodeSignatureShares.nodeTxSigningResult.publicKeys,
|
|
25011
26045
|
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25012
26046
|
statechainCommitments: treeResp.rootNodeSignatureShares.nodeTxSigningResult.signingNonceCommitments,
|
|
25013
|
-
selfCommitment:
|
|
26047
|
+
selfCommitment: cpfpRootNonceCommitment,
|
|
25014
26048
|
publicKey: signingPubKey,
|
|
25015
|
-
selfSignature:
|
|
26049
|
+
selfSignature: cpfpRootSignature,
|
|
25016
26050
|
adaptorPubKey: new Uint8Array()
|
|
25017
26051
|
});
|
|
25018
|
-
const
|
|
25019
|
-
message:
|
|
26052
|
+
const cpfpRefundAggregate = await this.config.signer.aggregateFrost({
|
|
26053
|
+
message: cpfpRefundTxSighash,
|
|
25020
26054
|
statechainSignatures: treeResp.rootNodeSignatureShares.refundTxSigningResult.signatureShares,
|
|
25021
26055
|
statechainPublicKeys: treeResp.rootNodeSignatureShares.refundTxSigningResult.publicKeys,
|
|
25022
26056
|
verifyingKey: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
25023
26057
|
statechainCommitments: treeResp.rootNodeSignatureShares.refundTxSigningResult.signingNonceCommitments,
|
|
25024
|
-
selfCommitment:
|
|
26058
|
+
selfCommitment: cpfpRefundNonceCommitment,
|
|
25025
26059
|
publicKey: signingPubKey,
|
|
25026
|
-
selfSignature:
|
|
26060
|
+
selfSignature: cpfpRefundSignature,
|
|
25027
26061
|
adaptorPubKey: new Uint8Array()
|
|
25028
26062
|
});
|
|
25029
26063
|
let finalizeResp;
|
|
25030
26064
|
try {
|
|
25031
|
-
finalizeResp = await sparkClient.
|
|
26065
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
25032
26066
|
intent: 0 /* CREATION */,
|
|
25033
26067
|
nodeSignatures: [
|
|
25034
26068
|
{
|
|
25035
26069
|
nodeId: treeResp.rootNodeSignatureShares.nodeId,
|
|
25036
|
-
nodeTxSignature:
|
|
25037
|
-
refundTxSignature:
|
|
26070
|
+
nodeTxSignature: cpfpRootAggregate,
|
|
26071
|
+
refundTxSignature: cpfpRefundAggregate
|
|
25038
26072
|
}
|
|
25039
26073
|
]
|
|
25040
26074
|
});
|
|
@@ -25244,7 +26278,8 @@ var LightningService = class {
|
|
|
25244
26278
|
let signingCommitments;
|
|
25245
26279
|
try {
|
|
25246
26280
|
signingCommitments = await sparkClient.get_signing_commitments({
|
|
25247
|
-
nodeIds: leaves.map((leaf) => leaf.leaf.id)
|
|
26281
|
+
nodeIds: leaves.map((leaf) => leaf.leaf.id),
|
|
26282
|
+
count: 3
|
|
25248
26283
|
});
|
|
25249
26284
|
} catch (error) {
|
|
25250
26285
|
throw new NetworkError(
|
|
@@ -25257,10 +26292,19 @@ var LightningService = class {
|
|
|
25257
26292
|
error
|
|
25258
26293
|
);
|
|
25259
26294
|
}
|
|
25260
|
-
const
|
|
26295
|
+
const {
|
|
26296
|
+
cpfpLeafSigningJobs,
|
|
26297
|
+
directLeafSigningJobs,
|
|
26298
|
+
directFromCpfpLeafSigningJobs
|
|
26299
|
+
} = await this.signingService.signRefunds(
|
|
25261
26300
|
leaves,
|
|
25262
|
-
|
|
25263
|
-
|
|
26301
|
+
receiverIdentityPubkey,
|
|
26302
|
+
signingCommitments.signingCommitments.slice(0, leaves.length),
|
|
26303
|
+
signingCommitments.signingCommitments.slice(
|
|
26304
|
+
leaves.length,
|
|
26305
|
+
2 * leaves.length
|
|
26306
|
+
),
|
|
26307
|
+
signingCommitments.signingCommitments.slice(2 * leaves.length)
|
|
25264
26308
|
);
|
|
25265
26309
|
const transferId = (0, import_uuidv73.uuidv7)();
|
|
25266
26310
|
let bolt11String = "";
|
|
@@ -25297,7 +26341,7 @@ var LightningService = class {
|
|
|
25297
26341
|
const reason = isInboundPayment ? 1 /* REASON_RECEIVE */ : 0 /* REASON_SEND */;
|
|
25298
26342
|
let response;
|
|
25299
26343
|
try {
|
|
25300
|
-
response = await sparkClient.
|
|
26344
|
+
response = await sparkClient.initiate_preimage_swap_v2({
|
|
25301
26345
|
paymentHash,
|
|
25302
26346
|
invoiceAmount: {
|
|
25303
26347
|
invoiceAmountProof: {
|
|
@@ -25309,7 +26353,9 @@ var LightningService = class {
|
|
|
25309
26353
|
transfer: {
|
|
25310
26354
|
transferId,
|
|
25311
26355
|
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
25312
|
-
leavesToSend:
|
|
26356
|
+
leavesToSend: cpfpLeafSigningJobs,
|
|
26357
|
+
directLeavesToSend: directLeafSigningJobs,
|
|
26358
|
+
directFromCpfpLeavesToSend: directFromCpfpLeafSigningJobs,
|
|
25313
26359
|
receiverIdentityPublicKey: receiverIdentityPubkey,
|
|
25314
26360
|
expiryTime: new Date(Date.now() + 2 * 60 * 1e3)
|
|
25315
26361
|
},
|
|
@@ -28042,13 +29088,6 @@ function isTokenTransaction(tokenTransaction) {
|
|
|
28042
29088
|
init_buffer();
|
|
28043
29089
|
var import_utils17 = require("@noble/curves/abstract/utils");
|
|
28044
29090
|
var import_btc_signer5 = require("@scure/btc-signer");
|
|
28045
|
-
var INITIAL_TIME_LOCK3 = 2e3;
|
|
28046
|
-
function maybeApplyFee2(amount) {
|
|
28047
|
-
if (amount > BigInt(DEFAULT_FEE_SATS)) {
|
|
28048
|
-
return amount - BigInt(DEFAULT_FEE_SATS);
|
|
28049
|
-
}
|
|
28050
|
-
return amount;
|
|
28051
|
-
}
|
|
28052
29091
|
var TreeCreationService = class {
|
|
28053
29092
|
config;
|
|
28054
29093
|
connectionManager;
|
|
@@ -28163,7 +29202,7 @@ var TreeCreationService = class {
|
|
|
28163
29202
|
);
|
|
28164
29203
|
let response;
|
|
28165
29204
|
try {
|
|
28166
|
-
response = await sparkClient.
|
|
29205
|
+
response = await sparkClient.create_tree_v2(request);
|
|
28167
29206
|
} catch (error) {
|
|
28168
29207
|
throw new Error(`Error creating tree: ${error}`);
|
|
28169
29208
|
}
|
|
@@ -28180,7 +29219,7 @@ var TreeCreationService = class {
|
|
|
28180
29219
|
);
|
|
28181
29220
|
let finalizeResp;
|
|
28182
29221
|
try {
|
|
28183
|
-
finalizeResp = await sparkClient.
|
|
29222
|
+
finalizeResp = await sparkClient.finalize_node_signatures_v2({
|
|
28184
29223
|
nodeSignatures
|
|
28185
29224
|
});
|
|
28186
29225
|
} catch (error) {
|
|
@@ -28245,91 +29284,111 @@ var TreeCreationService = class {
|
|
|
28245
29284
|
async buildChildCreationNode(node, parentTx, vout, network) {
|
|
28246
29285
|
const internalCreationNode = {
|
|
28247
29286
|
nodeTxSigningJob: void 0,
|
|
28248
|
-
refundTxSigningJob: void 0,
|
|
28249
|
-
children: [],
|
|
28250
29287
|
directNodeTxSigningJob: void 0,
|
|
29288
|
+
refundTxSigningJob: void 0,
|
|
28251
29289
|
directRefundTxSigningJob: void 0,
|
|
28252
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
29290
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
29291
|
+
children: []
|
|
28253
29292
|
};
|
|
28254
|
-
const tx = new import_btc_signer5.Transaction({ version: 3 });
|
|
28255
|
-
tx.addInput({
|
|
28256
|
-
txid: getTxId(parentTx),
|
|
28257
|
-
index: vout
|
|
28258
|
-
});
|
|
28259
29293
|
const parentTxOut = parentTx.getOutput(vout);
|
|
28260
29294
|
if (!parentTxOut?.script || !parentTxOut?.amount) {
|
|
28261
29295
|
throw new Error("parentTxOut is undefined");
|
|
28262
29296
|
}
|
|
28263
|
-
|
|
29297
|
+
const parentOutPoint = {
|
|
29298
|
+
txid: (0, import_utils17.hexToBytes)(getTxId(parentTx)),
|
|
29299
|
+
index: vout
|
|
29300
|
+
};
|
|
29301
|
+
const parentTxOutObj = {
|
|
28264
29302
|
script: parentTxOut.script,
|
|
28265
29303
|
amount: parentTxOut.amount
|
|
28266
|
-
|
|
28267
|
-
}
|
|
28268
|
-
|
|
28269
|
-
|
|
28270
|
-
|
|
29304
|
+
};
|
|
29305
|
+
const { cpfpNodeTx, directNodeTx } = createNodeTxs(
|
|
29306
|
+
parentTxOutObj,
|
|
29307
|
+
parentOutPoint
|
|
29308
|
+
);
|
|
29309
|
+
const cpfpNodeSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29310
|
+
const directNodeSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29311
|
+
const cpfpNodeSigningJob = {
|
|
28271
29312
|
signingPublicKey: node.signingPublicKey,
|
|
28272
|
-
rawTx:
|
|
28273
|
-
signingNonceCommitment:
|
|
29313
|
+
rawTx: cpfpNodeTx.toBytes(),
|
|
29314
|
+
signingNonceCommitment: cpfpNodeSigningCommitment.commitment
|
|
28274
29315
|
};
|
|
28275
|
-
|
|
28276
|
-
|
|
28277
|
-
|
|
29316
|
+
const directNodeSigningJob = directNodeTx ? {
|
|
29317
|
+
signingPublicKey: node.signingPublicKey,
|
|
29318
|
+
rawTx: directNodeTx.toBytes(),
|
|
29319
|
+
signingNonceCommitment: directNodeSigningCommitment.commitment
|
|
29320
|
+
} : void 0;
|
|
29321
|
+
internalCreationNode.nodeTxSigningCommitment = cpfpNodeSigningCommitment;
|
|
29322
|
+
internalCreationNode.directNodeTxSigningCommitment = directNodeSigningCommitment;
|
|
29323
|
+
internalCreationNode.nodeTxSigningJob = cpfpNodeSigningJob;
|
|
29324
|
+
internalCreationNode.directNodeTxSigningJob = directNodeSigningJob;
|
|
29325
|
+
const sequence = INITIAL_SEQUENCE;
|
|
29326
|
+
const directSequence = INITIAL_DIRECT_SEQUENCE;
|
|
28278
29327
|
const childCreationNode = {
|
|
28279
29328
|
nodeTxSigningJob: void 0,
|
|
28280
|
-
refundTxSigningJob: void 0,
|
|
28281
|
-
children: [],
|
|
28282
29329
|
directNodeTxSigningJob: void 0,
|
|
29330
|
+
refundTxSigningJob: void 0,
|
|
28283
29331
|
directRefundTxSigningJob: void 0,
|
|
28284
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
29332
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
29333
|
+
children: []
|
|
28285
29334
|
};
|
|
28286
|
-
const
|
|
28287
|
-
|
|
28288
|
-
|
|
28289
|
-
index: 0,
|
|
28290
|
-
|
|
28291
|
-
|
|
28292
|
-
|
|
28293
|
-
|
|
28294
|
-
|
|
28295
|
-
|
|
28296
|
-
|
|
28297
|
-
childTx.addOutput(getEphemeralAnchorOutput());
|
|
28298
|
-
const childSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
28299
|
-
const childSigningJob = {
|
|
29335
|
+
const [cpfpLeafTx, directLeafTx] = createLeafNodeTx(
|
|
29336
|
+
sequence,
|
|
29337
|
+
directSequence,
|
|
29338
|
+
{ txid: (0, import_utils17.hexToBytes)(getTxId(cpfpNodeTx)), index: 0 },
|
|
29339
|
+
parentTxOutObj,
|
|
29340
|
+
true
|
|
29341
|
+
// shouldCalculateFee
|
|
29342
|
+
);
|
|
29343
|
+
const cpfpLeafSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29344
|
+
const directLeafSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29345
|
+
const cpfpLeafSigningJob = {
|
|
28300
29346
|
signingPublicKey: node.signingPublicKey,
|
|
28301
|
-
rawTx:
|
|
28302
|
-
signingNonceCommitment:
|
|
28303
|
-
};
|
|
28304
|
-
|
|
28305
|
-
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
|
|
28309
|
-
|
|
28310
|
-
|
|
28311
|
-
|
|
28312
|
-
|
|
28313
|
-
|
|
29347
|
+
rawTx: cpfpLeafTx.toBytes(),
|
|
29348
|
+
signingNonceCommitment: cpfpLeafSigningCommitment.commitment
|
|
29349
|
+
};
|
|
29350
|
+
const directLeafSigningJob = {
|
|
29351
|
+
signingPublicKey: node.signingPublicKey,
|
|
29352
|
+
rawTx: directLeafTx.toBytes(),
|
|
29353
|
+
signingNonceCommitment: directLeafSigningCommitment.commitment
|
|
29354
|
+
};
|
|
29355
|
+
childCreationNode.nodeTxSigningCommitment = cpfpLeafSigningCommitment;
|
|
29356
|
+
childCreationNode.directNodeTxSigningCommitment = directLeafSigningCommitment;
|
|
29357
|
+
childCreationNode.nodeTxSigningJob = cpfpLeafSigningJob;
|
|
29358
|
+
childCreationNode.directNodeTxSigningJob = directLeafSigningJob;
|
|
29359
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
29360
|
+
sequence,
|
|
29361
|
+
directSequence,
|
|
29362
|
+
input: { txid: (0, import_utils17.hexToBytes)(getTxId(cpfpLeafTx)), index: 0 },
|
|
29363
|
+
directInput: { txid: (0, import_utils17.hexToBytes)(getTxId(directLeafTx)), index: 0 },
|
|
29364
|
+
amountSats: parentTxOut.amount,
|
|
29365
|
+
receivingPubkey: node.signingPublicKey,
|
|
28314
29366
|
network
|
|
28315
|
-
);
|
|
28316
|
-
const refundAddress = (0, import_btc_signer5.Address)(getNetwork(network)).decode(
|
|
28317
|
-
refundP2trAddress
|
|
28318
|
-
);
|
|
28319
|
-
const refundPkScript = import_btc_signer5.OutScript.encode(refundAddress);
|
|
28320
|
-
refundTx.addOutput({
|
|
28321
|
-
script: refundPkScript,
|
|
28322
|
-
amount: maybeApplyFee2(parentTxOut.amount)
|
|
28323
29367
|
});
|
|
28324
|
-
|
|
28325
|
-
const
|
|
28326
|
-
const
|
|
29368
|
+
const cpfpRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29369
|
+
const directRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29370
|
+
const directFromCpfpRefundSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29371
|
+
const cpfpRefundSigningJob = {
|
|
28327
29372
|
signingPublicKey: node.signingPublicKey,
|
|
28328
|
-
rawTx:
|
|
28329
|
-
signingNonceCommitment:
|
|
29373
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
29374
|
+
signingNonceCommitment: cpfpRefundSigningCommitment.commitment
|
|
28330
29375
|
};
|
|
28331
|
-
|
|
28332
|
-
|
|
29376
|
+
const directRefundSigningJob = directRefundTx ? {
|
|
29377
|
+
signingPublicKey: node.signingPublicKey,
|
|
29378
|
+
rawTx: directRefundTx.toBytes(),
|
|
29379
|
+
signingNonceCommitment: directRefundSigningCommitment.commitment
|
|
29380
|
+
} : void 0;
|
|
29381
|
+
const directFromCpfpRefundSigningJob = directFromCpfpRefundTx ? {
|
|
29382
|
+
signingPublicKey: node.signingPublicKey,
|
|
29383
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
29384
|
+
signingNonceCommitment: directFromCpfpRefundSigningCommitment.commitment
|
|
29385
|
+
} : void 0;
|
|
29386
|
+
childCreationNode.refundTxSigningCommitment = cpfpRefundSigningCommitment;
|
|
29387
|
+
childCreationNode.directRefundTxSigningCommitment = directRefundSigningCommitment;
|
|
29388
|
+
childCreationNode.directFromCpfpRefundTxSigningCommitment = directFromCpfpRefundSigningCommitment;
|
|
29389
|
+
childCreationNode.refundTxSigningJob = cpfpRefundSigningJob;
|
|
29390
|
+
childCreationNode.directRefundTxSigningJob = directRefundSigningJob;
|
|
29391
|
+
childCreationNode.directFromCpfpRefundTxSigningJob = directFromCpfpRefundSigningJob;
|
|
28333
29392
|
internalCreationNode.children.push(childCreationNode);
|
|
28334
29393
|
return internalCreationNode;
|
|
28335
29394
|
}
|
|
@@ -28338,11 +29397,7 @@ var TreeCreationService = class {
|
|
|
28338
29397
|
if (!parentTxOutput?.script || !parentTxOutput?.amount) {
|
|
28339
29398
|
throw new Error("parentTxOutput is undefined");
|
|
28340
29399
|
}
|
|
28341
|
-
const
|
|
28342
|
-
rootNodeTx.addInput({
|
|
28343
|
-
txid: getTxId(parentTx),
|
|
28344
|
-
index: vout
|
|
28345
|
-
});
|
|
29400
|
+
const childTxOuts = [];
|
|
28346
29401
|
for (let i = 0; i < root.children.length; i++) {
|
|
28347
29402
|
const child = root.children[i];
|
|
28348
29403
|
if (!child || !child.address) {
|
|
@@ -28350,28 +29405,41 @@ var TreeCreationService = class {
|
|
|
28350
29405
|
}
|
|
28351
29406
|
const childAddress = (0, import_btc_signer5.Address)(getNetwork(network)).decode(child.address);
|
|
28352
29407
|
const childPkScript = import_btc_signer5.OutScript.encode(childAddress);
|
|
28353
|
-
|
|
29408
|
+
childTxOuts.push({
|
|
28354
29409
|
script: childPkScript,
|
|
28355
29410
|
amount: parentTxOutput.amount / 2n
|
|
28356
|
-
// feeAdjustedAmount / 2n,
|
|
28357
29411
|
});
|
|
28358
29412
|
}
|
|
28359
|
-
|
|
28360
|
-
|
|
28361
|
-
|
|
29413
|
+
const parentOutPoint = {
|
|
29414
|
+
txid: (0, import_utils17.hexToBytes)(getTxId(parentTx)),
|
|
29415
|
+
index: vout
|
|
29416
|
+
};
|
|
29417
|
+
const [cpfpSplitTx, directSplitTx] = createSplitTx(
|
|
29418
|
+
parentOutPoint,
|
|
29419
|
+
childTxOuts
|
|
29420
|
+
);
|
|
29421
|
+
const cpfpSplitSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29422
|
+
const directSplitSigningCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29423
|
+
const cpfpSplitSigningJob = {
|
|
28362
29424
|
signingPublicKey: root.signingPublicKey,
|
|
28363
|
-
rawTx:
|
|
28364
|
-
signingNonceCommitment:
|
|
29425
|
+
rawTx: cpfpSplitTx.toBytes(),
|
|
29426
|
+
signingNonceCommitment: cpfpSplitSigningCommitment.commitment
|
|
29427
|
+
};
|
|
29428
|
+
const directSplitSigningJob = {
|
|
29429
|
+
signingPublicKey: root.signingPublicKey,
|
|
29430
|
+
rawTx: directSplitTx.toBytes(),
|
|
29431
|
+
signingNonceCommitment: directSplitSigningCommitment.commitment
|
|
28365
29432
|
};
|
|
28366
29433
|
const rootCreationNode = {
|
|
28367
|
-
nodeTxSigningJob:
|
|
29434
|
+
nodeTxSigningJob: cpfpSplitSigningJob,
|
|
29435
|
+
directNodeTxSigningJob: directSplitSigningJob,
|
|
28368
29436
|
refundTxSigningJob: void 0,
|
|
28369
|
-
children: [],
|
|
28370
|
-
directNodeTxSigningJob: void 0,
|
|
28371
29437
|
directRefundTxSigningJob: void 0,
|
|
28372
|
-
directFromCpfpRefundTxSigningJob: void 0
|
|
29438
|
+
directFromCpfpRefundTxSigningJob: void 0,
|
|
29439
|
+
children: []
|
|
28373
29440
|
};
|
|
28374
|
-
rootCreationNode.nodeTxSigningCommitment =
|
|
29441
|
+
rootCreationNode.nodeTxSigningCommitment = cpfpSplitSigningCommitment;
|
|
29442
|
+
rootCreationNode.directNodeTxSigningCommitment = directSplitSigningCommitment;
|
|
28375
29443
|
const leftChild = root.children[0];
|
|
28376
29444
|
const rightChild = root.children[1];
|
|
28377
29445
|
if (!leftChild || !rightChild) {
|
|
@@ -28379,13 +29447,15 @@ var TreeCreationService = class {
|
|
|
28379
29447
|
}
|
|
28380
29448
|
const leftChildCreationNode = await this.buildChildCreationNode(
|
|
28381
29449
|
leftChild,
|
|
28382
|
-
|
|
29450
|
+
cpfpSplitTx,
|
|
29451
|
+
// Use CPFP version for children
|
|
28383
29452
|
0,
|
|
28384
29453
|
network
|
|
28385
29454
|
);
|
|
28386
29455
|
const rightChildCreationNode = await this.buildChildCreationNode(
|
|
28387
29456
|
rightChild,
|
|
28388
|
-
|
|
29457
|
+
cpfpSplitTx,
|
|
29458
|
+
// Use CPFP version for children
|
|
28389
29459
|
1,
|
|
28390
29460
|
network
|
|
28391
29461
|
);
|
|
@@ -28394,19 +29464,19 @@ var TreeCreationService = class {
|
|
|
28394
29464
|
return rootCreationNode;
|
|
28395
29465
|
}
|
|
28396
29466
|
async signNodeCreation(parentTx, vout, internalNode, creationNode, creationResponseNode) {
|
|
28397
|
-
if (!creationNode.nodeTxSigningJob?.signingPublicKey || !internalNode.verificationKey) {
|
|
29467
|
+
if (!creationNode.nodeTxSigningJob?.signingPublicKey || !creationNode.directNodeTxSigningJob?.signingPublicKey || !internalNode.verificationKey) {
|
|
28398
29468
|
throw new Error("signingPublicKey or verificationKey is undefined");
|
|
28399
29469
|
}
|
|
28400
29470
|
const parentTxOutput = parentTx.getOutput(vout);
|
|
28401
29471
|
if (!parentTxOutput) {
|
|
28402
29472
|
throw new Error("parentTxOutput is undefined");
|
|
28403
29473
|
}
|
|
28404
|
-
const
|
|
28405
|
-
const
|
|
28406
|
-
let
|
|
29474
|
+
const cpfpNodeTx = getTxFromRawTxBytes(creationNode.nodeTxSigningJob.rawTx);
|
|
29475
|
+
const cpfpNodeTxSighash = getSigHashFromTx(cpfpNodeTx, 0, parentTxOutput);
|
|
29476
|
+
let cpfpNodeTxSignature = new Uint8Array();
|
|
28407
29477
|
if (creationNode.nodeTxSigningCommitment) {
|
|
28408
|
-
const
|
|
28409
|
-
message:
|
|
29478
|
+
const cpfpUserSignature = await this.config.signer.signFrost({
|
|
29479
|
+
message: cpfpNodeTxSighash,
|
|
28410
29480
|
publicKey: creationNode.nodeTxSigningJob.signingPublicKey,
|
|
28411
29481
|
keyDerivation: {
|
|
28412
29482
|
type: "leaf" /* LEAF */,
|
|
@@ -28416,30 +29486,84 @@ var TreeCreationService = class {
|
|
|
28416
29486
|
statechainCommitments: creationResponseNode.nodeTxSigningResult?.signingNonceCommitments,
|
|
28417
29487
|
verifyingKey: internalNode.verificationKey
|
|
28418
29488
|
});
|
|
28419
|
-
|
|
28420
|
-
message:
|
|
29489
|
+
cpfpNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
29490
|
+
message: cpfpNodeTxSighash,
|
|
28421
29491
|
statechainSignatures: creationResponseNode.nodeTxSigningResult?.signatureShares,
|
|
28422
29492
|
statechainPublicKeys: creationResponseNode.nodeTxSigningResult?.publicKeys,
|
|
28423
29493
|
verifyingKey: internalNode.verificationKey,
|
|
28424
29494
|
statechainCommitments: creationResponseNode.nodeTxSigningResult?.signingNonceCommitments,
|
|
28425
29495
|
selfCommitment: creationNode.nodeTxSigningCommitment,
|
|
28426
|
-
selfSignature:
|
|
29496
|
+
selfSignature: cpfpUserSignature,
|
|
28427
29497
|
publicKey: internalNode.signingPublicKey
|
|
28428
29498
|
});
|
|
28429
29499
|
}
|
|
28430
|
-
|
|
28431
|
-
|
|
28432
|
-
|
|
28433
|
-
|
|
28434
|
-
|
|
28435
|
-
|
|
28436
|
-
|
|
28437
|
-
|
|
28438
|
-
|
|
28439
|
-
|
|
28440
|
-
const
|
|
28441
|
-
|
|
28442
|
-
|
|
29500
|
+
const directNodeTx = getTxFromRawTxBytes(
|
|
29501
|
+
creationNode.directNodeTxSigningJob.rawTx
|
|
29502
|
+
);
|
|
29503
|
+
const directNodeTxSighash = getSigHashFromTx(
|
|
29504
|
+
directNodeTx,
|
|
29505
|
+
0,
|
|
29506
|
+
parentTxOutput
|
|
29507
|
+
);
|
|
29508
|
+
let directNodeTxSignature = new Uint8Array();
|
|
29509
|
+
if (creationNode.directNodeTxSigningCommitment) {
|
|
29510
|
+
const directUserSignature = await this.config.signer.signFrost({
|
|
29511
|
+
message: directNodeTxSighash,
|
|
29512
|
+
publicKey: creationNode.directNodeTxSigningJob.signingPublicKey,
|
|
29513
|
+
keyDerivation: {
|
|
29514
|
+
type: "leaf" /* LEAF */,
|
|
29515
|
+
path: creationResponseNode.nodeId
|
|
29516
|
+
},
|
|
29517
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
29518
|
+
statechainCommitments: creationResponseNode.directNodeTxSigningResult?.signingNonceCommitments,
|
|
29519
|
+
verifyingKey: internalNode.verificationKey
|
|
29520
|
+
});
|
|
29521
|
+
directNodeTxSignature = await this.config.signer.aggregateFrost({
|
|
29522
|
+
message: directNodeTxSighash,
|
|
29523
|
+
statechainSignatures: creationResponseNode.directNodeTxSigningResult?.signatureShares,
|
|
29524
|
+
statechainPublicKeys: creationResponseNode.directNodeTxSigningResult?.publicKeys,
|
|
29525
|
+
verifyingKey: internalNode.verificationKey,
|
|
29526
|
+
statechainCommitments: creationResponseNode.directNodeTxSigningResult?.signingNonceCommitments,
|
|
29527
|
+
selfCommitment: creationNode.directNodeTxSigningCommitment,
|
|
29528
|
+
selfSignature: directUserSignature,
|
|
29529
|
+
publicKey: internalNode.signingPublicKey
|
|
29530
|
+
});
|
|
29531
|
+
}
|
|
29532
|
+
let cpfpRefundTxSignature = new Uint8Array();
|
|
29533
|
+
let directRefundTxSignature = new Uint8Array();
|
|
29534
|
+
let directFromCpfpRefundTxSignature = new Uint8Array();
|
|
29535
|
+
if (creationNode.refundTxSigningCommitment && creationNode.directRefundTxSigningCommitment && creationNode.directFromCpfpRefundTxSigningCommitment) {
|
|
29536
|
+
const rawCpfpRefundTx = creationNode.refundTxSigningJob?.rawTx;
|
|
29537
|
+
const rawDirectRefundTx = creationNode.directRefundTxSigningJob?.rawTx;
|
|
29538
|
+
const rawDirectFromCpfpRefundTx = creationNode.directFromCpfpRefundTxSigningJob?.rawTx;
|
|
29539
|
+
if (!rawCpfpRefundTx || !rawDirectRefundTx || !rawDirectFromCpfpRefundTx) {
|
|
29540
|
+
throw new Error("refund transaction rawTx is undefined");
|
|
29541
|
+
}
|
|
29542
|
+
if (!creationNode.refundTxSigningJob?.signingPublicKey || !creationNode.directRefundTxSigningJob?.signingPublicKey || !creationNode.directFromCpfpRefundTxSigningJob?.signingPublicKey) {
|
|
29543
|
+
throw new Error("refund transaction signingPublicKey is undefined");
|
|
29544
|
+
}
|
|
29545
|
+
const cpfpRefundTx = getTxFromRawTxBytes(rawCpfpRefundTx);
|
|
29546
|
+
const directRefundTx = getTxFromRawTxBytes(rawDirectRefundTx);
|
|
29547
|
+
const directFromCpfpRefundTx = getTxFromRawTxBytes(
|
|
29548
|
+
rawDirectFromCpfpRefundTx
|
|
29549
|
+
);
|
|
29550
|
+
const cpfpRefundTxSighash = getSigHashFromTx(
|
|
29551
|
+
cpfpRefundTx,
|
|
29552
|
+
0,
|
|
29553
|
+
cpfpNodeTx.getOutput(0)
|
|
29554
|
+
);
|
|
29555
|
+
const directRefundTxSighash = getSigHashFromTx(
|
|
29556
|
+
directRefundTx,
|
|
29557
|
+
0,
|
|
29558
|
+
directNodeTx.getOutput(0)
|
|
29559
|
+
);
|
|
29560
|
+
const directFromCpfpRefundTxSighash = getSigHashFromTx(
|
|
29561
|
+
directFromCpfpRefundTx,
|
|
29562
|
+
0,
|
|
29563
|
+
cpfpNodeTx.getOutput(0)
|
|
29564
|
+
);
|
|
29565
|
+
const cpfpRefundUserSignature = await this.config.signer.signFrost({
|
|
29566
|
+
message: cpfpRefundTxSighash,
|
|
28443
29567
|
publicKey: creationNode.refundTxSigningJob.signingPublicKey,
|
|
28444
29568
|
keyDerivation: {
|
|
28445
29569
|
type: "leaf" /* LEAF */,
|
|
@@ -28449,27 +29573,69 @@ var TreeCreationService = class {
|
|
|
28449
29573
|
statechainCommitments: creationResponseNode.refundTxSigningResult?.signingNonceCommitments,
|
|
28450
29574
|
verifyingKey: internalNode.verificationKey
|
|
28451
29575
|
});
|
|
28452
|
-
|
|
28453
|
-
message:
|
|
29576
|
+
cpfpRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
29577
|
+
message: cpfpRefundTxSighash,
|
|
28454
29578
|
statechainSignatures: creationResponseNode.refundTxSigningResult?.signatureShares,
|
|
28455
29579
|
statechainPublicKeys: creationResponseNode.refundTxSigningResult?.publicKeys,
|
|
28456
29580
|
verifyingKey: internalNode.verificationKey,
|
|
28457
29581
|
statechainCommitments: creationResponseNode.refundTxSigningResult?.signingNonceCommitments,
|
|
28458
29582
|
selfCommitment: creationNode.refundTxSigningCommitment,
|
|
28459
|
-
selfSignature:
|
|
29583
|
+
selfSignature: cpfpRefundUserSignature,
|
|
29584
|
+
publicKey: internalNode.signingPublicKey
|
|
29585
|
+
});
|
|
29586
|
+
const keyDerivation = {
|
|
29587
|
+
type: "leaf" /* LEAF */,
|
|
29588
|
+
path: creationResponseNode.nodeId
|
|
29589
|
+
};
|
|
29590
|
+
const directRefundUserSignature = await this.config.signer.signFrost({
|
|
29591
|
+
message: directRefundTxSighash,
|
|
29592
|
+
publicKey: creationNode.directRefundTxSigningJob.signingPublicKey,
|
|
29593
|
+
keyDerivation,
|
|
29594
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
29595
|
+
statechainCommitments: creationResponseNode.directRefundTxSigningResult?.signingNonceCommitments,
|
|
29596
|
+
verifyingKey: internalNode.verificationKey
|
|
29597
|
+
});
|
|
29598
|
+
directRefundTxSignature = await this.config.signer.aggregateFrost({
|
|
29599
|
+
message: directRefundTxSighash,
|
|
29600
|
+
statechainSignatures: creationResponseNode.directRefundTxSigningResult?.signatureShares,
|
|
29601
|
+
statechainPublicKeys: creationResponseNode.directRefundTxSigningResult?.publicKeys,
|
|
29602
|
+
verifyingKey: internalNode.verificationKey,
|
|
29603
|
+
statechainCommitments: creationResponseNode.directRefundTxSigningResult?.signingNonceCommitments,
|
|
29604
|
+
selfCommitment: creationNode.directRefundTxSigningCommitment,
|
|
29605
|
+
selfSignature: directRefundUserSignature,
|
|
28460
29606
|
publicKey: internalNode.signingPublicKey
|
|
28461
29607
|
});
|
|
29608
|
+
const directFromCpfpRefundUserSignature = await this.config.signer.signFrost({
|
|
29609
|
+
message: directFromCpfpRefundTxSighash,
|
|
29610
|
+
publicKey: creationNode.directFromCpfpRefundTxSigningJob.signingPublicKey,
|
|
29611
|
+
keyDerivation,
|
|
29612
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
29613
|
+
statechainCommitments: creationResponseNode.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
29614
|
+
verifyingKey: internalNode.verificationKey
|
|
29615
|
+
});
|
|
29616
|
+
directFromCpfpRefundTxSignature = await this.config.signer.aggregateFrost(
|
|
29617
|
+
{
|
|
29618
|
+
message: directFromCpfpRefundTxSighash,
|
|
29619
|
+
statechainSignatures: creationResponseNode.directFromCpfpRefundTxSigningResult?.signatureShares,
|
|
29620
|
+
statechainPublicKeys: creationResponseNode.directFromCpfpRefundTxSigningResult?.publicKeys,
|
|
29621
|
+
verifyingKey: internalNode.verificationKey,
|
|
29622
|
+
statechainCommitments: creationResponseNode.directFromCpfpRefundTxSigningResult?.signingNonceCommitments,
|
|
29623
|
+
selfCommitment: creationNode.directFromCpfpRefundTxSigningCommitment,
|
|
29624
|
+
selfSignature: directFromCpfpRefundUserSignature,
|
|
29625
|
+
publicKey: internalNode.signingPublicKey
|
|
29626
|
+
}
|
|
29627
|
+
);
|
|
28462
29628
|
}
|
|
28463
29629
|
return {
|
|
28464
|
-
tx,
|
|
29630
|
+
tx: cpfpNodeTx,
|
|
29631
|
+
// Return CPFP version for children
|
|
28465
29632
|
signature: {
|
|
28466
29633
|
nodeId: creationResponseNode.nodeId,
|
|
28467
|
-
nodeTxSignature,
|
|
28468
|
-
|
|
28469
|
-
|
|
28470
|
-
|
|
28471
|
-
|
|
28472
|
-
directFromCpfpRefundTxSignature: new Uint8Array()
|
|
29634
|
+
nodeTxSignature: cpfpNodeTxSignature,
|
|
29635
|
+
directNodeTxSignature,
|
|
29636
|
+
refundTxSignature: cpfpRefundTxSignature,
|
|
29637
|
+
directRefundTxSignature,
|
|
29638
|
+
directFromCpfpRefundTxSignature
|
|
28473
29639
|
}
|
|
28474
29640
|
};
|
|
28475
29641
|
}
|
|
@@ -28559,13 +29725,24 @@ function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes
|
|
|
28559
29725
|
const adaptorPrivateKey = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
28560
29726
|
const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k113.secp256k1.CURVE.n);
|
|
28561
29727
|
const newSig = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
|
|
28562
|
-
|
|
28563
|
-
|
|
29728
|
+
try {
|
|
29729
|
+
if (import_secp256k113.schnorr.verify(newSig, hash, pubkey)) {
|
|
29730
|
+
return newSig;
|
|
29731
|
+
}
|
|
29732
|
+
} catch (e) {
|
|
29733
|
+
console.error("[applyAdaptorToSignature] Addition verification failed:", e);
|
|
28564
29734
|
}
|
|
28565
29735
|
const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k113.secp256k1.CURVE.n);
|
|
28566
29736
|
const altSig = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(altS, 32)]);
|
|
28567
|
-
|
|
28568
|
-
|
|
29737
|
+
try {
|
|
29738
|
+
if (import_secp256k113.schnorr.verify(altSig, hash, pubkey)) {
|
|
29739
|
+
return altSig;
|
|
29740
|
+
}
|
|
29741
|
+
} catch (e) {
|
|
29742
|
+
console.error(
|
|
29743
|
+
"[applyAdaptorToSignature] Subtraction verification failed:",
|
|
29744
|
+
e
|
|
29745
|
+
);
|
|
28569
29746
|
}
|
|
28570
29747
|
throw new Error("Cannot apply adaptor to signature");
|
|
28571
29748
|
}
|
|
@@ -28654,8 +29831,45 @@ var SigningService = class {
|
|
|
28654
29831
|
constructor(config) {
|
|
28655
29832
|
this.config = config;
|
|
28656
29833
|
}
|
|
28657
|
-
async
|
|
29834
|
+
async signRefundsInternal(refundTx, sighash, leaf, signingCommitments) {
|
|
28658
29835
|
const leafSigningJobs = [];
|
|
29836
|
+
const signingCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
29837
|
+
if (!signingCommitments) {
|
|
29838
|
+
throw new ValidationError("Invalid signing commitments", {
|
|
29839
|
+
field: "signingNonceCommitments",
|
|
29840
|
+
value: signingCommitments,
|
|
29841
|
+
expected: "Non-null signing commitments"
|
|
29842
|
+
});
|
|
29843
|
+
}
|
|
29844
|
+
const signingResult = await this.config.signer.signFrost({
|
|
29845
|
+
message: sighash,
|
|
29846
|
+
keyDerivation: leaf.keyDerivation,
|
|
29847
|
+
publicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
29848
|
+
leaf.keyDerivation
|
|
29849
|
+
),
|
|
29850
|
+
selfCommitment: signingCommitment,
|
|
29851
|
+
statechainCommitments: signingCommitments,
|
|
29852
|
+
adaptorPubKey: new Uint8Array(),
|
|
29853
|
+
verifyingKey: leaf.leaf.verifyingPublicKey
|
|
29854
|
+
});
|
|
29855
|
+
leafSigningJobs.push({
|
|
29856
|
+
leafId: leaf.leaf.id,
|
|
29857
|
+
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
29858
|
+
leaf.keyDerivation
|
|
29859
|
+
),
|
|
29860
|
+
rawTx: refundTx.toBytes(),
|
|
29861
|
+
signingNonceCommitment: signingCommitment.commitment,
|
|
29862
|
+
userSignature: signingResult,
|
|
29863
|
+
signingCommitments: {
|
|
29864
|
+
signingCommitments
|
|
29865
|
+
}
|
|
29866
|
+
});
|
|
29867
|
+
return leafSigningJobs;
|
|
29868
|
+
}
|
|
29869
|
+
async signRefunds(leaves, receiverIdentityPubkey, cpfpSigningCommitments, directSigningCommitments, directFromCpfpSigningCommitments) {
|
|
29870
|
+
const cpfpLeafSigningJobs = [];
|
|
29871
|
+
const directLeafSigningJobs = [];
|
|
29872
|
+
const directFromCpfpLeafSigningJobs = [];
|
|
28659
29873
|
for (let i = 0; i < leaves.length; i++) {
|
|
28660
29874
|
const leaf = leaves[i];
|
|
28661
29875
|
if (!leaf?.leaf) {
|
|
@@ -28666,14 +29880,20 @@ var SigningService = class {
|
|
|
28666
29880
|
});
|
|
28667
29881
|
}
|
|
28668
29882
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
28669
|
-
const
|
|
29883
|
+
const cpfpNodeOutPoint = {
|
|
28670
29884
|
txid: (0, import_utils19.hexToBytes)(getTxId(nodeTx)),
|
|
28671
29885
|
index: 0
|
|
28672
29886
|
};
|
|
28673
29887
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
28674
|
-
const
|
|
28675
|
-
|
|
28676
|
-
|
|
29888
|
+
const sequence = currRefundTx.getInput(0).sequence;
|
|
29889
|
+
if (!sequence) {
|
|
29890
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
29891
|
+
field: "sequence",
|
|
29892
|
+
value: currRefundTx.getInput(0),
|
|
29893
|
+
expected: "Non-null sequence"
|
|
29894
|
+
});
|
|
29895
|
+
}
|
|
29896
|
+
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
28677
29897
|
const amountSats = currRefundTx.getOutput(0).amount;
|
|
28678
29898
|
if (amountSats === void 0) {
|
|
28679
29899
|
throw new ValidationError("Invalid refund transaction", {
|
|
@@ -28682,48 +29902,90 @@ var SigningService = class {
|
|
|
28682
29902
|
expected: "Non-null amount"
|
|
28683
29903
|
});
|
|
28684
29904
|
}
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
29905
|
+
let directNodeTx;
|
|
29906
|
+
let directNodeOutPoint;
|
|
29907
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
29908
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
29909
|
+
directNodeOutPoint = {
|
|
29910
|
+
txid: (0, import_utils19.hexToBytes)(getTxId(directNodeTx)),
|
|
29911
|
+
index: 0
|
|
29912
|
+
};
|
|
29913
|
+
}
|
|
29914
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
29915
|
+
sequence: nextSequence,
|
|
29916
|
+
directSequence: nextDirectSequence,
|
|
29917
|
+
input: cpfpNodeOutPoint,
|
|
29918
|
+
directInput: directNodeOutPoint,
|
|
28688
29919
|
amountSats,
|
|
28689
|
-
receiverIdentityPubkey,
|
|
28690
|
-
this.config.getNetwork()
|
|
29920
|
+
receivingPubkey: receiverIdentityPubkey,
|
|
29921
|
+
network: this.config.getNetwork()
|
|
29922
|
+
});
|
|
29923
|
+
const refundSighash = getSigHashFromTx(
|
|
29924
|
+
cpfpRefundTx,
|
|
29925
|
+
0,
|
|
29926
|
+
nodeTx.getOutput(0)
|
|
28691
29927
|
);
|
|
28692
|
-
const
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
|
|
28696
|
-
|
|
28697
|
-
|
|
28698
|
-
|
|
28699
|
-
|
|
28700
|
-
|
|
29928
|
+
const signingJobs = await this.signRefundsInternal(
|
|
29929
|
+
cpfpRefundTx,
|
|
29930
|
+
refundSighash,
|
|
29931
|
+
leaf,
|
|
29932
|
+
cpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29933
|
+
);
|
|
29934
|
+
cpfpLeafSigningJobs.push(...signingJobs);
|
|
29935
|
+
if (directRefundTx) {
|
|
29936
|
+
if (!directNodeTx) {
|
|
29937
|
+
throw new ValidationError(
|
|
29938
|
+
"Direct node transaction undefined while direct refund transaction is defined",
|
|
29939
|
+
{
|
|
29940
|
+
field: "directNodeTx",
|
|
29941
|
+
value: directNodeTx,
|
|
29942
|
+
expected: "Non-null direct node transaction"
|
|
29943
|
+
}
|
|
29944
|
+
);
|
|
29945
|
+
}
|
|
29946
|
+
const refundSighash2 = getSigHashFromTx(
|
|
29947
|
+
directRefundTx,
|
|
29948
|
+
0,
|
|
29949
|
+
directNodeTx.getOutput(0)
|
|
29950
|
+
);
|
|
29951
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
29952
|
+
directRefundTx,
|
|
29953
|
+
refundSighash2,
|
|
29954
|
+
leaf,
|
|
29955
|
+
directSigningCommitments[i]?.signingNonceCommitments
|
|
29956
|
+
);
|
|
29957
|
+
directLeafSigningJobs.push(...signingJobs2);
|
|
28701
29958
|
}
|
|
28702
|
-
|
|
28703
|
-
|
|
28704
|
-
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
});
|
|
28713
|
-
leafSigningJobs.push({
|
|
28714
|
-
leafId: leaf.leaf.id,
|
|
28715
|
-
signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
|
|
28716
|
-
leaf.keyDerivation
|
|
28717
|
-
),
|
|
28718
|
-
rawTx: refundTx.toBytes(),
|
|
28719
|
-
signingNonceCommitment: signingCommitment.commitment,
|
|
28720
|
-
userSignature: signingResult,
|
|
28721
|
-
signingCommitments: {
|
|
28722
|
-
signingCommitments: signingNonceCommitments
|
|
29959
|
+
if (directFromCpfpRefundTx) {
|
|
29960
|
+
if (!directNodeTx) {
|
|
29961
|
+
throw new ValidationError(
|
|
29962
|
+
"Direct node transaction undefined while direct from CPFP refund transaction is defined",
|
|
29963
|
+
{
|
|
29964
|
+
field: "directNodeTx",
|
|
29965
|
+
value: directNodeTx,
|
|
29966
|
+
expected: "Non-null direct node transaction"
|
|
29967
|
+
}
|
|
29968
|
+
);
|
|
28723
29969
|
}
|
|
28724
|
-
|
|
29970
|
+
const refundSighash2 = getSigHashFromTx(
|
|
29971
|
+
directFromCpfpRefundTx,
|
|
29972
|
+
0,
|
|
29973
|
+
nodeTx.getOutput(0)
|
|
29974
|
+
);
|
|
29975
|
+
const signingJobs2 = await this.signRefundsInternal(
|
|
29976
|
+
directFromCpfpRefundTx,
|
|
29977
|
+
refundSighash2,
|
|
29978
|
+
leaf,
|
|
29979
|
+
directFromCpfpSigningCommitments[i]?.signingNonceCommitments
|
|
29980
|
+
);
|
|
29981
|
+
directFromCpfpLeafSigningJobs.push(...signingJobs2);
|
|
29982
|
+
}
|
|
28725
29983
|
}
|
|
28726
|
-
return
|
|
29984
|
+
return {
|
|
29985
|
+
cpfpLeafSigningJobs,
|
|
29986
|
+
directLeafSigningJobs,
|
|
29987
|
+
directFromCpfpLeafSigningJobs
|
|
29988
|
+
};
|
|
28727
29989
|
}
|
|
28728
29990
|
};
|
|
28729
29991
|
|
|
@@ -28731,9 +29993,32 @@ var SigningService = class {
|
|
|
28731
29993
|
init_buffer();
|
|
28732
29994
|
var import_utils20 = require("@noble/curves/abstract/utils");
|
|
28733
29995
|
var import_secp256k114 = require("@noble/curves/secp256k1");
|
|
28734
|
-
var
|
|
29996
|
+
var btc3 = __toESM(require("@scure/btc-signer"), 1);
|
|
28735
29997
|
var import_btc_signer6 = require("@scure/btc-signer");
|
|
28736
29998
|
var import_utils21 = require("@scure/btc-signer/utils");
|
|
29999
|
+
|
|
30000
|
+
// src/utils/fetch.ts
|
|
30001
|
+
init_buffer();
|
|
30002
|
+
var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch : null;
|
|
30003
|
+
var Headers = globalThis.Headers ?? null;
|
|
30004
|
+
var getFetch = () => {
|
|
30005
|
+
if (!fetchImpl) {
|
|
30006
|
+
throw new Error(
|
|
30007
|
+
"Fetch implementation is not set. Please set it using setFetch()."
|
|
30008
|
+
);
|
|
30009
|
+
}
|
|
30010
|
+
if (!Headers) {
|
|
30011
|
+
throw new Error(
|
|
30012
|
+
"Headers implementation is not set. Please set it using setFetch()."
|
|
30013
|
+
);
|
|
30014
|
+
}
|
|
30015
|
+
return {
|
|
30016
|
+
fetch: fetchImpl,
|
|
30017
|
+
Headers
|
|
30018
|
+
};
|
|
30019
|
+
};
|
|
30020
|
+
|
|
30021
|
+
// src/tests/utils/test-faucet.ts
|
|
28737
30022
|
var STATIC_FAUCET_KEY = (0, import_utils20.hexToBytes)(
|
|
28738
30023
|
"deadbeef1337cafe4242424242424242deadbeef1337cafe4242424242424242"
|
|
28739
30024
|
);
|
|
@@ -28877,7 +30162,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
28877
30162
|
}
|
|
28878
30163
|
async sendFaucetCoinToP2WPKHAddress(pubKey) {
|
|
28879
30164
|
const sendToPubKeyTx = new import_btc_signer6.Transaction();
|
|
28880
|
-
const p2wpkhAddress =
|
|
30165
|
+
const p2wpkhAddress = btc3.p2wpkh(pubKey, getNetwork(4 /* LOCAL */)).address;
|
|
28881
30166
|
if (!p2wpkhAddress) {
|
|
28882
30167
|
throw new Error("Invalid P2WPKH address");
|
|
28883
30168
|
}
|
|
@@ -28933,12 +30218,13 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
28933
30218
|
}
|
|
28934
30219
|
async call(method, params) {
|
|
28935
30220
|
try {
|
|
28936
|
-
const
|
|
30221
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
30222
|
+
const response = await fetch2(this.url, {
|
|
28937
30223
|
method: "POST",
|
|
28938
|
-
headers: {
|
|
30224
|
+
headers: new Headers2({
|
|
28939
30225
|
"Content-Type": "application/json",
|
|
28940
30226
|
Authorization: "Basic " + btoa(`${this.username}:${this.password}`)
|
|
28941
|
-
},
|
|
30227
|
+
}),
|
|
28942
30228
|
body: JSON.stringify({
|
|
28943
30229
|
jsonrpc: "1.0",
|
|
28944
30230
|
id: "spark-js",
|
|
@@ -29313,31 +30599,37 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29313
30599
|
}
|
|
29314
30600
|
}
|
|
29315
30601
|
async getLeaves(isBalanceCheck = false) {
|
|
29316
|
-
const
|
|
29317
|
-
|
|
29318
|
-
|
|
29319
|
-
|
|
29320
|
-
|
|
29321
|
-
|
|
29322
|
-
|
|
29323
|
-
}
|
|
30602
|
+
const operatorToLeaves = /* @__PURE__ */ new Map();
|
|
30603
|
+
const ownerIdentityPubkey = await this.config.signer.getIdentityPublicKey();
|
|
30604
|
+
let signingOperators = Object.entries(this.config.getSigningOperators());
|
|
30605
|
+
if (isBalanceCheck) {
|
|
30606
|
+
signingOperators = signingOperators.filter(
|
|
30607
|
+
([id, _]) => id === this.config.getCoordinatorIdentifier()
|
|
30608
|
+
);
|
|
30609
|
+
}
|
|
30610
|
+
await Promise.all(
|
|
30611
|
+
signingOperators.map(async ([id, operator]) => {
|
|
30612
|
+
const leaves2 = await this.queryNodes(
|
|
30613
|
+
{
|
|
30614
|
+
source: {
|
|
30615
|
+
$case: "ownerIdentityPubkey",
|
|
30616
|
+
ownerIdentityPubkey
|
|
30617
|
+
},
|
|
30618
|
+
includeParents: false,
|
|
30619
|
+
network: NetworkToProto[this.config.getNetwork()]
|
|
30620
|
+
},
|
|
30621
|
+
operator.address
|
|
30622
|
+
);
|
|
30623
|
+
operatorToLeaves.set(id, leaves2);
|
|
30624
|
+
})
|
|
30625
|
+
);
|
|
30626
|
+
const leaves = operatorToLeaves.get(
|
|
30627
|
+
this.config.getCoordinatorIdentifier()
|
|
30628
|
+
);
|
|
29324
30629
|
const leavesToIgnore = /* @__PURE__ */ new Set();
|
|
29325
30630
|
if (!isBalanceCheck) {
|
|
29326
|
-
for (const [id,
|
|
29327
|
-
this.config.getSigningOperators()
|
|
29328
|
-
)) {
|
|
30631
|
+
for (const [id, operatorLeaves] of operatorToLeaves) {
|
|
29329
30632
|
if (id !== this.config.getCoordinatorIdentifier()) {
|
|
29330
|
-
const operatorLeaves = await this.queryNodes(
|
|
29331
|
-
{
|
|
29332
|
-
source: {
|
|
29333
|
-
$case: "ownerIdentityPubkey",
|
|
29334
|
-
ownerIdentityPubkey: await this.config.signer.getIdentityPublicKey()
|
|
29335
|
-
},
|
|
29336
|
-
includeParents: false,
|
|
29337
|
-
network: NetworkToProto[this.config.getNetwork()]
|
|
29338
|
-
},
|
|
29339
|
-
operator.address
|
|
29340
|
-
);
|
|
29341
30633
|
for (const [nodeId, leaf] of Object.entries(leaves.nodes)) {
|
|
29342
30634
|
const operatorLeaf = operatorLeaves.nodes[nodeId];
|
|
29343
30635
|
if (!operatorLeaf) {
|
|
@@ -29778,21 +31070,68 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29778
31070
|
}
|
|
29779
31071
|
}))
|
|
29780
31072
|
);
|
|
29781
|
-
const {
|
|
31073
|
+
const {
|
|
31074
|
+
transfer,
|
|
31075
|
+
signatureMap,
|
|
31076
|
+
directSignatureMap,
|
|
31077
|
+
directFromCpfpSignatureMap
|
|
31078
|
+
} = await this.transferService.startSwapSignRefund(
|
|
29782
31079
|
leafKeyTweaks,
|
|
29783
31080
|
(0, import_utils23.hexToBytes)(this.config.getSspIdentityPublicKey()),
|
|
29784
31081
|
new Date(Date.now() + 2 * 60 * 1e3)
|
|
29785
31082
|
);
|
|
29786
31083
|
try {
|
|
29787
31084
|
if (!transfer.leaves[0]?.leaf) {
|
|
31085
|
+
console.error("[processSwapBatch] First leaf is missing");
|
|
29788
31086
|
throw new Error("Failed to get leaf");
|
|
29789
31087
|
}
|
|
29790
|
-
const
|
|
29791
|
-
if (!
|
|
29792
|
-
|
|
31088
|
+
const cpfpRefundSignature = signatureMap.get(transfer.leaves[0].leaf.id);
|
|
31089
|
+
if (!cpfpRefundSignature) {
|
|
31090
|
+
console.error(
|
|
31091
|
+
"[processSwapBatch] Missing CPFP refund signature for first leaf"
|
|
31092
|
+
);
|
|
31093
|
+
throw new Error("Failed to get CPFP refund signature");
|
|
31094
|
+
}
|
|
31095
|
+
const directRefundSignature = directSignatureMap.get(
|
|
31096
|
+
transfer.leaves[0].leaf.id
|
|
31097
|
+
);
|
|
31098
|
+
if (!directRefundSignature) {
|
|
31099
|
+
console.error(
|
|
31100
|
+
"[processSwapBatch] Missing direct refund signature for first leaf"
|
|
31101
|
+
);
|
|
31102
|
+
throw new Error("Failed to get direct refund signature");
|
|
31103
|
+
}
|
|
31104
|
+
const directFromCpfpRefundSignature = directFromCpfpSignatureMap.get(
|
|
31105
|
+
transfer.leaves[0].leaf.id
|
|
31106
|
+
);
|
|
31107
|
+
if (!directFromCpfpRefundSignature) {
|
|
31108
|
+
console.error(
|
|
31109
|
+
"[processSwapBatch] Missing direct from CPFP refund signature for first leaf"
|
|
31110
|
+
);
|
|
31111
|
+
throw new Error("Failed to get direct from CPFP refund signature");
|
|
31112
|
+
}
|
|
31113
|
+
const {
|
|
31114
|
+
adaptorPrivateKey: cpfpAdaptorPrivateKey,
|
|
31115
|
+
adaptorSignature: cpfpAdaptorSignature
|
|
31116
|
+
} = generateAdaptorFromSignature(cpfpRefundSignature);
|
|
31117
|
+
let directAdaptorPrivateKey = new Uint8Array();
|
|
31118
|
+
let directAdaptorSignature = new Uint8Array();
|
|
31119
|
+
let directFromCpfpAdaptorPrivateKey = new Uint8Array();
|
|
31120
|
+
let directFromCpfpAdaptorSignature = new Uint8Array();
|
|
31121
|
+
if (directRefundSignature.length > 0) {
|
|
31122
|
+
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(directRefundSignature);
|
|
31123
|
+
directAdaptorPrivateKey = adaptorPrivateKey;
|
|
31124
|
+
directAdaptorSignature = adaptorSignature;
|
|
31125
|
+
}
|
|
31126
|
+
if (directFromCpfpRefundSignature.length > 0) {
|
|
31127
|
+
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(directFromCpfpRefundSignature);
|
|
31128
|
+
directFromCpfpAdaptorPrivateKey = adaptorPrivateKey;
|
|
31129
|
+
directFromCpfpAdaptorSignature = adaptorSignature;
|
|
29793
31130
|
}
|
|
29794
|
-
const { adaptorPrivateKey, adaptorSignature } = generateAdaptorFromSignature(refundSignature);
|
|
29795
31131
|
if (!transfer.leaves[0].leaf) {
|
|
31132
|
+
console.error(
|
|
31133
|
+
"[processSwapBatch] First leaf missing when preparing user leaves"
|
|
31134
|
+
);
|
|
29796
31135
|
throw new Error("Failed to get leaf");
|
|
29797
31136
|
}
|
|
29798
31137
|
const userLeaves = [];
|
|
@@ -29801,37 +31140,113 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29801
31140
|
raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
29802
31141
|
transfer.leaves[0].intermediateRefundTx
|
|
29803
31142
|
),
|
|
29804
|
-
|
|
31143
|
+
direct_raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
31144
|
+
transfer.leaves[0].intermediateDirectRefundTx
|
|
31145
|
+
),
|
|
31146
|
+
direct_from_cpfp_raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
31147
|
+
transfer.leaves[0].intermediateDirectFromCpfpRefundTx
|
|
31148
|
+
),
|
|
31149
|
+
adaptor_added_signature: (0, import_utils23.bytesToHex)(cpfpAdaptorSignature),
|
|
31150
|
+
direct_adaptor_added_signature: (0, import_utils23.bytesToHex)(directAdaptorSignature),
|
|
31151
|
+
direct_from_cpfp_adaptor_added_signature: (0, import_utils23.bytesToHex)(
|
|
31152
|
+
directFromCpfpAdaptorSignature
|
|
31153
|
+
)
|
|
29805
31154
|
});
|
|
29806
31155
|
for (let i = 1; i < transfer.leaves.length; i++) {
|
|
29807
31156
|
const leaf = transfer.leaves[i];
|
|
29808
31157
|
if (!leaf?.leaf) {
|
|
31158
|
+
console.error(`[processSwapBatch] Leaf ${i + 1} is missing`);
|
|
29809
31159
|
throw new Error("Failed to get leaf");
|
|
29810
31160
|
}
|
|
29811
|
-
const
|
|
29812
|
-
if (!
|
|
29813
|
-
|
|
31161
|
+
const cpfpRefundSignature2 = signatureMap.get(leaf.leaf.id);
|
|
31162
|
+
if (!cpfpRefundSignature2) {
|
|
31163
|
+
console.error(
|
|
31164
|
+
`[processSwapBatch] Missing CPFP refund signature for leaf ${i + 1}`
|
|
31165
|
+
);
|
|
31166
|
+
throw new Error("Failed to get CPFP refund signature");
|
|
31167
|
+
}
|
|
31168
|
+
const directRefundSignature2 = directSignatureMap.get(leaf.leaf.id);
|
|
31169
|
+
if (!directRefundSignature2) {
|
|
31170
|
+
console.error(
|
|
31171
|
+
`[processSwapBatch] Missing direct refund signature for leaf ${i + 1}`
|
|
31172
|
+
);
|
|
31173
|
+
throw new Error("Failed to get direct refund signature");
|
|
31174
|
+
}
|
|
31175
|
+
const directFromCpfpRefundSignature2 = directFromCpfpSignatureMap.get(
|
|
31176
|
+
leaf.leaf.id
|
|
31177
|
+
);
|
|
31178
|
+
if (!directFromCpfpRefundSignature2) {
|
|
31179
|
+
console.error(
|
|
31180
|
+
`[processSwapBatch] Missing direct from CPFP refund signature for leaf ${i + 1}`
|
|
31181
|
+
);
|
|
31182
|
+
throw new Error("Failed to get direct from CPFP refund signature");
|
|
29814
31183
|
}
|
|
29815
|
-
const
|
|
29816
|
-
|
|
29817
|
-
|
|
31184
|
+
const cpfpSignature = generateSignatureFromExistingAdaptor(
|
|
31185
|
+
cpfpRefundSignature2,
|
|
31186
|
+
cpfpAdaptorPrivateKey
|
|
29818
31187
|
);
|
|
31188
|
+
let directSignature = new Uint8Array();
|
|
31189
|
+
if (directRefundSignature2.length > 0) {
|
|
31190
|
+
directSignature = generateSignatureFromExistingAdaptor(
|
|
31191
|
+
directRefundSignature2,
|
|
31192
|
+
directAdaptorPrivateKey
|
|
31193
|
+
);
|
|
31194
|
+
}
|
|
31195
|
+
let directFromCpfpSignature = new Uint8Array();
|
|
31196
|
+
if (directFromCpfpRefundSignature2.length > 0) {
|
|
31197
|
+
directFromCpfpSignature = generateSignatureFromExistingAdaptor(
|
|
31198
|
+
directFromCpfpRefundSignature2,
|
|
31199
|
+
directFromCpfpAdaptorPrivateKey
|
|
31200
|
+
);
|
|
31201
|
+
}
|
|
29819
31202
|
userLeaves.push({
|
|
29820
31203
|
leaf_id: leaf.leaf.id,
|
|
29821
31204
|
raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
29822
31205
|
leaf.intermediateRefundTx
|
|
29823
31206
|
),
|
|
29824
|
-
|
|
31207
|
+
direct_raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
31208
|
+
leaf.intermediateDirectRefundTx
|
|
31209
|
+
),
|
|
31210
|
+
direct_from_cpfp_raw_unsigned_refund_transaction: (0, import_utils23.bytesToHex)(
|
|
31211
|
+
leaf.intermediateDirectFromCpfpRefundTx
|
|
31212
|
+
),
|
|
31213
|
+
adaptor_added_signature: (0, import_utils23.bytesToHex)(cpfpSignature),
|
|
31214
|
+
direct_adaptor_added_signature: (0, import_utils23.bytesToHex)(directSignature),
|
|
31215
|
+
direct_from_cpfp_adaptor_added_signature: (0, import_utils23.bytesToHex)(
|
|
31216
|
+
directFromCpfpSignature
|
|
31217
|
+
)
|
|
29825
31218
|
});
|
|
29826
31219
|
}
|
|
29827
31220
|
const sspClient = this.getSspClient();
|
|
29828
|
-
const
|
|
29829
|
-
import_secp256k115.secp256k1.getPublicKey(
|
|
31221
|
+
const cpfpAdaptorPubkey = (0, import_utils23.bytesToHex)(
|
|
31222
|
+
import_secp256k115.secp256k1.getPublicKey(cpfpAdaptorPrivateKey)
|
|
29830
31223
|
);
|
|
31224
|
+
if (!cpfpAdaptorPubkey) {
|
|
31225
|
+
throw new Error("Failed to generate CPFP adaptor pubkey");
|
|
31226
|
+
}
|
|
31227
|
+
let directAdaptorPubkey;
|
|
31228
|
+
if (directAdaptorPrivateKey.length > 0) {
|
|
31229
|
+
directAdaptorPubkey = (0, import_utils23.bytesToHex)(
|
|
31230
|
+
import_secp256k115.secp256k1.getPublicKey(directAdaptorPrivateKey)
|
|
31231
|
+
);
|
|
31232
|
+
}
|
|
31233
|
+
let directFromCpfpAdaptorPubkey;
|
|
31234
|
+
if (directFromCpfpAdaptorPrivateKey.length > 0) {
|
|
31235
|
+
directFromCpfpAdaptorPubkey = (0, import_utils23.bytesToHex)(
|
|
31236
|
+
import_secp256k115.secp256k1.getPublicKey(directFromCpfpAdaptorPrivateKey)
|
|
31237
|
+
);
|
|
31238
|
+
}
|
|
29831
31239
|
let request = null;
|
|
31240
|
+
const targetAmountSats = targetAmounts?.reduce((acc, amount) => acc + amount, 0) || leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0);
|
|
31241
|
+
const totalAmountSats = leavesBatch.reduce(
|
|
31242
|
+
(acc, leaf) => acc + leaf.value,
|
|
31243
|
+
0
|
|
31244
|
+
);
|
|
29832
31245
|
request = await sspClient.requestLeaveSwap({
|
|
29833
31246
|
userLeaves,
|
|
29834
|
-
adaptorPubkey,
|
|
31247
|
+
adaptorPubkey: cpfpAdaptorPubkey,
|
|
31248
|
+
directAdaptorPubkey,
|
|
31249
|
+
directFromCpfpAdaptorPubkey,
|
|
29835
31250
|
targetAmountSats: targetAmounts?.reduce((acc, amount) => acc + amount, 0) || leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0),
|
|
29836
31251
|
totalAmountSats: leavesBatch.reduce((acc, leaf) => acc + leaf.value, 0),
|
|
29837
31252
|
targetAmountSatsList: targetAmounts,
|
|
@@ -29840,6 +31255,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29840
31255
|
idempotencyKey: (0, import_uuidv75.uuidv7)()
|
|
29841
31256
|
});
|
|
29842
31257
|
if (!request) {
|
|
31258
|
+
console.error("[processSwapBatch] Leave swap request returned null");
|
|
29843
31259
|
throw new Error("Failed to request leaves swap. No response returned.");
|
|
29844
31260
|
}
|
|
29845
31261
|
const nodes = await this.queryNodes({
|
|
@@ -29853,50 +31269,140 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29853
31269
|
network: NetworkToProto[this.config.getNetwork()]
|
|
29854
31270
|
});
|
|
29855
31271
|
if (Object.values(nodes.nodes).length !== request.swapLeaves.length) {
|
|
31272
|
+
console.error("[processSwapBatch] Node count mismatch:", {
|
|
31273
|
+
actual: Object.values(nodes.nodes).length,
|
|
31274
|
+
expected: request.swapLeaves.length
|
|
31275
|
+
});
|
|
29856
31276
|
throw new Error("Expected same number of nodes as swapLeaves");
|
|
29857
31277
|
}
|
|
29858
31278
|
for (const [nodeId, node] of Object.entries(nodes.nodes)) {
|
|
29859
31279
|
if (!node.nodeTx) {
|
|
31280
|
+
console.error(`[processSwapBatch] Node tx missing for ${nodeId}`);
|
|
29860
31281
|
throw new Error(`Node tx not found for leaf ${nodeId}`);
|
|
29861
31282
|
}
|
|
29862
31283
|
if (!node.verifyingPublicKey) {
|
|
31284
|
+
console.error(
|
|
31285
|
+
`[processSwapBatch] Verifying public key missing for ${nodeId}`
|
|
31286
|
+
);
|
|
29863
31287
|
throw new Error(`Node public key not found for leaf ${nodeId}`);
|
|
29864
31288
|
}
|
|
29865
31289
|
const leaf = request.swapLeaves.find((leaf2) => leaf2.leafId === nodeId);
|
|
29866
31290
|
if (!leaf) {
|
|
31291
|
+
console.error(`[processSwapBatch] Leaf not found for node ${nodeId}`);
|
|
29867
31292
|
throw new Error(`Leaf not found for node ${nodeId}`);
|
|
29868
31293
|
}
|
|
29869
|
-
const
|
|
29870
|
-
const
|
|
29871
|
-
const
|
|
29872
|
-
const
|
|
31294
|
+
const cpfpNodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
31295
|
+
const cpfpRefundTxBytes = (0, import_utils23.hexToBytes)(leaf.rawUnsignedRefundTransaction);
|
|
31296
|
+
const cpfpRefundTx = getTxFromRawTxBytes(cpfpRefundTxBytes);
|
|
31297
|
+
const cpfpSighash = getSigHashFromTx(
|
|
31298
|
+
cpfpRefundTx,
|
|
31299
|
+
0,
|
|
31300
|
+
cpfpNodeTx.getOutput(0)
|
|
31301
|
+
);
|
|
29873
31302
|
const nodePublicKey = node.verifyingPublicKey;
|
|
29874
31303
|
const taprootKey = computeTaprootKeyNoScript(nodePublicKey.slice(1));
|
|
29875
|
-
const
|
|
31304
|
+
const cpfpAdaptorSignatureBytes = (0, import_utils23.hexToBytes)(
|
|
31305
|
+
leaf.adaptorSignedSignature
|
|
31306
|
+
);
|
|
31307
|
+
applyAdaptorToSignature(
|
|
31308
|
+
taprootKey.slice(1),
|
|
31309
|
+
cpfpSighash,
|
|
31310
|
+
cpfpAdaptorSignatureBytes,
|
|
31311
|
+
cpfpAdaptorPrivateKey
|
|
31312
|
+
);
|
|
31313
|
+
if (!leaf.directRawUnsignedRefundTransaction) {
|
|
31314
|
+
throw new Error(
|
|
31315
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
31316
|
+
);
|
|
31317
|
+
}
|
|
31318
|
+
if (!leaf.directAdaptorSignedSignature) {
|
|
31319
|
+
throw new Error(
|
|
31320
|
+
`Direct adaptor signed signature missing for node ${nodeId}`
|
|
31321
|
+
);
|
|
31322
|
+
}
|
|
31323
|
+
const directNodeTx = getTxFromRawTxBytes(node.directTx);
|
|
31324
|
+
const directRefundTxBytes = (0, import_utils23.hexToBytes)(
|
|
31325
|
+
leaf.directRawUnsignedRefundTransaction
|
|
31326
|
+
);
|
|
31327
|
+
const directRefundTx = getTxFromRawTxBytes(directRefundTxBytes);
|
|
31328
|
+
const directSighash = getSigHashFromTx(
|
|
31329
|
+
directRefundTx,
|
|
31330
|
+
0,
|
|
31331
|
+
directNodeTx.getOutput(0)
|
|
31332
|
+
);
|
|
31333
|
+
if (!leaf.directFromCpfpAdaptorSignedSignature) {
|
|
31334
|
+
throw new Error(
|
|
31335
|
+
`Direct adaptor signed signature missing for node ${nodeId}`
|
|
31336
|
+
);
|
|
31337
|
+
}
|
|
31338
|
+
const directAdaptorSignatureBytes = (0, import_utils23.hexToBytes)(
|
|
31339
|
+
leaf.directAdaptorSignedSignature
|
|
31340
|
+
);
|
|
31341
|
+
applyAdaptorToSignature(
|
|
31342
|
+
taprootKey.slice(1),
|
|
31343
|
+
directSighash,
|
|
31344
|
+
directAdaptorSignatureBytes,
|
|
31345
|
+
directAdaptorPrivateKey
|
|
31346
|
+
);
|
|
31347
|
+
if (!leaf.directRawUnsignedRefundTransaction) {
|
|
31348
|
+
throw new Error(
|
|
31349
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
31350
|
+
);
|
|
31351
|
+
}
|
|
31352
|
+
if (!leaf.directFromCpfpRawUnsignedRefundTransaction) {
|
|
31353
|
+
throw new Error(
|
|
31354
|
+
`Direct raw unsigned refund transaction missing for node ${nodeId}`
|
|
31355
|
+
);
|
|
31356
|
+
}
|
|
31357
|
+
const directFromCpfpRefundTxBytes = (0, import_utils23.hexToBytes)(
|
|
31358
|
+
leaf.directFromCpfpRawUnsignedRefundTransaction
|
|
31359
|
+
);
|
|
31360
|
+
const directFromCpfpRefundTx = getTxFromRawTxBytes(
|
|
31361
|
+
directFromCpfpRefundTxBytes
|
|
31362
|
+
);
|
|
31363
|
+
const directFromCpfpSighash = getSigHashFromTx(
|
|
31364
|
+
directFromCpfpRefundTx,
|
|
31365
|
+
0,
|
|
31366
|
+
cpfpNodeTx.getOutput(0)
|
|
31367
|
+
);
|
|
31368
|
+
const directFromCpfpAdaptorSignatureBytes = (0, import_utils23.hexToBytes)(
|
|
31369
|
+
leaf.directFromCpfpAdaptorSignedSignature
|
|
31370
|
+
);
|
|
29876
31371
|
applyAdaptorToSignature(
|
|
29877
31372
|
taprootKey.slice(1),
|
|
29878
|
-
|
|
29879
|
-
|
|
29880
|
-
|
|
31373
|
+
directFromCpfpSighash,
|
|
31374
|
+
directFromCpfpAdaptorSignatureBytes,
|
|
31375
|
+
directFromCpfpAdaptorPrivateKey
|
|
29881
31376
|
);
|
|
29882
31377
|
}
|
|
29883
31378
|
await this.transferService.deliverTransferPackage(
|
|
29884
31379
|
transfer,
|
|
29885
31380
|
leafKeyTweaks,
|
|
29886
|
-
signatureMap
|
|
31381
|
+
signatureMap,
|
|
31382
|
+
directSignatureMap,
|
|
31383
|
+
directFromCpfpSignatureMap
|
|
29887
31384
|
);
|
|
29888
31385
|
const completeResponse = await sspClient.completeLeaveSwap({
|
|
29889
|
-
adaptorSecretKey: (0, import_utils23.bytesToHex)(
|
|
31386
|
+
adaptorSecretKey: (0, import_utils23.bytesToHex)(cpfpAdaptorPrivateKey),
|
|
31387
|
+
directAdaptorSecretKey: (0, import_utils23.bytesToHex)(directAdaptorPrivateKey),
|
|
31388
|
+
directFromCpfpAdaptorSecretKey: (0, import_utils23.bytesToHex)(
|
|
31389
|
+
directFromCpfpAdaptorPrivateKey
|
|
31390
|
+
),
|
|
29890
31391
|
userOutboundTransferExternalId: transfer.id,
|
|
29891
31392
|
leavesSwapRequestId: request.id
|
|
29892
31393
|
});
|
|
29893
31394
|
if (!completeResponse || !completeResponse.inboundTransfer?.sparkId) {
|
|
31395
|
+
console.error(
|
|
31396
|
+
"[processSwapBatch] Invalid complete response:",
|
|
31397
|
+
completeResponse
|
|
31398
|
+
);
|
|
29894
31399
|
throw new Error("Failed to complete leaves swap");
|
|
29895
31400
|
}
|
|
29896
31401
|
const incomingTransfer = await this.transferService.queryTransfer(
|
|
29897
31402
|
completeResponse.inboundTransfer.sparkId
|
|
29898
31403
|
);
|
|
29899
31404
|
if (!incomingTransfer) {
|
|
31405
|
+
console.error("[processSwapBatch] No incoming transfer found");
|
|
29900
31406
|
throw new Error("Failed to get incoming transfer");
|
|
29901
31407
|
}
|
|
29902
31408
|
return await this.claimTransfer({
|
|
@@ -29906,6 +31412,11 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
29906
31412
|
optimize: false
|
|
29907
31413
|
});
|
|
29908
31414
|
} catch (e) {
|
|
31415
|
+
console.error("[processSwapBatch] Error details:", {
|
|
31416
|
+
error: e,
|
|
31417
|
+
message: e.message,
|
|
31418
|
+
stack: e.stack
|
|
31419
|
+
});
|
|
29909
31420
|
await this.cancelAllSenderInitiatedTransfers();
|
|
29910
31421
|
throw new Error(`Failed to request leaves swap: ${e}`);
|
|
29911
31422
|
}
|
|
@@ -30376,8 +31887,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30376
31887
|
field: "txid"
|
|
30377
31888
|
});
|
|
30378
31889
|
}
|
|
31890
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
30379
31891
|
const baseUrl = this.config.getElectrsUrl();
|
|
30380
|
-
const headers =
|
|
31892
|
+
const headers = new Headers2();
|
|
30381
31893
|
let txHex;
|
|
30382
31894
|
if (this.config.getNetwork() === 4 /* LOCAL */) {
|
|
30383
31895
|
const localFaucet = BitcoinFaucet.getInstance();
|
|
@@ -30388,9 +31900,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30388
31900
|
const auth = btoa(
|
|
30389
31901
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
30390
31902
|
);
|
|
30391
|
-
headers
|
|
31903
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
30392
31904
|
}
|
|
30393
|
-
const response = await
|
|
31905
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}/hex`, {
|
|
30394
31906
|
headers
|
|
30395
31907
|
});
|
|
30396
31908
|
txHex = await response.text();
|
|
@@ -30518,8 +32030,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30518
32030
|
this.mutexes.set(txid, mutex);
|
|
30519
32031
|
}
|
|
30520
32032
|
const nodes = await mutex.runExclusive(async () => {
|
|
32033
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
30521
32034
|
const baseUrl = this.config.getElectrsUrl();
|
|
30522
|
-
const headers =
|
|
32035
|
+
const headers = new Headers2();
|
|
30523
32036
|
let txHex;
|
|
30524
32037
|
if (this.config.getNetwork() === 4 /* LOCAL */) {
|
|
30525
32038
|
const localFaucet = BitcoinFaucet.getInstance();
|
|
@@ -30530,9 +32043,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30530
32043
|
const auth = btoa(
|
|
30531
32044
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
30532
32045
|
);
|
|
30533
|
-
headers
|
|
32046
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
30534
32047
|
}
|
|
30535
|
-
const response = await
|
|
32048
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}/hex`, {
|
|
30536
32049
|
headers
|
|
30537
32050
|
});
|
|
30538
32051
|
txHex = await response.text();
|
|
@@ -30774,10 +32287,16 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30774
32287
|
const validNodes = [];
|
|
30775
32288
|
for (const node of nodes) {
|
|
30776
32289
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
30777
|
-
const
|
|
30778
|
-
|
|
30779
|
-
|
|
30780
|
-
|
|
32290
|
+
const sequence = nodeTx.getInput(0).sequence;
|
|
32291
|
+
if (!sequence) {
|
|
32292
|
+
throw new ValidationError("Invalid node transaction", {
|
|
32293
|
+
field: "sequence",
|
|
32294
|
+
value: nodeTx.getInput(0),
|
|
32295
|
+
expected: "Non-null sequence"
|
|
32296
|
+
});
|
|
32297
|
+
}
|
|
32298
|
+
const needsRefresh = doesLeafNeedRefresh(sequence, true);
|
|
32299
|
+
if (needsRefresh) {
|
|
30781
32300
|
nodesToExtend.push(node);
|
|
30782
32301
|
nodeIds.push(node.id);
|
|
30783
32302
|
} else {
|
|
@@ -30814,11 +32333,16 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30814
32333
|
const validNodes = [];
|
|
30815
32334
|
for (const node of nodes) {
|
|
30816
32335
|
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
30817
|
-
const
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
32336
|
+
const sequence = refundTx.getInput(0).sequence;
|
|
32337
|
+
if (!sequence) {
|
|
32338
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
32339
|
+
field: "sequence",
|
|
32340
|
+
value: refundTx.getInput(0),
|
|
32341
|
+
expected: "Non-null sequence"
|
|
32342
|
+
});
|
|
32343
|
+
}
|
|
32344
|
+
const needsRefresh = doesLeafNeedRefresh(sequence);
|
|
32345
|
+
if (needsRefresh) {
|
|
30822
32346
|
nodesToRefresh.push(node);
|
|
30823
32347
|
nodeIds.push(node.id);
|
|
30824
32348
|
} else {
|
|
@@ -30852,7 +32376,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30852
32376
|
throw new Error(`parent node ${node.parentNodeId} not found`);
|
|
30853
32377
|
}
|
|
30854
32378
|
const { nodes: nodes2 } = await this.transferService.refreshTimelockNodes(
|
|
30855
|
-
|
|
32379
|
+
node,
|
|
30856
32380
|
parentNode
|
|
30857
32381
|
);
|
|
30858
32382
|
if (nodes2.length !== 1) {
|
|
@@ -30901,7 +32425,9 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30901
32425
|
leavesToClaim.push({
|
|
30902
32426
|
leaf: {
|
|
30903
32427
|
...leaf.leaf,
|
|
30904
|
-
refundTx: leaf.intermediateRefundTx
|
|
32428
|
+
refundTx: leaf.intermediateRefundTx,
|
|
32429
|
+
directRefundTx: leaf.intermediateDirectRefundTx,
|
|
32430
|
+
directFromCpfpRefundTx: leaf.intermediateDirectFromCpfpRefundTx
|
|
30905
32431
|
},
|
|
30906
32432
|
keyDerivation: {
|
|
30907
32433
|
type: "ecies" /* ECIES */,
|
|
@@ -30977,7 +32503,7 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
30977
32503
|
if (type && transfer.type !== type) {
|
|
30978
32504
|
continue;
|
|
30979
32505
|
}
|
|
30980
|
-
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 */) {
|
|
32506
|
+
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 */) {
|
|
30981
32507
|
continue;
|
|
30982
32508
|
}
|
|
30983
32509
|
promises.push(
|
|
@@ -31265,6 +32791,8 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
31265
32791
|
await this.transferService.deliverTransferPackage(
|
|
31266
32792
|
swapResponse.transfer,
|
|
31267
32793
|
leavesToSend,
|
|
32794
|
+
/* @__PURE__ */ new Map(),
|
|
32795
|
+
/* @__PURE__ */ new Map(),
|
|
31268
32796
|
/* @__PURE__ */ new Map()
|
|
31269
32797
|
);
|
|
31270
32798
|
const sspResponse = await sspClient.requestLightningSend({
|
|
@@ -32027,87 +33555,64 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
32027
33555
|
},
|
|
32028
33556
|
includeParents: true
|
|
32029
33557
|
});
|
|
32030
|
-
|
|
32031
|
-
if (!
|
|
33558
|
+
let leaf = response.nodes[nodeId];
|
|
33559
|
+
if (!leaf) {
|
|
32032
33560
|
throw new ValidationError("Node not found", {
|
|
32033
33561
|
field: "nodeId",
|
|
32034
33562
|
value: nodeId
|
|
32035
33563
|
});
|
|
32036
33564
|
}
|
|
32037
|
-
|
|
32038
|
-
|
|
32039
|
-
|
|
32040
|
-
|
|
32041
|
-
|
|
32042
|
-
|
|
32043
|
-
|
|
32044
|
-
|
|
32045
|
-
|
|
32046
|
-
|
|
32047
|
-
|
|
32048
|
-
});
|
|
32049
|
-
}
|
|
32050
|
-
const result = await this.transferService.refreshTimelockNodes(
|
|
32051
|
-
[node],
|
|
32052
|
-
parentNode
|
|
32053
|
-
);
|
|
32054
|
-
const leafIndex = this.leaves.findIndex((leaf) => leaf.id === node.id);
|
|
32055
|
-
if (leafIndex !== -1 && result.nodes.length > 0) {
|
|
32056
|
-
const newNode = result.nodes[0];
|
|
32057
|
-
if (newNode) {
|
|
32058
|
-
this.leaves[leafIndex] = newNode;
|
|
33565
|
+
let parentNode;
|
|
33566
|
+
let hasParentNode = false;
|
|
33567
|
+
if (!leaf.parentNodeId) {
|
|
33568
|
+
} else {
|
|
33569
|
+
hasParentNode = true;
|
|
33570
|
+
parentNode = response.nodes[leaf.parentNodeId];
|
|
33571
|
+
if (!parentNode) {
|
|
33572
|
+
throw new ValidationError("Parent node not found", {
|
|
33573
|
+
field: "parentNodeId",
|
|
33574
|
+
value: leaf.parentNodeId
|
|
33575
|
+
});
|
|
32059
33576
|
}
|
|
32060
33577
|
}
|
|
32061
|
-
|
|
32062
|
-
|
|
32063
|
-
|
|
32064
|
-
|
|
32065
|
-
|
|
32066
|
-
|
|
32067
|
-
|
|
32068
|
-
|
|
32069
|
-
|
|
32070
|
-
|
|
32071
|
-
|
|
32072
|
-
|
|
32073
|
-
|
|
32074
|
-
|
|
32075
|
-
* @returns {Promise<void>} Promise that resolves when the refund timelock is refreshed
|
|
32076
|
-
*/
|
|
32077
|
-
async testOnly_expireTimelockRefundTx(nodeId) {
|
|
32078
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
32079
|
-
this.config.getCoordinatorAddress()
|
|
32080
|
-
);
|
|
32081
|
-
try {
|
|
32082
|
-
const response = await sparkClient.query_nodes({
|
|
32083
|
-
source: {
|
|
32084
|
-
$case: "nodeIds",
|
|
32085
|
-
nodeIds: {
|
|
32086
|
-
nodeIds: [nodeId]
|
|
33578
|
+
const nodeTx = getTxFromRawTxBytes(leaf.nodeTx);
|
|
33579
|
+
const refundTx = getTxFromRawTxBytes(leaf.refundTx);
|
|
33580
|
+
if (hasParentNode) {
|
|
33581
|
+
const nodeTimelock = getCurrentTimelock(nodeTx.getInput(0).sequence);
|
|
33582
|
+
if (nodeTimelock > 100) {
|
|
33583
|
+
const expiredNodeTxLeaf = await this.transferService.testonly_expireTimeLockNodeTx(
|
|
33584
|
+
leaf,
|
|
33585
|
+
parentNode
|
|
33586
|
+
);
|
|
33587
|
+
if (!expiredNodeTxLeaf.nodes[0]) {
|
|
33588
|
+
throw new ValidationError("No expired node tx leaf", {
|
|
33589
|
+
field: "expiredNodeTxLeaf",
|
|
33590
|
+
value: expiredNodeTxLeaf
|
|
33591
|
+
});
|
|
32087
33592
|
}
|
|
32088
|
-
|
|
32089
|
-
|
|
32090
|
-
});
|
|
32091
|
-
const node = response.nodes[nodeId];
|
|
32092
|
-
if (!node) {
|
|
32093
|
-
throw new ValidationError("Node not found", {
|
|
32094
|
-
field: "nodeId",
|
|
32095
|
-
value: nodeId
|
|
32096
|
-
});
|
|
33593
|
+
leaf = expiredNodeTxLeaf.nodes[0];
|
|
33594
|
+
}
|
|
32097
33595
|
}
|
|
32098
|
-
const
|
|
32099
|
-
|
|
32100
|
-
|
|
32101
|
-
|
|
32102
|
-
|
|
32103
|
-
|
|
33596
|
+
const refundTimelock = getCurrentTimelock(refundTx.getInput(0).sequence);
|
|
33597
|
+
if (refundTimelock > 100) {
|
|
33598
|
+
const expiredTxLeaf = await this.transferService.testonly_expireTimeLockRefundtx(leaf);
|
|
33599
|
+
if (!expiredTxLeaf.nodes[0]) {
|
|
33600
|
+
throw new ValidationError("No expired tx leaf", {
|
|
33601
|
+
field: "expiredTxLeaf",
|
|
33602
|
+
value: expiredTxLeaf
|
|
33603
|
+
});
|
|
32104
33604
|
}
|
|
33605
|
+
leaf = expiredTxLeaf.nodes[0];
|
|
33606
|
+
}
|
|
33607
|
+
const leafIndex = this.leaves.findIndex((leaf2) => leaf2.id === leaf2.id);
|
|
33608
|
+
if (leafIndex !== -1) {
|
|
33609
|
+
this.leaves[leafIndex] = leaf;
|
|
32105
33610
|
}
|
|
32106
33611
|
} catch (error) {
|
|
32107
33612
|
throw new NetworkError(
|
|
32108
|
-
"Failed to refresh
|
|
33613
|
+
"Failed to refresh timelock",
|
|
32109
33614
|
{
|
|
32110
|
-
method: "
|
|
33615
|
+
method: "refresh_timelock"
|
|
32111
33616
|
},
|
|
32112
33617
|
error
|
|
32113
33618
|
);
|
|
@@ -32171,10 +33676,15 @@ var SparkWallet = class _SparkWallet extends import_eventemitter3.EventEmitter {
|
|
|
32171
33676
|
var utils_exports = {};
|
|
32172
33677
|
__export(utils_exports, {
|
|
32173
33678
|
DEFAULT_FEE_SATS: () => DEFAULT_FEE_SATS,
|
|
33679
|
+
DIRECT_TIMELOCK_OFFSET: () => DIRECT_TIMELOCK_OFFSET,
|
|
33680
|
+
INITIAL_DIRECT_SEQUENCE: () => INITIAL_DIRECT_SEQUENCE,
|
|
33681
|
+
INITIAL_SEQUENCE: () => INITIAL_SEQUENCE,
|
|
32174
33682
|
LRC_WALLET_NETWORK: () => LRC_WALLET_NETWORK,
|
|
32175
33683
|
LRC_WALLET_NETWORK_TYPE: () => LRC_WALLET_NETWORK_TYPE,
|
|
32176
33684
|
Network: () => Network2,
|
|
32177
33685
|
NetworkToProto: () => NetworkToProto,
|
|
33686
|
+
TEST_UNILATERAL_DIRECT_SEQUENCE: () => TEST_UNILATERAL_DIRECT_SEQUENCE,
|
|
33687
|
+
TEST_UNILATERAL_SEQUENCE: () => TEST_UNILATERAL_SEQUENCE,
|
|
32178
33688
|
addPrivateKeys: () => addPrivateKeys,
|
|
32179
33689
|
addPublicKeys: () => addPublicKeys,
|
|
32180
33690
|
applyAdaptorToSignature: () => applyAdaptorToSignature,
|
|
@@ -32188,13 +33698,21 @@ __export(utils_exports, {
|
|
|
32188
33698
|
constructFeeBumpTx: () => constructFeeBumpTx,
|
|
32189
33699
|
constructUnilateralExitFeeBumpPackages: () => constructUnilateralExitFeeBumpPackages,
|
|
32190
33700
|
constructUnilateralExitTxs: () => constructUnilateralExitTxs,
|
|
33701
|
+
createConnectorRefundTransactions: () => createConnectorRefundTransactions,
|
|
33702
|
+
createLeafNodeTx: () => createLeafNodeTx,
|
|
33703
|
+
createNodeTx: () => createNodeTx,
|
|
33704
|
+
createNodeTxs: () => createNodeTxs,
|
|
32191
33705
|
createRefundTx: () => createRefundTx,
|
|
33706
|
+
createRefundTxs: () => createRefundTxs,
|
|
33707
|
+
createRootTx: () => createRootTx,
|
|
32192
33708
|
createSigningCommitment: () => createSigningCommitment,
|
|
32193
33709
|
createSigningNonce: () => createSigningNonce,
|
|
33710
|
+
createSplitTx: () => createSplitTx,
|
|
32194
33711
|
decodeBech32mTokenIdentifier: () => decodeBech32mTokenIdentifier,
|
|
32195
33712
|
decodeBytesToSigningCommitment: () => decodeBytesToSigningCommitment,
|
|
32196
33713
|
decodeBytesToSigningNonce: () => decodeBytesToSigningNonce,
|
|
32197
33714
|
decodeSparkAddress: () => decodeSparkAddress,
|
|
33715
|
+
doesLeafNeedRefresh: () => doesLeafNeedRefresh,
|
|
32198
33716
|
encodeBech32mTokenIdentifier: () => encodeBech32mTokenIdentifier,
|
|
32199
33717
|
encodeSigningCommitmentToBytes: () => encodeSigningCommitmentToBytes,
|
|
32200
33718
|
encodeSigningNonceToBytes: () => encodeSigningNonceToBytes,
|
|
@@ -32256,16 +33774,17 @@ init_buffer();
|
|
|
32256
33774
|
|
|
32257
33775
|
// src/utils/mempool.ts
|
|
32258
33776
|
async function getLatestDepositTxId(address2) {
|
|
33777
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
32259
33778
|
const network = getNetworkFromAddress(address2);
|
|
32260
33779
|
const baseUrl = network === BitcoinNetwork_default.REGTEST ? getElectrsUrl("REGTEST") : getElectrsUrl("MAINNET");
|
|
32261
|
-
const headers =
|
|
33780
|
+
const headers = new Headers2();
|
|
32262
33781
|
if (network === BitcoinNetwork_default.REGTEST) {
|
|
32263
33782
|
const auth = btoa(
|
|
32264
33783
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
32265
33784
|
);
|
|
32266
|
-
headers
|
|
33785
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
32267
33786
|
}
|
|
32268
|
-
const response = await
|
|
33787
|
+
const response = await fetch2(`${baseUrl}/address/${address2}/txs`, {
|
|
32269
33788
|
headers
|
|
32270
33789
|
});
|
|
32271
33790
|
const addressTxs = await response.json();
|
|
@@ -32282,14 +33801,15 @@ async function getLatestDepositTxId(address2) {
|
|
|
32282
33801
|
return null;
|
|
32283
33802
|
}
|
|
32284
33803
|
async function isTxBroadcast(txid, baseUrl, network) {
|
|
32285
|
-
const
|
|
33804
|
+
const { fetch: fetch2, Headers: Headers2 } = getFetch();
|
|
33805
|
+
const headers = new Headers2();
|
|
32286
33806
|
if (network === 3 /* REGTEST */) {
|
|
32287
33807
|
const auth = btoa(
|
|
32288
33808
|
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
32289
33809
|
);
|
|
32290
|
-
headers
|
|
33810
|
+
headers.set("Authorization", `Basic ${auth}`);
|
|
32291
33811
|
}
|
|
32292
|
-
const response = await
|
|
33812
|
+
const response = await fetch2(`${baseUrl}/tx/${txid}`, {
|
|
32293
33813
|
headers
|
|
32294
33814
|
});
|
|
32295
33815
|
const tx = await response.json();
|
|
@@ -32304,7 +33824,7 @@ init_buffer();
|
|
|
32304
33824
|
var import_utils24 = require("@noble/curves/abstract/utils");
|
|
32305
33825
|
var import_legacy = require("@noble/hashes/legacy");
|
|
32306
33826
|
var import_sha212 = require("@noble/hashes/sha2");
|
|
32307
|
-
var
|
|
33827
|
+
var btc4 = __toESM(require("@scure/btc-signer"), 1);
|
|
32308
33828
|
function isEphemeralAnchorOutput(script, amount) {
|
|
32309
33829
|
return Boolean(
|
|
32310
33830
|
amount === 0n && script && // Pattern 1: Bare OP_TRUE (single byte 0x51)
|
|
@@ -32519,7 +34039,7 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
|
|
|
32519
34039
|
usedUtxos,
|
|
32520
34040
|
correctedParentTx
|
|
32521
34041
|
} = constructFeeBumpTx(nodeTxHex, availableUtxos, feeRate, void 0);
|
|
32522
|
-
const feeBumpTx =
|
|
34042
|
+
const feeBumpTx = btc4.Transaction.fromPSBT((0, import_utils24.hexToBytes)(nodeFeeBumpPsbt));
|
|
32523
34043
|
var feeBumpOut = feeBumpTx.outputsLength === 1 ? feeBumpTx.getOutput(0) : null;
|
|
32524
34044
|
var feeBumpOutPubKey = null;
|
|
32525
34045
|
for (const usedUtxo of usedUtxos) {
|
|
@@ -32573,7 +34093,7 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
|
|
|
32573
34093
|
feeRate,
|
|
32574
34094
|
void 0
|
|
32575
34095
|
);
|
|
32576
|
-
const feeBumpTx2 =
|
|
34096
|
+
const feeBumpTx2 = btc4.Transaction.fromPSBT(
|
|
32577
34097
|
(0, import_utils24.hexToBytes)(refundFeeBump.feeBumpPsbt)
|
|
32578
34098
|
);
|
|
32579
34099
|
var feeBumpOut = feeBumpTx2.outputsLength === 1 ? feeBumpTx2.getOutput(0) : null;
|
|
@@ -32677,7 +34197,7 @@ function constructFeeBumpTx(txHex, utxos, feeRate, previousFeeBumpTx) {
|
|
|
32677
34197
|
if (utxos.length === 0) {
|
|
32678
34198
|
throw new Error("No UTXOs available for fee bump");
|
|
32679
34199
|
}
|
|
32680
|
-
const builder = new
|
|
34200
|
+
const builder = new btc4.Transaction({
|
|
32681
34201
|
version: 3,
|
|
32682
34202
|
allowUnknown: true,
|
|
32683
34203
|
allowLegacyWitnessUtxo: true
|
|
@@ -32770,19 +34290,19 @@ function constructFeeBumpTx(txHex, utxos, feeRate, previousFeeBumpTx) {
|
|
|
32770
34290
|
|
|
32771
34291
|
// src/utils/xchain-address.ts
|
|
32772
34292
|
init_buffer();
|
|
32773
|
-
var
|
|
34293
|
+
var btc5 = __toESM(require("@scure/btc-signer"), 1);
|
|
32774
34294
|
var networkByType = {
|
|
32775
|
-
MAINNET:
|
|
32776
|
-
TESTNET:
|
|
34295
|
+
MAINNET: btc5.NETWORK,
|
|
34296
|
+
TESTNET: btc5.TEST_NETWORK,
|
|
32777
34297
|
REGTEST: {
|
|
32778
|
-
...
|
|
34298
|
+
...btc5.TEST_NETWORK,
|
|
32779
34299
|
bech32: "bcrt"
|
|
32780
34300
|
}
|
|
32781
34301
|
};
|
|
32782
34302
|
function getSparkAddressFromTaproot(taprootAddress) {
|
|
32783
34303
|
for (const networkType of ["MAINNET", "TESTNET", "REGTEST"]) {
|
|
32784
34304
|
try {
|
|
32785
|
-
const result =
|
|
34305
|
+
const result = btc5.Address(networkByType[networkType]).decode(taprootAddress);
|
|
32786
34306
|
if (result.type === "tr") {
|
|
32787
34307
|
const outputPublicKey = result.pubkey;
|
|
32788
34308
|
return encodeSparkAddress({
|