@buildonspark/spark-sdk 0.3.8 → 0.4.0
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 +18 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/uniffi/uniffi/spark_frost/spark_frost.kt +1361 -1367
- package/android/src/main/jniLibs/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86_64/libuniffi_spark_frost.so +0 -0
- package/dist/bare/index.cjs +1342 -1346
- package/dist/bare/index.d.cts +114 -68
- package/dist/bare/index.d.ts +114 -68
- package/dist/bare/index.js +1266 -1279
- package/dist/{chunk-FXIESWE6.js → chunk-27ILUWDJ.js} +1 -1
- package/dist/{chunk-5ASXVNTM.js → chunk-4YFT7DAE.js} +1 -1
- package/dist/{chunk-FP2CRVQH.js → chunk-G3LHXHF3.js} +1045 -1308
- package/dist/{chunk-XI6FCNYG.js → chunk-JLF6WJ7K.js} +1 -1
- package/dist/{chunk-3LPEQGVJ.js → chunk-LOXWCMZL.js} +1 -1
- package/dist/{chunk-5HU5W56H.js → chunk-WICAF6BS.js} +2 -2
- package/dist/{chunk-VFN34EOX.js → chunk-YEBEN7XD.js} +258 -0
- package/dist/{client-pNpGP15j.d.cts → client-BIqiUNy4.d.cts} +1 -1
- package/dist/{client-By-N7oJS.d.ts → client-BaQf-5gD.d.ts} +1 -1
- package/dist/debug.cjs +1330 -1336
- package/dist/debug.d.cts +20 -16
- package/dist/debug.d.ts +20 -16
- package/dist/debug.js +5 -5
- package/dist/graphql/objects/index.d.cts +3 -3
- package/dist/graphql/objects/index.d.ts +3 -3
- package/dist/index.cjs +1363 -1365
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +32 -24
- package/dist/index.node.cjs +1363 -1365
- package/dist/index.node.d.cts +7 -7
- package/dist/index.node.d.ts +7 -7
- package/dist/index.node.js +31 -23
- package/dist/{logging-DMFVY384.d.ts → logging-BNGm6dBp.d.ts} +42 -37
- package/dist/{logging-DxLp34Xm.d.cts → logging-D3IfXfHG.d.cts} +42 -37
- package/dist/native/index.react-native.cjs +1505 -1366
- package/dist/native/index.react-native.d.cts +112 -58
- package/dist/native/index.react-native.d.ts +112 -58
- package/dist/native/index.react-native.js +1415 -1289
- package/dist/proto/spark.cjs +258 -0
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +5 -1
- package/dist/proto/spark_token.d.cts +1 -1
- package/dist/proto/spark_token.d.ts +1 -1
- package/dist/proto/spark_token.js +2 -2
- package/dist/{spark-By6yHsrk.d.cts → spark-DOpheE8_.d.cts} +39 -2
- package/dist/{spark-By6yHsrk.d.ts → spark-DOpheE8_.d.ts} +39 -2
- package/dist/{spark-wallet.browser-C1dQknVj.d.ts → spark-wallet.browser-B2rGwjuM.d.ts} +2 -2
- package/dist/{spark-wallet.browser-CNMo3IvO.d.cts → spark-wallet.browser-Ck9No4Ks.d.cts} +2 -2
- package/dist/{spark-wallet.node-Og6__NMh.d.ts → spark-wallet.node-BqmKsGPs.d.ts} +2 -2
- package/dist/{spark-wallet.node-BZJhJZKq.d.cts → spark-wallet.node-C2TIkyt4.d.cts} +2 -2
- package/dist/tests/test-utils.cjs +1304 -1236
- package/dist/tests/test-utils.d.cts +18 -4
- package/dist/tests/test-utils.d.ts +18 -4
- package/dist/tests/test-utils.js +7 -7
- package/dist/{token-transactions-CLR3rnYi.d.cts → token-transactions-Db8mkjnU.d.cts} +2 -2
- package/dist/{token-transactions-C7yefB2S.d.ts → token-transactions-DoMcrxXQ.d.ts} +2 -2
- package/dist/types/index.cjs +256 -0
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -2
- package/dist/{wallet-config-BoyMVa6n.d.ts → wallet-config-Bg3kWltL.d.ts} +42 -35
- package/dist/{wallet-config-xom-9UFF.d.cts → wallet-config-CuZKNo9S.d.cts} +42 -35
- package/ios/spark_frostFFI.xcframework/ios-arm64/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/macos-arm64_x86_64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/package.json +1 -1
- package/src/index.react-native.ts +8 -2
- package/src/proto/spark.ts +348 -4
- package/src/services/config.ts +5 -0
- package/src/services/coop-exit.ts +26 -107
- package/src/services/deposit.ts +12 -48
- package/src/services/signing.ts +62 -49
- package/src/services/transfer.ts +437 -722
- package/src/services/wallet-config.ts +10 -0
- package/src/services/xhr-transport.ts +13 -3
- package/src/signer/signer.react-native.ts +73 -1
- package/src/spark-wallet/proto-descriptors.ts +1 -1
- package/src/spark-wallet/spark-wallet.ts +162 -315
- package/src/spark-wallet/types.ts +2 -2
- package/src/spark_descriptors.pb +0 -0
- package/src/tests/integration/lightning.test.ts +1 -27
- package/src/tests/integration/static_deposit.test.ts +6 -9
- package/src/tests/integration/unilateral-exit.test.ts +117 -0
- package/src/tests/optimize.test.ts +31 -1
- package/src/tests/utils/signing.ts +33 -0
- package/src/tests/utils/test-faucet.ts +61 -0
- package/src/utils/optimize.ts +42 -0
- package/src/utils/transaction.ts +250 -249
- package/src/utils/unilateral-exit.ts +1 -40
package/dist/bare/index.cjs
CHANGED
|
@@ -1228,7 +1228,6 @@ __export(index_exports, {
|
|
|
1228
1228
|
DIRECT_TIMELOCK_OFFSET: () => DIRECT_TIMELOCK_OFFSET,
|
|
1229
1229
|
DefaultSparkSigner: () => DefaultSparkSigner,
|
|
1230
1230
|
HTLC_TIMELOCK_OFFSET: () => HTLC_TIMELOCK_OFFSET,
|
|
1231
|
-
INITIAL_DIRECT_SEQUENCE: () => INITIAL_DIRECT_SEQUENCE,
|
|
1232
1231
|
INITIAL_SEQUENCE: () => INITIAL_SEQUENCE,
|
|
1233
1232
|
InternalValidationError: () => InternalValidationError,
|
|
1234
1233
|
LOGGER_NAMES: () => LOGGER_NAMES,
|
|
@@ -1261,21 +1260,24 @@ __export(index_exports, {
|
|
|
1261
1260
|
constructFeeBumpTx: () => constructFeeBumpTx,
|
|
1262
1261
|
constructUnilateralExitFeeBumpPackages: () => constructUnilateralExitFeeBumpPackages,
|
|
1263
1262
|
constructUnilateralExitTxs: () => constructUnilateralExitTxs,
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1263
|
+
createConnectorRefundTxs: () => createConnectorRefundTxs,
|
|
1264
|
+
createCurrentTimelockRefundTxs: () => createCurrentTimelockRefundTxs,
|
|
1265
|
+
createDecrementedTimelockNodeTx: () => createDecrementedTimelockNodeTx,
|
|
1266
|
+
createDecrementedTimelockRefundTxs: () => createDecrementedTimelockRefundTxs,
|
|
1267
|
+
createInitialTimelockNodeTx: () => createInitialTimelockNodeTx,
|
|
1268
|
+
createInitialTimelockRefundTxs: () => createInitialTimelockRefundTxs,
|
|
1269
|
+
createRootNodeTx: () => createRootNodeTx,
|
|
1271
1270
|
createSigningCommitment: () => createSigningCommitment,
|
|
1272
1271
|
createSigningNonce: () => createSigningNonce,
|
|
1273
|
-
|
|
1272
|
+
createTestUnilateralRefundTxs: () => createTestUnilateralRefundTxs,
|
|
1273
|
+
createTestUnilateralTimelockNodeTx: () => createTestUnilateralTimelockNodeTx,
|
|
1274
|
+
createZeroTimelockNodeTx: () => createZeroTimelockNodeTx,
|
|
1274
1275
|
decodeBech32mTokenIdentifier: () => decodeBech32mTokenIdentifier,
|
|
1275
1276
|
decodeBytesToSigningCommitment: () => decodeBytesToSigningCommitment,
|
|
1276
1277
|
decodeBytesToSigningNonce: () => decodeBytesToSigningNonce,
|
|
1277
1278
|
decodeSparkAddress: () => decodeSparkAddress,
|
|
1278
1279
|
doesLeafNeedRefresh: () => doesLeafNeedRefresh,
|
|
1280
|
+
doesTxnNeedRenewed: () => doesTxnNeedRenewed,
|
|
1279
1281
|
encodeBech32mTokenIdentifier: () => encodeBech32mTokenIdentifier,
|
|
1280
1282
|
encodeSigningCommitmentToBytes: () => encodeSigningCommitmentToBytes,
|
|
1281
1283
|
encodeSigningNonceToBytes: () => encodeSigningNonceToBytes,
|
|
@@ -1313,12 +1315,14 @@ __export(index_exports, {
|
|
|
1313
1315
|
getTxFromRawTxHex: () => getTxFromRawTxHex,
|
|
1314
1316
|
getTxId: () => getTxId,
|
|
1315
1317
|
getTxIdNoReverse: () => getTxIdNoReverse,
|
|
1318
|
+
hash160: () => hash160,
|
|
1316
1319
|
isEphemeralAnchorOutput: () => isEphemeralAnchorOutput,
|
|
1317
1320
|
isLegacySparkAddress: () => isLegacySparkAddress,
|
|
1318
1321
|
isSafeForNumber: () => isSafeForNumber,
|
|
1319
1322
|
isTxBroadcast: () => isTxBroadcast,
|
|
1320
1323
|
isValidPublicKey: () => isValidPublicKey,
|
|
1321
1324
|
isValidSparkAddress: () => isValidSparkAddress,
|
|
1325
|
+
isZeroTimelock: () => isZeroTimelock,
|
|
1322
1326
|
lastKeyWithTarget: () => lastKeyWithTarget,
|
|
1323
1327
|
maybeApplyFee: () => maybeApplyFee,
|
|
1324
1328
|
modInverse: () => modInverse,
|
|
@@ -1502,7 +1506,7 @@ var import_secp256k114 = require("@noble/curves/secp256k1");
|
|
|
1502
1506
|
var import_utils24 = require("@noble/curves/utils");
|
|
1503
1507
|
var import_bip392 = require("@scure/bip39");
|
|
1504
1508
|
var import_english2 = require("@scure/bip39/wordlists/english");
|
|
1505
|
-
var
|
|
1509
|
+
var import_btc_signer5 = require("@scure/btc-signer");
|
|
1506
1510
|
var import_async_mutex = require("async-mutex");
|
|
1507
1511
|
var import_uuidv75 = require("uuidv7");
|
|
1508
1512
|
|
|
@@ -5949,6 +5953,12 @@ var RenewLeafRequest = {
|
|
|
5949
5953
|
writer.uint32(26).fork()
|
|
5950
5954
|
).join();
|
|
5951
5955
|
break;
|
|
5956
|
+
case "renewNodeZeroTimelockSigningJob":
|
|
5957
|
+
RenewNodeZeroTimelockSigningJob.encode(
|
|
5958
|
+
message.signingJobs.renewNodeZeroTimelockSigningJob,
|
|
5959
|
+
writer.uint32(34).fork()
|
|
5960
|
+
).join();
|
|
5961
|
+
break;
|
|
5952
5962
|
}
|
|
5953
5963
|
return writer;
|
|
5954
5964
|
},
|
|
@@ -5986,6 +5996,16 @@ var RenewLeafRequest = {
|
|
|
5986
5996
|
};
|
|
5987
5997
|
continue;
|
|
5988
5998
|
}
|
|
5999
|
+
case 4: {
|
|
6000
|
+
if (tag !== 34) {
|
|
6001
|
+
break;
|
|
6002
|
+
}
|
|
6003
|
+
message.signingJobs = {
|
|
6004
|
+
$case: "renewNodeZeroTimelockSigningJob",
|
|
6005
|
+
renewNodeZeroTimelockSigningJob: RenewNodeZeroTimelockSigningJob.decode(reader, reader.uint32())
|
|
6006
|
+
};
|
|
6007
|
+
continue;
|
|
6008
|
+
}
|
|
5989
6009
|
}
|
|
5990
6010
|
if ((tag & 7) === 4 || tag === 0) {
|
|
5991
6011
|
break;
|
|
@@ -6003,6 +6023,11 @@ var RenewLeafRequest = {
|
|
|
6003
6023
|
} : isSet3(object.renewRefundTimelockSigningJob) ? {
|
|
6004
6024
|
$case: "renewRefundTimelockSigningJob",
|
|
6005
6025
|
renewRefundTimelockSigningJob: RenewRefundTimelockSigningJob.fromJSON(object.renewRefundTimelockSigningJob)
|
|
6026
|
+
} : isSet3(object.renewNodeZeroTimelockSigningJob) ? {
|
|
6027
|
+
$case: "renewNodeZeroTimelockSigningJob",
|
|
6028
|
+
renewNodeZeroTimelockSigningJob: RenewNodeZeroTimelockSigningJob.fromJSON(
|
|
6029
|
+
object.renewNodeZeroTimelockSigningJob
|
|
6030
|
+
)
|
|
6006
6031
|
} : void 0
|
|
6007
6032
|
};
|
|
6008
6033
|
},
|
|
@@ -6019,6 +6044,10 @@ var RenewLeafRequest = {
|
|
|
6019
6044
|
obj.renewRefundTimelockSigningJob = RenewRefundTimelockSigningJob.toJSON(
|
|
6020
6045
|
message.signingJobs.renewRefundTimelockSigningJob
|
|
6021
6046
|
);
|
|
6047
|
+
} else if (message.signingJobs?.$case === "renewNodeZeroTimelockSigningJob") {
|
|
6048
|
+
obj.renewNodeZeroTimelockSigningJob = RenewNodeZeroTimelockSigningJob.toJSON(
|
|
6049
|
+
message.signingJobs.renewNodeZeroTimelockSigningJob
|
|
6050
|
+
);
|
|
6022
6051
|
}
|
|
6023
6052
|
return obj;
|
|
6024
6053
|
},
|
|
@@ -6051,6 +6080,17 @@ var RenewLeafRequest = {
|
|
|
6051
6080
|
}
|
|
6052
6081
|
break;
|
|
6053
6082
|
}
|
|
6083
|
+
case "renewNodeZeroTimelockSigningJob": {
|
|
6084
|
+
if (object.signingJobs?.renewNodeZeroTimelockSigningJob !== void 0 && object.signingJobs?.renewNodeZeroTimelockSigningJob !== null) {
|
|
6085
|
+
message.signingJobs = {
|
|
6086
|
+
$case: "renewNodeZeroTimelockSigningJob",
|
|
6087
|
+
renewNodeZeroTimelockSigningJob: RenewNodeZeroTimelockSigningJob.fromPartial(
|
|
6088
|
+
object.signingJobs.renewNodeZeroTimelockSigningJob
|
|
6089
|
+
)
|
|
6090
|
+
};
|
|
6091
|
+
}
|
|
6092
|
+
break;
|
|
6093
|
+
}
|
|
6054
6094
|
}
|
|
6055
6095
|
return message;
|
|
6056
6096
|
}
|
|
@@ -6325,6 +6365,125 @@ var RenewRefundTimelockSigningJob = {
|
|
|
6325
6365
|
return message;
|
|
6326
6366
|
}
|
|
6327
6367
|
};
|
|
6368
|
+
function createBaseRenewNodeZeroTimelockSigningJob() {
|
|
6369
|
+
return {
|
|
6370
|
+
nodeTxSigningJob: void 0,
|
|
6371
|
+
refundTxSigningJob: void 0,
|
|
6372
|
+
directNodeTxSigningJob: void 0,
|
|
6373
|
+
directRefundTxSigningJob: void 0,
|
|
6374
|
+
directFromCpfpRefundTxSigningJob: void 0
|
|
6375
|
+
};
|
|
6376
|
+
}
|
|
6377
|
+
var RenewNodeZeroTimelockSigningJob = {
|
|
6378
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
6379
|
+
if (message.nodeTxSigningJob !== void 0) {
|
|
6380
|
+
UserSignedTxSigningJob.encode(message.nodeTxSigningJob, writer.uint32(10).fork()).join();
|
|
6381
|
+
}
|
|
6382
|
+
if (message.refundTxSigningJob !== void 0) {
|
|
6383
|
+
UserSignedTxSigningJob.encode(message.refundTxSigningJob, writer.uint32(18).fork()).join();
|
|
6384
|
+
}
|
|
6385
|
+
if (message.directNodeTxSigningJob !== void 0) {
|
|
6386
|
+
UserSignedTxSigningJob.encode(message.directNodeTxSigningJob, writer.uint32(26).fork()).join();
|
|
6387
|
+
}
|
|
6388
|
+
if (message.directRefundTxSigningJob !== void 0) {
|
|
6389
|
+
UserSignedTxSigningJob.encode(message.directRefundTxSigningJob, writer.uint32(34).fork()).join();
|
|
6390
|
+
}
|
|
6391
|
+
if (message.directFromCpfpRefundTxSigningJob !== void 0) {
|
|
6392
|
+
UserSignedTxSigningJob.encode(message.directFromCpfpRefundTxSigningJob, writer.uint32(42).fork()).join();
|
|
6393
|
+
}
|
|
6394
|
+
return writer;
|
|
6395
|
+
},
|
|
6396
|
+
decode(input, length) {
|
|
6397
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
6398
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
6399
|
+
const message = createBaseRenewNodeZeroTimelockSigningJob();
|
|
6400
|
+
while (reader.pos < end) {
|
|
6401
|
+
const tag = reader.uint32();
|
|
6402
|
+
switch (tag >>> 3) {
|
|
6403
|
+
case 1: {
|
|
6404
|
+
if (tag !== 10) {
|
|
6405
|
+
break;
|
|
6406
|
+
}
|
|
6407
|
+
message.nodeTxSigningJob = UserSignedTxSigningJob.decode(reader, reader.uint32());
|
|
6408
|
+
continue;
|
|
6409
|
+
}
|
|
6410
|
+
case 2: {
|
|
6411
|
+
if (tag !== 18) {
|
|
6412
|
+
break;
|
|
6413
|
+
}
|
|
6414
|
+
message.refundTxSigningJob = UserSignedTxSigningJob.decode(reader, reader.uint32());
|
|
6415
|
+
continue;
|
|
6416
|
+
}
|
|
6417
|
+
case 3: {
|
|
6418
|
+
if (tag !== 26) {
|
|
6419
|
+
break;
|
|
6420
|
+
}
|
|
6421
|
+
message.directNodeTxSigningJob = UserSignedTxSigningJob.decode(reader, reader.uint32());
|
|
6422
|
+
continue;
|
|
6423
|
+
}
|
|
6424
|
+
case 4: {
|
|
6425
|
+
if (tag !== 34) {
|
|
6426
|
+
break;
|
|
6427
|
+
}
|
|
6428
|
+
message.directRefundTxSigningJob = UserSignedTxSigningJob.decode(reader, reader.uint32());
|
|
6429
|
+
continue;
|
|
6430
|
+
}
|
|
6431
|
+
case 5: {
|
|
6432
|
+
if (tag !== 42) {
|
|
6433
|
+
break;
|
|
6434
|
+
}
|
|
6435
|
+
message.directFromCpfpRefundTxSigningJob = UserSignedTxSigningJob.decode(reader, reader.uint32());
|
|
6436
|
+
continue;
|
|
6437
|
+
}
|
|
6438
|
+
}
|
|
6439
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
6440
|
+
break;
|
|
6441
|
+
}
|
|
6442
|
+
reader.skip(tag & 7);
|
|
6443
|
+
}
|
|
6444
|
+
return message;
|
|
6445
|
+
},
|
|
6446
|
+
fromJSON(object) {
|
|
6447
|
+
return {
|
|
6448
|
+
nodeTxSigningJob: isSet3(object.nodeTxSigningJob) ? UserSignedTxSigningJob.fromJSON(object.nodeTxSigningJob) : void 0,
|
|
6449
|
+
refundTxSigningJob: isSet3(object.refundTxSigningJob) ? UserSignedTxSigningJob.fromJSON(object.refundTxSigningJob) : void 0,
|
|
6450
|
+
directNodeTxSigningJob: isSet3(object.directNodeTxSigningJob) ? UserSignedTxSigningJob.fromJSON(object.directNodeTxSigningJob) : void 0,
|
|
6451
|
+
directRefundTxSigningJob: isSet3(object.directRefundTxSigningJob) ? UserSignedTxSigningJob.fromJSON(object.directRefundTxSigningJob) : void 0,
|
|
6452
|
+
directFromCpfpRefundTxSigningJob: isSet3(object.directFromCpfpRefundTxSigningJob) ? UserSignedTxSigningJob.fromJSON(object.directFromCpfpRefundTxSigningJob) : void 0
|
|
6453
|
+
};
|
|
6454
|
+
},
|
|
6455
|
+
toJSON(message) {
|
|
6456
|
+
const obj = {};
|
|
6457
|
+
if (message.nodeTxSigningJob !== void 0) {
|
|
6458
|
+
obj.nodeTxSigningJob = UserSignedTxSigningJob.toJSON(message.nodeTxSigningJob);
|
|
6459
|
+
}
|
|
6460
|
+
if (message.refundTxSigningJob !== void 0) {
|
|
6461
|
+
obj.refundTxSigningJob = UserSignedTxSigningJob.toJSON(message.refundTxSigningJob);
|
|
6462
|
+
}
|
|
6463
|
+
if (message.directNodeTxSigningJob !== void 0) {
|
|
6464
|
+
obj.directNodeTxSigningJob = UserSignedTxSigningJob.toJSON(message.directNodeTxSigningJob);
|
|
6465
|
+
}
|
|
6466
|
+
if (message.directRefundTxSigningJob !== void 0) {
|
|
6467
|
+
obj.directRefundTxSigningJob = UserSignedTxSigningJob.toJSON(message.directRefundTxSigningJob);
|
|
6468
|
+
}
|
|
6469
|
+
if (message.directFromCpfpRefundTxSigningJob !== void 0) {
|
|
6470
|
+
obj.directFromCpfpRefundTxSigningJob = UserSignedTxSigningJob.toJSON(message.directFromCpfpRefundTxSigningJob);
|
|
6471
|
+
}
|
|
6472
|
+
return obj;
|
|
6473
|
+
},
|
|
6474
|
+
create(base) {
|
|
6475
|
+
return RenewNodeZeroTimelockSigningJob.fromPartial(base ?? {});
|
|
6476
|
+
},
|
|
6477
|
+
fromPartial(object) {
|
|
6478
|
+
const message = createBaseRenewNodeZeroTimelockSigningJob();
|
|
6479
|
+
message.nodeTxSigningJob = object.nodeTxSigningJob !== void 0 && object.nodeTxSigningJob !== null ? UserSignedTxSigningJob.fromPartial(object.nodeTxSigningJob) : void 0;
|
|
6480
|
+
message.refundTxSigningJob = object.refundTxSigningJob !== void 0 && object.refundTxSigningJob !== null ? UserSignedTxSigningJob.fromPartial(object.refundTxSigningJob) : void 0;
|
|
6481
|
+
message.directNodeTxSigningJob = object.directNodeTxSigningJob !== void 0 && object.directNodeTxSigningJob !== null ? UserSignedTxSigningJob.fromPartial(object.directNodeTxSigningJob) : void 0;
|
|
6482
|
+
message.directRefundTxSigningJob = object.directRefundTxSigningJob !== void 0 && object.directRefundTxSigningJob !== null ? UserSignedTxSigningJob.fromPartial(object.directRefundTxSigningJob) : void 0;
|
|
6483
|
+
message.directFromCpfpRefundTxSigningJob = object.directFromCpfpRefundTxSigningJob !== void 0 && object.directFromCpfpRefundTxSigningJob !== null ? UserSignedTxSigningJob.fromPartial(object.directFromCpfpRefundTxSigningJob) : void 0;
|
|
6484
|
+
return message;
|
|
6485
|
+
}
|
|
6486
|
+
};
|
|
6328
6487
|
function createBaseRenewLeafResponse() {
|
|
6329
6488
|
return { renewResult: void 0 };
|
|
6330
6489
|
}
|
|
@@ -6337,6 +6496,9 @@ var RenewLeafResponse = {
|
|
|
6337
6496
|
case "renewRefundTimelockResult":
|
|
6338
6497
|
RenewRefundTimelockResult.encode(message.renewResult.renewRefundTimelockResult, writer.uint32(18).fork()).join();
|
|
6339
6498
|
break;
|
|
6499
|
+
case "renewNodeZeroTimelockResult":
|
|
6500
|
+
RenewNodeZeroTimelockResult.encode(message.renewResult.renewNodeZeroTimelockResult, writer.uint32(26).fork()).join();
|
|
6501
|
+
break;
|
|
6340
6502
|
}
|
|
6341
6503
|
return writer;
|
|
6342
6504
|
},
|
|
@@ -6367,6 +6529,16 @@ var RenewLeafResponse = {
|
|
|
6367
6529
|
};
|
|
6368
6530
|
continue;
|
|
6369
6531
|
}
|
|
6532
|
+
case 3: {
|
|
6533
|
+
if (tag !== 26) {
|
|
6534
|
+
break;
|
|
6535
|
+
}
|
|
6536
|
+
message.renewResult = {
|
|
6537
|
+
$case: "renewNodeZeroTimelockResult",
|
|
6538
|
+
renewNodeZeroTimelockResult: RenewNodeZeroTimelockResult.decode(reader, reader.uint32())
|
|
6539
|
+
};
|
|
6540
|
+
continue;
|
|
6541
|
+
}
|
|
6370
6542
|
}
|
|
6371
6543
|
if ((tag & 7) === 4 || tag === 0) {
|
|
6372
6544
|
break;
|
|
@@ -6383,6 +6555,9 @@ var RenewLeafResponse = {
|
|
|
6383
6555
|
} : isSet3(object.renewRefundTimelockResult) ? {
|
|
6384
6556
|
$case: "renewRefundTimelockResult",
|
|
6385
6557
|
renewRefundTimelockResult: RenewRefundTimelockResult.fromJSON(object.renewRefundTimelockResult)
|
|
6558
|
+
} : isSet3(object.renewNodeZeroTimelockResult) ? {
|
|
6559
|
+
$case: "renewNodeZeroTimelockResult",
|
|
6560
|
+
renewNodeZeroTimelockResult: RenewNodeZeroTimelockResult.fromJSON(object.renewNodeZeroTimelockResult)
|
|
6386
6561
|
} : void 0
|
|
6387
6562
|
};
|
|
6388
6563
|
},
|
|
@@ -6392,6 +6567,10 @@ var RenewLeafResponse = {
|
|
|
6392
6567
|
obj.renewNodeTimelockResult = RenewNodeTimelockResult.toJSON(message.renewResult.renewNodeTimelockResult);
|
|
6393
6568
|
} else if (message.renewResult?.$case === "renewRefundTimelockResult") {
|
|
6394
6569
|
obj.renewRefundTimelockResult = RenewRefundTimelockResult.toJSON(message.renewResult.renewRefundTimelockResult);
|
|
6570
|
+
} else if (message.renewResult?.$case === "renewNodeZeroTimelockResult") {
|
|
6571
|
+
obj.renewNodeZeroTimelockResult = RenewNodeZeroTimelockResult.toJSON(
|
|
6572
|
+
message.renewResult.renewNodeZeroTimelockResult
|
|
6573
|
+
);
|
|
6395
6574
|
}
|
|
6396
6575
|
return obj;
|
|
6397
6576
|
},
|
|
@@ -6421,6 +6600,17 @@ var RenewLeafResponse = {
|
|
|
6421
6600
|
}
|
|
6422
6601
|
break;
|
|
6423
6602
|
}
|
|
6603
|
+
case "renewNodeZeroTimelockResult": {
|
|
6604
|
+
if (object.renewResult?.renewNodeZeroTimelockResult !== void 0 && object.renewResult?.renewNodeZeroTimelockResult !== null) {
|
|
6605
|
+
message.renewResult = {
|
|
6606
|
+
$case: "renewNodeZeroTimelockResult",
|
|
6607
|
+
renewNodeZeroTimelockResult: RenewNodeZeroTimelockResult.fromPartial(
|
|
6608
|
+
object.renewResult.renewNodeZeroTimelockResult
|
|
6609
|
+
)
|
|
6610
|
+
};
|
|
6611
|
+
}
|
|
6612
|
+
break;
|
|
6613
|
+
}
|
|
6424
6614
|
}
|
|
6425
6615
|
return message;
|
|
6426
6616
|
}
|
|
@@ -6544,6 +6734,74 @@ var RenewRefundTimelockResult = {
|
|
|
6544
6734
|
return message;
|
|
6545
6735
|
}
|
|
6546
6736
|
};
|
|
6737
|
+
function createBaseRenewNodeZeroTimelockResult() {
|
|
6738
|
+
return { splitNode: void 0, node: void 0 };
|
|
6739
|
+
}
|
|
6740
|
+
var RenewNodeZeroTimelockResult = {
|
|
6741
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
6742
|
+
if (message.splitNode !== void 0) {
|
|
6743
|
+
TreeNode.encode(message.splitNode, writer.uint32(10).fork()).join();
|
|
6744
|
+
}
|
|
6745
|
+
if (message.node !== void 0) {
|
|
6746
|
+
TreeNode.encode(message.node, writer.uint32(18).fork()).join();
|
|
6747
|
+
}
|
|
6748
|
+
return writer;
|
|
6749
|
+
},
|
|
6750
|
+
decode(input, length) {
|
|
6751
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
6752
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
6753
|
+
const message = createBaseRenewNodeZeroTimelockResult();
|
|
6754
|
+
while (reader.pos < end) {
|
|
6755
|
+
const tag = reader.uint32();
|
|
6756
|
+
switch (tag >>> 3) {
|
|
6757
|
+
case 1: {
|
|
6758
|
+
if (tag !== 10) {
|
|
6759
|
+
break;
|
|
6760
|
+
}
|
|
6761
|
+
message.splitNode = TreeNode.decode(reader, reader.uint32());
|
|
6762
|
+
continue;
|
|
6763
|
+
}
|
|
6764
|
+
case 2: {
|
|
6765
|
+
if (tag !== 18) {
|
|
6766
|
+
break;
|
|
6767
|
+
}
|
|
6768
|
+
message.node = TreeNode.decode(reader, reader.uint32());
|
|
6769
|
+
continue;
|
|
6770
|
+
}
|
|
6771
|
+
}
|
|
6772
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
6773
|
+
break;
|
|
6774
|
+
}
|
|
6775
|
+
reader.skip(tag & 7);
|
|
6776
|
+
}
|
|
6777
|
+
return message;
|
|
6778
|
+
},
|
|
6779
|
+
fromJSON(object) {
|
|
6780
|
+
return {
|
|
6781
|
+
splitNode: isSet3(object.splitNode) ? TreeNode.fromJSON(object.splitNode) : void 0,
|
|
6782
|
+
node: isSet3(object.node) ? TreeNode.fromJSON(object.node) : void 0
|
|
6783
|
+
};
|
|
6784
|
+
},
|
|
6785
|
+
toJSON(message) {
|
|
6786
|
+
const obj = {};
|
|
6787
|
+
if (message.splitNode !== void 0) {
|
|
6788
|
+
obj.splitNode = TreeNode.toJSON(message.splitNode);
|
|
6789
|
+
}
|
|
6790
|
+
if (message.node !== void 0) {
|
|
6791
|
+
obj.node = TreeNode.toJSON(message.node);
|
|
6792
|
+
}
|
|
6793
|
+
return obj;
|
|
6794
|
+
},
|
|
6795
|
+
create(base) {
|
|
6796
|
+
return RenewNodeZeroTimelockResult.fromPartial(base ?? {});
|
|
6797
|
+
},
|
|
6798
|
+
fromPartial(object) {
|
|
6799
|
+
const message = createBaseRenewNodeZeroTimelockResult();
|
|
6800
|
+
message.splitNode = object.splitNode !== void 0 && object.splitNode !== null ? TreeNode.fromPartial(object.splitNode) : void 0;
|
|
6801
|
+
message.node = object.node !== void 0 && object.node !== null ? TreeNode.fromPartial(object.node) : void 0;
|
|
6802
|
+
return message;
|
|
6803
|
+
}
|
|
6804
|
+
};
|
|
6547
6805
|
function createBaseNodeSignatureShares() {
|
|
6548
6806
|
return {
|
|
6549
6807
|
nodeId: "",
|
|
@@ -19298,7 +19556,11 @@ var BASE_CONFIG = {
|
|
|
19298
19556
|
console: {
|
|
19299
19557
|
otel: false
|
|
19300
19558
|
},
|
|
19301
|
-
events: {}
|
|
19559
|
+
events: {},
|
|
19560
|
+
optimizationOptions: {
|
|
19561
|
+
auto: true,
|
|
19562
|
+
multiplicity: 0
|
|
19563
|
+
}
|
|
19302
19564
|
};
|
|
19303
19565
|
var LOCAL_WALLET_CONFIG = {
|
|
19304
19566
|
...BASE_CONFIG,
|
|
@@ -19509,10 +19771,12 @@ var WalletConfigService = class {
|
|
|
19509
19771
|
getEvents() {
|
|
19510
19772
|
return this.config.events;
|
|
19511
19773
|
}
|
|
19774
|
+
getOptimizationOptions() {
|
|
19775
|
+
return this.config.optimizationOptions;
|
|
19776
|
+
}
|
|
19512
19777
|
};
|
|
19513
19778
|
|
|
19514
19779
|
// src/services/coop-exit.ts
|
|
19515
|
-
var import_btc_signer3 = require("@scure/btc-signer");
|
|
19516
19780
|
var import_uuidv72 = require("uuidv7");
|
|
19517
19781
|
|
|
19518
19782
|
// src/utils/bitcoin.ts
|
|
@@ -19667,6 +19931,7 @@ function getTxEstimatedVbytesSizeByNumberOfInputsOutputs(numInputs, numOutputs)
|
|
|
19667
19931
|
}
|
|
19668
19932
|
|
|
19669
19933
|
// src/utils/transaction.ts
|
|
19934
|
+
var import_utils3 = require("@noble/hashes/utils");
|
|
19670
19935
|
var import_btc_signer = require("@scure/btc-signer");
|
|
19671
19936
|
var INITIAL_TIMELOCK = 2e3;
|
|
19672
19937
|
var TEST_UNILATERAL_TIMELOCK = 100;
|
|
@@ -19675,9 +19940,9 @@ var DIRECT_TIMELOCK_OFFSET = 50;
|
|
|
19675
19940
|
var HTLC_TIMELOCK_OFFSET = 70;
|
|
19676
19941
|
var DIRECT_HTLC_TIMELOCK_OFFSET = 85;
|
|
19677
19942
|
var INITIAL_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK;
|
|
19678
|
-
var INITIAL_DIRECT_SEQUENCE = 1 << 30 | INITIAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
19679
19943
|
var TEST_UNILATERAL_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK;
|
|
19680
19944
|
var TEST_UNILATERAL_DIRECT_SEQUENCE = 1 << 30 | TEST_UNILATERAL_TIMELOCK + DIRECT_TIMELOCK_OFFSET;
|
|
19945
|
+
var INITIAL_ROOT_NODE_SEQUENCE = 1 << 30 | 0;
|
|
19681
19946
|
var ESTIMATED_TX_SIZE = 191;
|
|
19682
19947
|
var DEFAULT_SATS_PER_VBYTE = 5;
|
|
19683
19948
|
var DEFAULT_FEE_SATS = ESTIMATED_TX_SIZE * DEFAULT_SATS_PER_VBYTE;
|
|
@@ -19687,63 +19952,8 @@ function maybeApplyFee(amount) {
|
|
|
19687
19952
|
}
|
|
19688
19953
|
return amount;
|
|
19689
19954
|
}
|
|
19690
|
-
function createRootTx(depositOutPoint, depositTxOut) {
|
|
19691
|
-
const cpfpRootTx = new import_btc_signer.Transaction({
|
|
19692
|
-
version: 3,
|
|
19693
|
-
allowUnknownOutputs: true
|
|
19694
|
-
});
|
|
19695
|
-
cpfpRootTx.addInput(depositOutPoint);
|
|
19696
|
-
cpfpRootTx.addOutput(depositTxOut);
|
|
19697
|
-
cpfpRootTx.addOutput(getEphemeralAnchorOutput());
|
|
19698
|
-
const directRootTx = new import_btc_signer.Transaction({
|
|
19699
|
-
version: 3,
|
|
19700
|
-
allowUnknownOutputs: true
|
|
19701
|
-
});
|
|
19702
|
-
directRootTx.addInput(depositOutPoint);
|
|
19703
|
-
directRootTx.addOutput({
|
|
19704
|
-
script: depositTxOut.script,
|
|
19705
|
-
amount: maybeApplyFee(depositTxOut.amount ?? 0n)
|
|
19706
|
-
});
|
|
19707
|
-
return [cpfpRootTx, directRootTx];
|
|
19708
|
-
}
|
|
19709
|
-
function createSplitTx(parentOutPoint, childTxOuts) {
|
|
19710
|
-
const cpfpSplitTx = new import_btc_signer.Transaction({
|
|
19711
|
-
version: 3,
|
|
19712
|
-
allowUnknownOutputs: true
|
|
19713
|
-
});
|
|
19714
|
-
cpfpSplitTx.addInput(parentOutPoint);
|
|
19715
|
-
for (const txOut of childTxOuts) {
|
|
19716
|
-
cpfpSplitTx.addOutput(txOut);
|
|
19717
|
-
}
|
|
19718
|
-
cpfpSplitTx.addOutput(getEphemeralAnchorOutput());
|
|
19719
|
-
const directSplitTx = new import_btc_signer.Transaction({
|
|
19720
|
-
version: 3,
|
|
19721
|
-
allowUnknownOutputs: true
|
|
19722
|
-
});
|
|
19723
|
-
directSplitTx.addInput(parentOutPoint);
|
|
19724
|
-
let totalOutputAmount = 0n;
|
|
19725
|
-
for (const txOut of childTxOuts) {
|
|
19726
|
-
totalOutputAmount += txOut.amount ?? 0n;
|
|
19727
|
-
}
|
|
19728
|
-
if (totalOutputAmount > BigInt(DEFAULT_FEE_SATS)) {
|
|
19729
|
-
const feeRatio = Number(DEFAULT_FEE_SATS) / Number(totalOutputAmount);
|
|
19730
|
-
for (const txOut of childTxOuts) {
|
|
19731
|
-
const adjustedAmount = BigInt(
|
|
19732
|
-
Math.floor(Number(txOut.amount ?? 0n) * (1 - feeRatio))
|
|
19733
|
-
);
|
|
19734
|
-
directSplitTx.addOutput({
|
|
19735
|
-
script: txOut.script,
|
|
19736
|
-
amount: adjustedAmount
|
|
19737
|
-
});
|
|
19738
|
-
}
|
|
19739
|
-
} else {
|
|
19740
|
-
for (const txOut of childTxOuts) {
|
|
19741
|
-
directSplitTx.addOutput(txOut);
|
|
19742
|
-
}
|
|
19743
|
-
}
|
|
19744
|
-
return [cpfpSplitTx, directSplitTx];
|
|
19745
|
-
}
|
|
19746
19955
|
function createNodeTx({
|
|
19956
|
+
sequence,
|
|
19747
19957
|
txOut,
|
|
19748
19958
|
parentOutPoint,
|
|
19749
19959
|
applyFee,
|
|
@@ -19753,7 +19963,10 @@ function createNodeTx({
|
|
|
19753
19963
|
version: 3,
|
|
19754
19964
|
allowUnknownOutputs: true
|
|
19755
19965
|
});
|
|
19756
|
-
nodeTx.addInput(
|
|
19966
|
+
nodeTx.addInput({
|
|
19967
|
+
...parentOutPoint,
|
|
19968
|
+
sequence
|
|
19969
|
+
});
|
|
19757
19970
|
if (applyFee) {
|
|
19758
19971
|
nodeTx.addOutput({
|
|
19759
19972
|
script: txOut.script,
|
|
@@ -19767,52 +19980,92 @@ function createNodeTx({
|
|
|
19767
19980
|
}
|
|
19768
19981
|
return nodeTx;
|
|
19769
19982
|
}
|
|
19770
|
-
function createNodeTxs(
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
if (
|
|
19778
|
-
|
|
19779
|
-
|
|
19780
|
-
|
|
19781
|
-
includeAnchor: false,
|
|
19782
|
-
applyFee: true
|
|
19983
|
+
function createNodeTxs({
|
|
19984
|
+
parentTx,
|
|
19985
|
+
sequence,
|
|
19986
|
+
directSequence,
|
|
19987
|
+
vout
|
|
19988
|
+
}) {
|
|
19989
|
+
const parentOutput = parentTx.getOutput(vout);
|
|
19990
|
+
if (!parentOutput.amount || !parentOutput.script) {
|
|
19991
|
+
throw new ValidationError("Parent output amount or script not found", {
|
|
19992
|
+
field: "parentOutput",
|
|
19993
|
+
value: parentOutput
|
|
19783
19994
|
});
|
|
19784
19995
|
}
|
|
19785
|
-
|
|
19996
|
+
const output = {
|
|
19997
|
+
script: parentOutput.script,
|
|
19998
|
+
amount: parentOutput.amount
|
|
19999
|
+
};
|
|
20000
|
+
const input = {
|
|
20001
|
+
txid: (0, import_utils3.hexToBytes)(getTxId(parentTx)),
|
|
20002
|
+
index: vout
|
|
20003
|
+
};
|
|
20004
|
+
const nodeTx = createNodeTx({
|
|
20005
|
+
sequence,
|
|
20006
|
+
txOut: output,
|
|
20007
|
+
parentOutPoint: input,
|
|
20008
|
+
includeAnchor: true
|
|
20009
|
+
});
|
|
20010
|
+
const directNodeTx = createNodeTx({
|
|
20011
|
+
sequence: directSequence ?? sequence + DIRECT_TIMELOCK_OFFSET,
|
|
20012
|
+
txOut: output,
|
|
20013
|
+
parentOutPoint: input,
|
|
20014
|
+
includeAnchor: false,
|
|
20015
|
+
applyFee: true
|
|
20016
|
+
});
|
|
20017
|
+
return { nodeTx, directNodeTx };
|
|
19786
20018
|
}
|
|
19787
|
-
function
|
|
19788
|
-
|
|
19789
|
-
|
|
19790
|
-
|
|
20019
|
+
function createRootNodeTx(parentTx, vout) {
|
|
20020
|
+
return createNodeTxs({
|
|
20021
|
+
parentTx,
|
|
20022
|
+
sequence: INITIAL_ROOT_NODE_SEQUENCE,
|
|
20023
|
+
vout
|
|
19791
20024
|
});
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
20025
|
+
}
|
|
20026
|
+
function createZeroTimelockNodeTx(parentTx) {
|
|
20027
|
+
return createNodeTxs({
|
|
20028
|
+
parentTx,
|
|
20029
|
+
sequence: INITIAL_ROOT_NODE_SEQUENCE,
|
|
20030
|
+
directSequence: DIRECT_TIMELOCK_OFFSET,
|
|
20031
|
+
vout: 0
|
|
19795
20032
|
});
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
20033
|
+
}
|
|
20034
|
+
function createInitialTimelockNodeTx(parentTx) {
|
|
20035
|
+
return createNodeTxs({
|
|
20036
|
+
parentTx,
|
|
20037
|
+
sequence: INITIAL_SEQUENCE,
|
|
20038
|
+
vout: 0
|
|
19801
20039
|
});
|
|
19802
|
-
|
|
19803
|
-
|
|
19804
|
-
|
|
20040
|
+
}
|
|
20041
|
+
function createDecrementedTimelockNodeTx(parentTx, currentTx) {
|
|
20042
|
+
const currentSequence = currentTx.getInput(0).sequence;
|
|
20043
|
+
if (!currentSequence) {
|
|
20044
|
+
throw new ValidationError("Current sequence not found", {
|
|
20045
|
+
field: "currentSequence",
|
|
20046
|
+
value: currentSequence
|
|
20047
|
+
});
|
|
20048
|
+
}
|
|
20049
|
+
return createNodeTxs({
|
|
20050
|
+
parentTx,
|
|
20051
|
+
sequence: getNextTransactionSequence(currentSequence).nextSequence,
|
|
20052
|
+
vout: 0
|
|
19805
20053
|
});
|
|
19806
|
-
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
20054
|
+
}
|
|
20055
|
+
function createTestUnilateralTimelockNodeTx(parentTx, nodeTx) {
|
|
20056
|
+
const sequence = nodeTx.getInput(0).sequence;
|
|
20057
|
+
if (!sequence) {
|
|
20058
|
+
throw new ValidationError("Sequence not found", {
|
|
20059
|
+
field: "sequence",
|
|
20060
|
+
value: sequence
|
|
20061
|
+
});
|
|
19810
20062
|
}
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
20063
|
+
const isBit30Defined = (sequence || 0) & 1 << 30;
|
|
20064
|
+
return createNodeTxs({
|
|
20065
|
+
parentTx,
|
|
20066
|
+
sequence: isBit30Defined | TEST_UNILATERAL_TIMELOCK,
|
|
20067
|
+
vout: 0
|
|
19814
20068
|
});
|
|
19815
|
-
return [cpfpLeafTx, directLeafTx];
|
|
19816
20069
|
}
|
|
19817
20070
|
function createRefundTx({
|
|
19818
20071
|
sequence,
|
|
@@ -19868,110 +20121,109 @@ function getNextHTLCTransactionSequence(currSequence, isNodeTx) {
|
|
|
19868
20121
|
};
|
|
19869
20122
|
}
|
|
19870
20123
|
function createRefundTxs({
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
input,
|
|
19874
|
-
directInput,
|
|
19875
|
-
amountSats,
|
|
20124
|
+
nodeTx,
|
|
20125
|
+
directNodeTx,
|
|
19876
20126
|
receivingPubkey,
|
|
19877
|
-
network
|
|
20127
|
+
network,
|
|
20128
|
+
sequence
|
|
19878
20129
|
}) {
|
|
19879
|
-
const
|
|
19880
|
-
|
|
19881
|
-
|
|
19882
|
-
|
|
19883
|
-
|
|
19884
|
-
|
|
19885
|
-
|
|
19886
|
-
|
|
19887
|
-
|
|
20130
|
+
const refundInput = {
|
|
20131
|
+
txid: (0, import_utils3.hexToBytes)(getTxId(nodeTx)),
|
|
20132
|
+
index: 0
|
|
20133
|
+
};
|
|
20134
|
+
const nodeAmountSats = nodeTx.getOutput(0).amount;
|
|
20135
|
+
if (nodeAmountSats === void 0) {
|
|
20136
|
+
throw new ValidationError("Node amount not found", {
|
|
20137
|
+
field: "nodeAmountSats",
|
|
20138
|
+
value: nodeAmountSats
|
|
20139
|
+
});
|
|
20140
|
+
}
|
|
19888
20141
|
let directRefundTx;
|
|
19889
|
-
|
|
19890
|
-
|
|
20142
|
+
if (directNodeTx) {
|
|
20143
|
+
const directRefundInput = {
|
|
20144
|
+
txid: (0, import_utils3.hexToBytes)(getTxId(directNodeTx)),
|
|
20145
|
+
index: 0
|
|
20146
|
+
};
|
|
20147
|
+
const directAmountSats = directNodeTx.getOutput(0).amount;
|
|
20148
|
+
if (directAmountSats === void 0) {
|
|
20149
|
+
throw new ValidationError("Direct amount not found", {
|
|
20150
|
+
field: "directAmountSats",
|
|
20151
|
+
value: directAmountSats
|
|
20152
|
+
});
|
|
20153
|
+
}
|
|
19891
20154
|
directRefundTx = createRefundTx({
|
|
19892
|
-
sequence:
|
|
19893
|
-
input:
|
|
19894
|
-
amountSats,
|
|
19895
|
-
receivingPubkey,
|
|
19896
|
-
network,
|
|
19897
|
-
shouldCalculateFee: true,
|
|
19898
|
-
includeAnchor: false
|
|
19899
|
-
});
|
|
19900
|
-
directFromCpfpRefundTx = createRefundTx({
|
|
19901
|
-
sequence: directSequence,
|
|
19902
|
-
input,
|
|
19903
|
-
amountSats,
|
|
20155
|
+
sequence: sequence + DIRECT_TIMELOCK_OFFSET,
|
|
20156
|
+
input: directRefundInput,
|
|
20157
|
+
amountSats: directAmountSats,
|
|
19904
20158
|
receivingPubkey,
|
|
19905
20159
|
network,
|
|
19906
20160
|
shouldCalculateFee: true,
|
|
19907
20161
|
includeAnchor: false
|
|
19908
20162
|
});
|
|
19909
|
-
} else if (directInput && !directSequence) {
|
|
19910
|
-
throw new ValidationError(
|
|
19911
|
-
"directSequence must be provided if directInput is",
|
|
19912
|
-
{
|
|
19913
|
-
field: "directSequence",
|
|
19914
|
-
value: directSequence
|
|
19915
|
-
}
|
|
19916
|
-
);
|
|
19917
20163
|
}
|
|
19918
|
-
|
|
19919
|
-
|
|
19920
|
-
|
|
19921
|
-
|
|
19922
|
-
|
|
19923
|
-
|
|
20164
|
+
const cpfpRefundTx = createRefundTx({
|
|
20165
|
+
sequence,
|
|
20166
|
+
input: refundInput,
|
|
20167
|
+
amountSats: nodeAmountSats,
|
|
20168
|
+
receivingPubkey,
|
|
20169
|
+
network,
|
|
20170
|
+
shouldCalculateFee: false,
|
|
20171
|
+
includeAnchor: true
|
|
19924
20172
|
});
|
|
19925
|
-
|
|
19926
|
-
|
|
19927
|
-
|
|
20173
|
+
const directFromCpfpRefundTx = createRefundTx({
|
|
20174
|
+
sequence: sequence + DIRECT_TIMELOCK_OFFSET,
|
|
20175
|
+
input: refundInput,
|
|
20176
|
+
amountSats: nodeAmountSats,
|
|
20177
|
+
receivingPubkey,
|
|
20178
|
+
network,
|
|
20179
|
+
shouldCalculateFee: true,
|
|
20180
|
+
includeAnchor: false
|
|
19928
20181
|
});
|
|
19929
|
-
cpfpRefundTx
|
|
19930
|
-
|
|
19931
|
-
|
|
19932
|
-
|
|
19933
|
-
|
|
20182
|
+
return { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx };
|
|
20183
|
+
}
|
|
20184
|
+
function createInitialTimelockRefundTxs(params) {
|
|
20185
|
+
return createRefundTxs({
|
|
20186
|
+
...params,
|
|
20187
|
+
sequence: INITIAL_SEQUENCE
|
|
19934
20188
|
});
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
20189
|
+
}
|
|
20190
|
+
function createDecrementedTimelockRefundTxs(params) {
|
|
20191
|
+
const nextSequence = getNextTransactionSequence(params.sequence).nextSequence;
|
|
20192
|
+
return createRefundTxs({
|
|
20193
|
+
...params,
|
|
20194
|
+
sequence: nextSequence
|
|
19938
20195
|
});
|
|
19939
|
-
|
|
19940
|
-
|
|
19941
|
-
|
|
20196
|
+
}
|
|
20197
|
+
function createCurrentTimelockRefundTxs(params) {
|
|
20198
|
+
return createRefundTxs(params);
|
|
20199
|
+
}
|
|
20200
|
+
function createTestUnilateralRefundTxs(params) {
|
|
20201
|
+
return createRefundTxs({
|
|
20202
|
+
...params,
|
|
20203
|
+
sequence: TEST_UNILATERAL_SEQUENCE
|
|
19942
20204
|
});
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
20205
|
+
}
|
|
20206
|
+
function createConnectorRefundTxs(params) {
|
|
20207
|
+
const { connectorOutput, ...baseParams } = params;
|
|
20208
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createDecrementedTimelockRefundTxs(baseParams);
|
|
20209
|
+
cpfpRefundTx.addInput(connectorOutput);
|
|
20210
|
+
if (directRefundTx) {
|
|
20211
|
+
directRefundTx.addInput(connectorOutput);
|
|
19947
20212
|
}
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
}
|
|
19952
|
-
const directFromCpfpTx = new import_btc_signer.Transaction({
|
|
19953
|
-
version: 3,
|
|
19954
|
-
allowUnknownOutputs: true
|
|
19955
|
-
});
|
|
19956
|
-
directFromCpfpTx.addInput({
|
|
19957
|
-
...cpfpNodeOutPoint,
|
|
19958
|
-
sequence
|
|
19959
|
-
});
|
|
19960
|
-
directFromCpfpTx.addInput(connectorOutput);
|
|
19961
|
-
directFromCpfpTx.addOutput({
|
|
19962
|
-
script: receiverScript,
|
|
19963
|
-
amount: outputAmount
|
|
19964
|
-
});
|
|
19965
|
-
return [cpfpRefundTx, directRefundTx, directFromCpfpTx];
|
|
20213
|
+
if (directFromCpfpRefundTx) {
|
|
20214
|
+
directFromCpfpRefundTx.addInput(connectorOutput);
|
|
20215
|
+
}
|
|
20216
|
+
return { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx };
|
|
19966
20217
|
}
|
|
19967
20218
|
function getCurrentTimelock(currSequence) {
|
|
19968
20219
|
return (currSequence || 0) & 65535;
|
|
19969
20220
|
}
|
|
19970
20221
|
function getTransactionSequence(currSequence) {
|
|
19971
20222
|
const timelock = getCurrentTimelock(currSequence);
|
|
20223
|
+
const isBit30Defined = (currSequence || 0) & 1 << 30;
|
|
19972
20224
|
return {
|
|
19973
|
-
nextSequence:
|
|
19974
|
-
nextDirectSequence:
|
|
20225
|
+
nextSequence: isBit30Defined | timelock,
|
|
20226
|
+
nextDirectSequence: isBit30Defined | timelock + DIRECT_TIMELOCK_OFFSET
|
|
19975
20227
|
};
|
|
19976
20228
|
}
|
|
19977
20229
|
function checkIfValidSequence(currSequence) {
|
|
@@ -19990,6 +20242,13 @@ function checkIfValidSequence(currSequence) {
|
|
|
19990
20242
|
});
|
|
19991
20243
|
}
|
|
19992
20244
|
}
|
|
20245
|
+
function isZeroTimelock(currSequence) {
|
|
20246
|
+
return getCurrentTimelock(currSequence) === 0;
|
|
20247
|
+
}
|
|
20248
|
+
function doesTxnNeedRenewed(currSequence) {
|
|
20249
|
+
const currentTimelock = getCurrentTimelock(currSequence);
|
|
20250
|
+
return currentTimelock <= 100;
|
|
20251
|
+
}
|
|
19993
20252
|
function doesLeafNeedRefresh(currSequence, isNodeTx) {
|
|
19994
20253
|
const currentTimelock = getCurrentTimelock(currSequence);
|
|
19995
20254
|
if (isNodeTx) {
|
|
@@ -20000,6 +20259,7 @@ function doesLeafNeedRefresh(currSequence, isNodeTx) {
|
|
|
20000
20259
|
function getNextTransactionSequence(currSequence, isNodeTx) {
|
|
20001
20260
|
const currentTimelock = getCurrentTimelock(currSequence);
|
|
20002
20261
|
const nextTimelock = currentTimelock - TIME_LOCK_INTERVAL;
|
|
20262
|
+
const isBit30Defined = (currSequence || 0) & 1 << 30;
|
|
20003
20263
|
if (isNodeTx && nextTimelock < 0) {
|
|
20004
20264
|
throw new ValidationError("timelock interval is less than 0", {
|
|
20005
20265
|
field: "nextTimelock",
|
|
@@ -20014,8 +20274,8 @@ function getNextTransactionSequence(currSequence, isNodeTx) {
|
|
|
20014
20274
|
});
|
|
20015
20275
|
}
|
|
20016
20276
|
return {
|
|
20017
|
-
nextSequence:
|
|
20018
|
-
nextDirectSequence:
|
|
20277
|
+
nextSequence: isBit30Defined | nextTimelock,
|
|
20278
|
+
nextDirectSequence: isBit30Defined | nextTimelock + DIRECT_TIMELOCK_OFFSET
|
|
20019
20279
|
};
|
|
20020
20280
|
}
|
|
20021
20281
|
function getEphemeralAnchorOutput() {
|
|
@@ -20028,14 +20288,13 @@ function getEphemeralAnchorOutput() {
|
|
|
20028
20288
|
|
|
20029
20289
|
// src/services/transfer.ts
|
|
20030
20290
|
var import_secp256k12 = require("@noble/curves/secp256k1");
|
|
20031
|
-
var
|
|
20291
|
+
var import_utils5 = require("@noble/curves/utils");
|
|
20032
20292
|
var import_sha24 = require("@noble/hashes/sha2");
|
|
20033
|
-
var import_btc_signer2 = require("@scure/btc-signer");
|
|
20034
20293
|
var ecies = __toESM(require("eciesjs"), 1);
|
|
20035
20294
|
var import_uuidv7 = require("uuidv7");
|
|
20036
20295
|
|
|
20037
20296
|
// src/utils/transfer_package.ts
|
|
20038
|
-
var
|
|
20297
|
+
var import_utils4 = require("@noble/curves/utils");
|
|
20039
20298
|
var import_sha23 = require("@noble/hashes/sha2");
|
|
20040
20299
|
function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
20041
20300
|
const encryptedPayload = transferPackage.keyTweakPackage;
|
|
@@ -20044,7 +20303,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
20044
20303
|
).map(([key, value]) => ({ key, value }));
|
|
20045
20304
|
pairs.sort((a, b) => a.key.localeCompare(b.key));
|
|
20046
20305
|
const encoder = new TextEncoder();
|
|
20047
|
-
let message = (0,
|
|
20306
|
+
let message = (0, import_utils4.hexToBytes)(transferID.replaceAll("-", ""));
|
|
20048
20307
|
for (const pair of pairs) {
|
|
20049
20308
|
const keyPart = encoder.encode(pair.key + ":");
|
|
20050
20309
|
const separator = encoder.encode(";");
|
|
@@ -20059,13 +20318,6 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
20059
20318
|
}
|
|
20060
20319
|
|
|
20061
20320
|
// src/services/transfer.ts
|
|
20062
|
-
function getSigningJobProto(signingJob) {
|
|
20063
|
-
return {
|
|
20064
|
-
signingPublicKey: signingJob.signingPublicKey,
|
|
20065
|
-
rawTx: signingJob.rawTx,
|
|
20066
|
-
signingNonceCommitment: signingJob.signingNonceCommitment.commitment
|
|
20067
|
-
};
|
|
20068
|
-
}
|
|
20069
20321
|
var BaseTransferService = class {
|
|
20070
20322
|
config;
|
|
20071
20323
|
connectionManager;
|
|
@@ -20412,7 +20664,7 @@ var BaseTransferService = class {
|
|
|
20412
20664
|
}
|
|
20413
20665
|
async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
|
|
20414
20666
|
const receiverEciesPubKey = ecies.PublicKey.fromHex(
|
|
20415
|
-
(0,
|
|
20667
|
+
(0, import_utils5.bytesToHex)(receiverIdentityPubkey)
|
|
20416
20668
|
);
|
|
20417
20669
|
const leavesTweaksMap = /* @__PURE__ */ new Map();
|
|
20418
20670
|
for (const leaf of leaves) {
|
|
@@ -20453,7 +20705,7 @@ var BaseTransferService = class {
|
|
|
20453
20705
|
throw new Error(`Share not found for operator ${operator.id}`);
|
|
20454
20706
|
}
|
|
20455
20707
|
const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
|
|
20456
|
-
(0,
|
|
20708
|
+
(0, import_utils5.numberToBytesBE)(share.share, 32),
|
|
20457
20709
|
true
|
|
20458
20710
|
);
|
|
20459
20711
|
pubkeySharesTweak.set(identifier, pubkeyTweak);
|
|
@@ -20478,7 +20730,7 @@ var BaseTransferService = class {
|
|
|
20478
20730
|
leafTweaksMap.set(identifier, {
|
|
20479
20731
|
leafId: leaf.leaf.id,
|
|
20480
20732
|
secretShareTweak: {
|
|
20481
|
-
secretShare: (0,
|
|
20733
|
+
secretShare: (0, import_utils5.numberToBytesBE)(share.share, 32),
|
|
20482
20734
|
proofs: share.proofs
|
|
20483
20735
|
},
|
|
20484
20736
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak),
|
|
@@ -20501,7 +20753,7 @@ var BaseTransferService = class {
|
|
|
20501
20753
|
return void 0;
|
|
20502
20754
|
}
|
|
20503
20755
|
compareTransfers(transfer1, transfer2) {
|
|
20504
|
-
return transfer1.id === transfer2.id && (0,
|
|
20756
|
+
return transfer1.id === transfer2.id && (0, import_utils5.equalBytes)(
|
|
20505
20757
|
transfer1.senderIdentityPublicKey,
|
|
20506
20758
|
transfer2.senderIdentityPublicKey
|
|
20507
20759
|
) && transfer1.status === transfer2.status && transfer1.totalValue === transfer2.totalValue && transfer1.expiryTime?.getTime() === transfer2.expiryTime?.getTime() && transfer1.leaves.length === transfer2.leaves.length;
|
|
@@ -20747,42 +20999,27 @@ var TransferService = class extends BaseTransferService {
|
|
|
20747
20999
|
throw new Error(`Leaf data not found for leaf ${leaf.leaf.id}`);
|
|
20748
21000
|
}
|
|
20749
21001
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
20750
|
-
const cpfpNodeOutPoint = {
|
|
20751
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
20752
|
-
index: 0
|
|
20753
|
-
};
|
|
20754
21002
|
let directNodeTx;
|
|
20755
|
-
let directNodeOutPoint;
|
|
20756
21003
|
if (leaf.leaf.directTx.length > 0) {
|
|
20757
21004
|
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
20758
|
-
directNodeOutPoint = {
|
|
20759
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
|
|
20760
|
-
index: 0
|
|
20761
|
-
};
|
|
20762
21005
|
}
|
|
20763
21006
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
20764
|
-
const
|
|
20765
|
-
if (!
|
|
21007
|
+
const currentSequence = currRefundTx.getInput(0).sequence;
|
|
21008
|
+
if (!currentSequence) {
|
|
20766
21009
|
throw new ValidationError("Invalid refund transaction", {
|
|
20767
21010
|
field: "sequence",
|
|
20768
21011
|
value: currRefundTx.getInput(0),
|
|
20769
21012
|
expected: "Non-null sequence"
|
|
20770
21013
|
});
|
|
20771
21014
|
}
|
|
20772
|
-
const
|
|
20773
|
-
|
|
20774
|
-
|
|
20775
|
-
|
|
20776
|
-
}
|
|
20777
|
-
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
|
|
20778
|
-
sequence: nextSequence,
|
|
20779
|
-
directSequence: nextDirectSequence,
|
|
20780
|
-
input: cpfpNodeOutPoint,
|
|
20781
|
-
directInput: directNodeOutPoint,
|
|
20782
|
-
amountSats,
|
|
21015
|
+
const refundTxsParams = {
|
|
21016
|
+
nodeTx,
|
|
21017
|
+
directNodeTx,
|
|
21018
|
+
sequence: currentSequence,
|
|
20783
21019
|
receivingPubkey: refundSigningData.receivingPubkey,
|
|
20784
21020
|
network: this.config.getNetwork()
|
|
20785
|
-
}
|
|
21021
|
+
};
|
|
21022
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = isForClaim ? createCurrentTimelockRefundTxs(refundTxsParams) : createDecrementedTimelockRefundTxs(refundTxsParams);
|
|
20786
21023
|
refundSigningData.refundTx = cpfpRefundTx;
|
|
20787
21024
|
refundSigningData.directRefundTx = directRefundTx;
|
|
20788
21025
|
refundSigningData.directFromCpfpRefundTx = directFromCpfpRefundTx;
|
|
@@ -20890,7 +21127,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
20890
21127
|
throw new Error(`Share not found for operator ${operator.id}`);
|
|
20891
21128
|
}
|
|
20892
21129
|
const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
|
|
20893
|
-
(0,
|
|
21130
|
+
(0, import_utils5.numberToBytesBE)(share.share, 32)
|
|
20894
21131
|
);
|
|
20895
21132
|
pubkeySharesTweak.set(identifier, pubkeyTweak);
|
|
20896
21133
|
}
|
|
@@ -20903,7 +21140,7 @@ var TransferService = class extends BaseTransferService {
|
|
|
20903
21140
|
leafTweaksMap.set(identifier, {
|
|
20904
21141
|
leafId: leaf.leaf.id,
|
|
20905
21142
|
secretShareTweak: {
|
|
20906
|
-
secretShare: (0,
|
|
21143
|
+
secretShare: (0, import_utils5.numberToBytesBE)(share.share, 32),
|
|
20907
21144
|
proofs: share.proofs
|
|
20908
21145
|
},
|
|
20909
21146
|
pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak)
|
|
@@ -20995,71 +21232,127 @@ var TransferService = class extends BaseTransferService {
|
|
|
20995
21232
|
throw new Error(`Error querying pending transfers by sender: ${error}`);
|
|
20996
21233
|
}
|
|
20997
21234
|
}
|
|
20998
|
-
async
|
|
20999
|
-
const
|
|
21000
|
-
|
|
21001
|
-
|
|
21002
|
-
|
|
21003
|
-
|
|
21235
|
+
async renewRefundTxn(node, parentNode) {
|
|
21236
|
+
const sparkClient = await this.connectionManager.createSparkClient(
|
|
21237
|
+
this.config.getCoordinatorAddress()
|
|
21238
|
+
);
|
|
21239
|
+
const signingJobs = await this.createRenewRefundSigningJobs(
|
|
21240
|
+
node,
|
|
21241
|
+
parentNode
|
|
21242
|
+
);
|
|
21243
|
+
const statechainCommitments = await sparkClient.get_signing_commitments({
|
|
21244
|
+
nodeIds: [node.id],
|
|
21245
|
+
count: signingJobs.length
|
|
21246
|
+
});
|
|
21247
|
+
const mappedSigningJobs = signingJobs.map((signingJob, index) => {
|
|
21248
|
+
const signingNonceCommitments = statechainCommitments.signingCommitments[index]?.signingNonceCommitments;
|
|
21249
|
+
if (!signingNonceCommitments) {
|
|
21250
|
+
throw new Error("Signing nonce commitments not found");
|
|
21251
|
+
}
|
|
21252
|
+
return {
|
|
21253
|
+
...signingJob,
|
|
21254
|
+
signingNonceCommitments
|
|
21255
|
+
};
|
|
21256
|
+
});
|
|
21257
|
+
const userSignedTxSigningJobs = await this.signingService.signSigningJobs(mappedSigningJobs);
|
|
21258
|
+
const renewRefundTimelockSigningJob = {
|
|
21259
|
+
nodeTxSigningJob: userSignedTxSigningJobs.get("node"),
|
|
21260
|
+
refundTxSigningJob: userSignedTxSigningJobs.get("cpfp"),
|
|
21261
|
+
directNodeTxSigningJob: userSignedTxSigningJobs.get("directNode"),
|
|
21262
|
+
directRefundTxSigningJob: userSignedTxSigningJobs.get("direct"),
|
|
21263
|
+
directFromCpfpRefundTxSigningJob: userSignedTxSigningJobs.get("directFromCpfp")
|
|
21264
|
+
};
|
|
21265
|
+
const response = await sparkClient.renew_leaf({
|
|
21266
|
+
leafId: node.id,
|
|
21267
|
+
signingJobs: {
|
|
21268
|
+
$case: "renewRefundTimelockSigningJob",
|
|
21269
|
+
renewRefundTimelockSigningJob
|
|
21270
|
+
}
|
|
21271
|
+
});
|
|
21272
|
+
if (response.renewResult?.$case !== "renewRefundTimelockResult" || !response.renewResult?.renewRefundTimelockResult.node) {
|
|
21273
|
+
throw new ValidationError("Unexpected renew result", {
|
|
21274
|
+
field: "renewResult",
|
|
21275
|
+
value: response.renewResult
|
|
21276
|
+
});
|
|
21004
21277
|
}
|
|
21005
|
-
|
|
21006
|
-
|
|
21007
|
-
|
|
21008
|
-
|
|
21009
|
-
|
|
21010
|
-
|
|
21011
|
-
|
|
21012
|
-
|
|
21013
|
-
|
|
21014
|
-
|
|
21015
|
-
|
|
21016
|
-
|
|
21017
|
-
|
|
21018
|
-
|
|
21019
|
-
|
|
21020
|
-
|
|
21021
|
-
|
|
21022
|
-
|
|
21278
|
+
return response.renewResult?.renewRefundTimelockResult.node;
|
|
21279
|
+
}
|
|
21280
|
+
async renewNodeTxn(node, parentNode) {
|
|
21281
|
+
const sparkClient = await this.connectionManager.createSparkClient(
|
|
21282
|
+
this.config.getCoordinatorAddress()
|
|
21283
|
+
);
|
|
21284
|
+
const signingJobs = await this.createRenewNodeSigningJobs(node, parentNode);
|
|
21285
|
+
const statechainCommitments = await sparkClient.get_signing_commitments({
|
|
21286
|
+
nodeIds: [node.id],
|
|
21287
|
+
count: signingJobs.length
|
|
21288
|
+
});
|
|
21289
|
+
const mappedSigningJobs = signingJobs.map((signingJob, index) => {
|
|
21290
|
+
const signingNonceCommitments = statechainCommitments.signingCommitments[index]?.signingNonceCommitments;
|
|
21291
|
+
if (!signingNonceCommitments) {
|
|
21292
|
+
throw new Error("Signing nonce commitments not found");
|
|
21293
|
+
}
|
|
21294
|
+
return {
|
|
21295
|
+
...signingJob,
|
|
21296
|
+
signingNonceCommitments
|
|
21297
|
+
};
|
|
21298
|
+
});
|
|
21299
|
+
const userSignedTxSigningJobs = await this.signingService.signSigningJobs(mappedSigningJobs);
|
|
21300
|
+
const response = await sparkClient.renew_leaf({
|
|
21301
|
+
leafId: node.id,
|
|
21302
|
+
signingJobs: {
|
|
21303
|
+
$case: "renewNodeTimelockSigningJob",
|
|
21304
|
+
renewNodeTimelockSigningJob: {
|
|
21305
|
+
splitNodeTxSigningJob: userSignedTxSigningJobs.get("split"),
|
|
21306
|
+
splitNodeDirectTxSigningJob: userSignedTxSigningJobs.get("directSplit"),
|
|
21307
|
+
nodeTxSigningJob: userSignedTxSigningJobs.get("node"),
|
|
21308
|
+
directNodeTxSigningJob: userSignedTxSigningJobs.get("directNode"),
|
|
21309
|
+
refundTxSigningJob: userSignedTxSigningJobs.get("cpfp"),
|
|
21310
|
+
directRefundTxSigningJob: userSignedTxSigningJobs.get("direct"),
|
|
21311
|
+
directFromCpfpRefundTxSigningJob: userSignedTxSigningJobs.get("directFromCpfp")
|
|
21312
|
+
}
|
|
21313
|
+
}
|
|
21314
|
+
});
|
|
21315
|
+
if (response.renewResult?.$case !== "renewNodeTimelockResult" || !response.renewResult?.renewNodeTimelockResult.node) {
|
|
21316
|
+
throw new ValidationError("Unexpected renew result", {
|
|
21317
|
+
field: "renewResult",
|
|
21318
|
+
value: response.renewResult
|
|
21023
21319
|
});
|
|
21024
21320
|
}
|
|
21025
|
-
|
|
21026
|
-
|
|
21027
|
-
|
|
21321
|
+
return response.renewResult.renewNodeTimelockResult.node;
|
|
21322
|
+
}
|
|
21323
|
+
async createRenewRefundSigningJobs(node, parentNode) {
|
|
21324
|
+
const signingJobs = [];
|
|
21325
|
+
const parentTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
21326
|
+
const parentNodeOutput = getTxFromRawTxBytes(parentNode.nodeTx).getOutput(
|
|
21327
|
+
0
|
|
21028
21328
|
);
|
|
21029
|
-
|
|
21329
|
+
if (!parentNodeOutput) {
|
|
21330
|
+
throw new Error("Parent node output not found");
|
|
21331
|
+
}
|
|
21332
|
+
const unsignedParentNodeOutput = {
|
|
21030
21333
|
script: parentNodeOutput.script,
|
|
21031
21334
|
amount: parentNodeOutput.amount
|
|
21032
21335
|
};
|
|
21033
|
-
const
|
|
21034
|
-
txid: nodeInput.txid,
|
|
21035
|
-
index: nodeInput.index,
|
|
21036
|
-
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_SEQUENCE : nextSequence
|
|
21037
|
-
};
|
|
21038
|
-
const newDirectInput = directNodeTx && directNodeInput ? {
|
|
21039
|
-
txid: directNodeInput.txid,
|
|
21040
|
-
index: directNodeInput.index,
|
|
21041
|
-
sequence: useTestUnilateralSequence ? TEST_UNILATERAL_DIRECT_SEQUENCE : nextDirectSequence
|
|
21042
|
-
} : void 0;
|
|
21043
|
-
const { cpfpNodeTx, directNodeTx: newDirectNodeTx } = createNodeTxs(
|
|
21044
|
-
output,
|
|
21045
|
-
newNodeInput,
|
|
21046
|
-
newDirectInput
|
|
21047
|
-
);
|
|
21048
|
-
const newCpfpNodeOutput = cpfpNodeTx.getOutput(0);
|
|
21049
|
-
if (!newCpfpNodeOutput) {
|
|
21050
|
-
throw Error("Could not get new cpfp node output");
|
|
21051
|
-
}
|
|
21052
|
-
const newDirectNodeOutput = newDirectNodeTx?.getOutput(0);
|
|
21053
|
-
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
21336
|
+
const keyDerivation = {
|
|
21054
21337
|
type: "leaf" /* LEAF */,
|
|
21055
21338
|
path: node.id
|
|
21056
|
-
}
|
|
21339
|
+
};
|
|
21340
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
21341
|
+
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
21342
|
+
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
21343
|
+
const { nodeTx: newNodeTx, directNodeTx: newDirectNodeTx } = createDecrementedTimelockNodeTx(parentTx, nodeTx);
|
|
21057
21344
|
signingJobs.push({
|
|
21058
21345
|
signingPublicKey,
|
|
21059
|
-
rawTx:
|
|
21346
|
+
rawTx: newNodeTx.toBytes(),
|
|
21060
21347
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21061
21348
|
type: "node",
|
|
21062
|
-
parentTxOut:
|
|
21349
|
+
parentTxOut: unsignedParentNodeOutput,
|
|
21350
|
+
leafId: node.id,
|
|
21351
|
+
keyDerivation: {
|
|
21352
|
+
type: "leaf" /* LEAF */,
|
|
21353
|
+
path: node.id
|
|
21354
|
+
},
|
|
21355
|
+
verifyingKey: node.verifyingPublicKey
|
|
21063
21356
|
});
|
|
21064
21357
|
if (newDirectNodeTx) {
|
|
21065
21358
|
signingJobs.push({
|
|
@@ -21067,537 +21360,299 @@ var TransferService = class extends BaseTransferService {
|
|
|
21067
21360
|
rawTx: newDirectNodeTx.toBytes(),
|
|
21068
21361
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21069
21362
|
type: "directNode",
|
|
21070
|
-
parentTxOut:
|
|
21363
|
+
parentTxOut: unsignedParentNodeOutput,
|
|
21364
|
+
leafId: node.id,
|
|
21365
|
+
keyDerivation: {
|
|
21366
|
+
type: "leaf" /* LEAF */,
|
|
21367
|
+
path: node.id
|
|
21368
|
+
},
|
|
21369
|
+
verifyingKey: node.verifyingPublicKey
|
|
21071
21370
|
});
|
|
21072
21371
|
}
|
|
21073
|
-
const
|
|
21074
|
-
|
|
21075
|
-
|
|
21076
|
-
};
|
|
21077
|
-
let newDirectRefundOutPoint;
|
|
21078
|
-
if (newDirectNodeTx) {
|
|
21079
|
-
newDirectRefundOutPoint = {
|
|
21080
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
21081
|
-
index: 0
|
|
21082
|
-
};
|
|
21372
|
+
const newCpfpNodeOutput = newNodeTx.getOutput(0);
|
|
21373
|
+
if (!newCpfpNodeOutput) {
|
|
21374
|
+
throw Error("Could not get new cpfp node output");
|
|
21083
21375
|
}
|
|
21084
|
-
const
|
|
21085
|
-
|
|
21086
|
-
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
|
|
21091
|
-
|
|
21092
|
-
|
|
21093
|
-
|
|
21376
|
+
const newDirectNodeOutput = newDirectNodeTx?.getOutput(0);
|
|
21377
|
+
const amountSats = refundTx.getOutput(0).amount;
|
|
21378
|
+
if (amountSats === void 0) {
|
|
21379
|
+
throw new Error("Amount not found in extendTimelock");
|
|
21380
|
+
}
|
|
21381
|
+
const directAmountSats = newDirectNodeOutput?.amount;
|
|
21382
|
+
if (directAmountSats === void 0) {
|
|
21383
|
+
throw new Error("Amount not found in extendTimelock");
|
|
21384
|
+
}
|
|
21385
|
+
const {
|
|
21386
|
+
cpfpRefundTx: newRefundTx,
|
|
21387
|
+
directRefundTx: newDirectRefundTx,
|
|
21388
|
+
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
21389
|
+
} = createInitialTimelockRefundTxs({
|
|
21390
|
+
nodeTx: newNodeTx,
|
|
21391
|
+
directNodeTx: newDirectNodeTx,
|
|
21392
|
+
receivingPubkey: signingPublicKey,
|
|
21094
21393
|
network: this.config.getNetwork()
|
|
21095
21394
|
});
|
|
21096
21395
|
signingJobs.push({
|
|
21097
21396
|
signingPublicKey,
|
|
21098
|
-
rawTx:
|
|
21397
|
+
rawTx: newRefundTx.toBytes(),
|
|
21099
21398
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21100
21399
|
type: "cpfp",
|
|
21101
|
-
parentTxOut: newCpfpNodeOutput
|
|
21400
|
+
parentTxOut: newCpfpNodeOutput,
|
|
21401
|
+
leafId: node.id,
|
|
21402
|
+
keyDerivation,
|
|
21403
|
+
verifyingKey: node.verifyingPublicKey
|
|
21102
21404
|
});
|
|
21103
|
-
if (
|
|
21405
|
+
if (newDirectRefundTx && newDirectNodeOutput) {
|
|
21104
21406
|
signingJobs.push({
|
|
21105
21407
|
signingPublicKey,
|
|
21106
|
-
rawTx:
|
|
21408
|
+
rawTx: newDirectRefundTx.toBytes(),
|
|
21107
21409
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21108
21410
|
type: "direct",
|
|
21109
|
-
parentTxOut: newDirectNodeOutput
|
|
21411
|
+
parentTxOut: newDirectNodeOutput,
|
|
21412
|
+
leafId: node.id,
|
|
21413
|
+
keyDerivation,
|
|
21414
|
+
verifyingKey: node.verifyingPublicKey
|
|
21110
21415
|
});
|
|
21111
21416
|
}
|
|
21112
|
-
if (
|
|
21417
|
+
if (newDirectFromCpfpRefundTx && newDirectNodeOutput) {
|
|
21113
21418
|
signingJobs.push({
|
|
21114
21419
|
signingPublicKey,
|
|
21115
|
-
rawTx:
|
|
21420
|
+
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
21116
21421
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21117
21422
|
type: "directFromCpfp",
|
|
21118
|
-
parentTxOut: newCpfpNodeOutput
|
|
21423
|
+
parentTxOut: newCpfpNodeOutput,
|
|
21424
|
+
leafId: node.id,
|
|
21425
|
+
keyDerivation,
|
|
21426
|
+
verifyingKey: node.verifyingPublicKey
|
|
21119
21427
|
});
|
|
21120
21428
|
}
|
|
21121
|
-
|
|
21122
|
-
this.config.getCoordinatorAddress()
|
|
21123
|
-
);
|
|
21124
|
-
const response = await sparkClient.refresh_timelock_v2({
|
|
21125
|
-
leafId: node.id,
|
|
21126
|
-
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
21127
|
-
signingJobs: signingJobs.map(getSigningJobProto)
|
|
21128
|
-
});
|
|
21129
|
-
if (signingJobs.length !== response.signingResults.length) {
|
|
21130
|
-
throw Error(
|
|
21131
|
-
`number of signing jobs and signing results do not match: ${signingJobs.length} !== ${response.signingResults.length}`
|
|
21132
|
-
);
|
|
21133
|
-
}
|
|
21134
|
-
let nodeSignatures = [];
|
|
21135
|
-
let leafCpfpSignature;
|
|
21136
|
-
let leafDirectSignature;
|
|
21137
|
-
let cpfpRefundSignature;
|
|
21138
|
-
let directRefundSignature;
|
|
21139
|
-
let directFromCpfpRefundSignature;
|
|
21140
|
-
for (const [i, signingResult] of response.signingResults.entries()) {
|
|
21141
|
-
const signingJob = signingJobs[i];
|
|
21142
|
-
if (!signingJob || !signingResult) {
|
|
21143
|
-
throw Error("Signing job does not exist");
|
|
21144
|
-
}
|
|
21145
|
-
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
21146
|
-
const txOut = signingJob.parentTxOut;
|
|
21147
|
-
if (!txOut) {
|
|
21148
|
-
throw Error("Could not get tx out");
|
|
21149
|
-
}
|
|
21150
|
-
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
21151
|
-
const userSignature = await this.config.signer.signFrost({
|
|
21152
|
-
message: rawTxSighash,
|
|
21153
|
-
keyDerivation: {
|
|
21154
|
-
type: "leaf" /* LEAF */,
|
|
21155
|
-
path: node.id
|
|
21156
|
-
},
|
|
21157
|
-
publicKey: signingJob.signingPublicKey,
|
|
21158
|
-
verifyingKey: signingResult.verifyingKey,
|
|
21159
|
-
selfCommitment: signingJob.signingNonceCommitment,
|
|
21160
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
21161
|
-
adaptorPubKey: new Uint8Array()
|
|
21162
|
-
});
|
|
21163
|
-
const signature = await this.config.signer.aggregateFrost({
|
|
21164
|
-
message: rawTxSighash,
|
|
21165
|
-
statechainSignatures: signingResult.signingResult?.signatureShares,
|
|
21166
|
-
statechainPublicKeys: signingResult.signingResult?.publicKeys,
|
|
21167
|
-
verifyingKey: signingResult.verifyingKey,
|
|
21168
|
-
statechainCommitments: signingResult.signingResult?.signingNonceCommitments,
|
|
21169
|
-
selfCommitment: signingJob.signingNonceCommitment,
|
|
21170
|
-
publicKey: signingJob.signingPublicKey,
|
|
21171
|
-
selfSignature: userSignature,
|
|
21172
|
-
adaptorPubKey: new Uint8Array()
|
|
21173
|
-
});
|
|
21174
|
-
if (signingJob.type === "node") {
|
|
21175
|
-
leafCpfpSignature = signature;
|
|
21176
|
-
} else if (signingJob.type === "directNode") {
|
|
21177
|
-
leafDirectSignature = signature;
|
|
21178
|
-
} else if (signingJob.type === "cpfp") {
|
|
21179
|
-
cpfpRefundSignature = signature;
|
|
21180
|
-
} else if (signingJob.type === "direct") {
|
|
21181
|
-
directRefundSignature = signature;
|
|
21182
|
-
} else if (signingJob.type === "directFromCpfp") {
|
|
21183
|
-
directFromCpfpRefundSignature = signature;
|
|
21184
|
-
}
|
|
21185
|
-
}
|
|
21186
|
-
nodeSignatures.push({
|
|
21187
|
-
nodeId: node.id,
|
|
21188
|
-
nodeTxSignature: leafCpfpSignature || new Uint8Array(),
|
|
21189
|
-
directNodeTxSignature: leafDirectSignature || new Uint8Array(),
|
|
21190
|
-
refundTxSignature: cpfpRefundSignature || new Uint8Array(),
|
|
21191
|
-
directRefundTxSignature: directRefundSignature || new Uint8Array(),
|
|
21192
|
-
directFromCpfpRefundTxSignature: directFromCpfpRefundSignature || new Uint8Array()
|
|
21193
|
-
});
|
|
21194
|
-
const result = await sparkClient.finalize_node_signatures_v2({
|
|
21195
|
-
intent: 3 /* REFRESH */,
|
|
21196
|
-
nodeSignatures
|
|
21197
|
-
});
|
|
21198
|
-
return result;
|
|
21199
|
-
}
|
|
21200
|
-
async refreshTimelockNodes(node, parentNode) {
|
|
21201
|
-
return await this.refreshTimelockNodesInternal(node, parentNode);
|
|
21429
|
+
return signingJobs;
|
|
21202
21430
|
}
|
|
21203
|
-
async
|
|
21204
|
-
const
|
|
21205
|
-
const
|
|
21206
|
-
const
|
|
21207
|
-
|
|
21208
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
21209
|
-
index: 0
|
|
21210
|
-
};
|
|
21211
|
-
const {
|
|
21212
|
-
nextSequence: newNodeSequence,
|
|
21213
|
-
nextDirectSequence: newDirectNodeSequence
|
|
21214
|
-
} = getNextTransactionSequence(refundSequence);
|
|
21215
|
-
const newNodeTx = new import_btc_signer2.Transaction({
|
|
21216
|
-
version: 3,
|
|
21217
|
-
allowUnknownOutputs: true
|
|
21218
|
-
});
|
|
21219
|
-
newNodeTx.addInput({ ...newNodeOutPoint, sequence: newNodeSequence });
|
|
21220
|
-
const originalOutput = nodeTx.getOutput(0);
|
|
21221
|
-
if (!originalOutput) {
|
|
21222
|
-
throw Error("Could not get original node output");
|
|
21223
|
-
}
|
|
21224
|
-
newNodeTx.addOutput({
|
|
21225
|
-
script: originalOutput.script,
|
|
21226
|
-
amount: originalOutput.amount
|
|
21227
|
-
});
|
|
21228
|
-
newNodeTx.addOutput(getEphemeralAnchorOutput());
|
|
21229
|
-
let newDirectNodeTx;
|
|
21230
|
-
if (node.directTx.length > 0) {
|
|
21231
|
-
newDirectNodeTx = new import_btc_signer2.Transaction({
|
|
21232
|
-
version: 3,
|
|
21233
|
-
allowUnknownOutputs: true
|
|
21234
|
-
});
|
|
21235
|
-
newDirectNodeTx.addInput({
|
|
21236
|
-
...newNodeOutPoint,
|
|
21237
|
-
sequence: newDirectNodeSequence
|
|
21238
|
-
});
|
|
21239
|
-
newDirectNodeTx.addOutput({
|
|
21240
|
-
script: originalOutput.script,
|
|
21241
|
-
amount: maybeApplyFee(originalOutput.amount)
|
|
21242
|
-
});
|
|
21243
|
-
}
|
|
21244
|
-
const newCpfpRefundOutPoint = {
|
|
21245
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(newNodeTx)),
|
|
21246
|
-
index: 0
|
|
21247
|
-
};
|
|
21248
|
-
let newDirectRefundOutPoint;
|
|
21249
|
-
if (newDirectNodeTx) {
|
|
21250
|
-
newDirectRefundOutPoint = {
|
|
21251
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
|
|
21252
|
-
index: 0
|
|
21253
|
-
};
|
|
21254
|
-
}
|
|
21255
|
-
const amountSats = refundTx.getOutput(0).amount;
|
|
21256
|
-
if (amountSats === void 0) {
|
|
21257
|
-
throw new Error("Amount not found in extendTimelock");
|
|
21258
|
-
}
|
|
21259
|
-
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation({
|
|
21260
|
-
type: "leaf" /* LEAF */,
|
|
21261
|
-
path: node.id
|
|
21262
|
-
});
|
|
21263
|
-
const {
|
|
21264
|
-
cpfpRefundTx: newCpfpRefundTx,
|
|
21265
|
-
directRefundTx: newDirectRefundTx,
|
|
21266
|
-
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
21267
|
-
} = createRefundTxs({
|
|
21268
|
-
sequence: INITIAL_SEQUENCE,
|
|
21269
|
-
directSequence: INITIAL_DIRECT_SEQUENCE,
|
|
21270
|
-
input: newCpfpRefundOutPoint,
|
|
21271
|
-
directInput: newDirectRefundOutPoint,
|
|
21272
|
-
amountSats,
|
|
21273
|
-
receivingPubkey: signingPublicKey,
|
|
21274
|
-
network: this.config.getNetwork()
|
|
21275
|
-
});
|
|
21276
|
-
if (!newCpfpRefundTx) {
|
|
21277
|
-
throw new ValidationError(
|
|
21278
|
-
"Failed to create refund transactions in extendTimelock"
|
|
21279
|
-
);
|
|
21280
|
-
}
|
|
21281
|
-
const nodeSighash = getSigHashFromTx(newNodeTx, 0, nodeTx.getOutput(0));
|
|
21282
|
-
const directNodeSighash = newDirectNodeTx ? getSigHashFromTx(newDirectNodeTx, 0, nodeTx.getOutput(0)) : void 0;
|
|
21283
|
-
const cpfpRefundSighash = getSigHashFromTx(
|
|
21284
|
-
newCpfpRefundTx,
|
|
21285
|
-
0,
|
|
21286
|
-
newNodeTx.getOutput(0)
|
|
21431
|
+
async createRenewNodeSigningJobs(node, parentNode) {
|
|
21432
|
+
const signingJobs = [];
|
|
21433
|
+
const parentTx = getTxFromRawTxBytes(parentNode.nodeTx);
|
|
21434
|
+
const parentNodeOutput = getTxFromRawTxBytes(parentNode.nodeTx).getOutput(
|
|
21435
|
+
0
|
|
21287
21436
|
);
|
|
21288
|
-
const
|
|
21289
|
-
|
|
21290
|
-
|
|
21291
|
-
signingPublicKey,
|
|
21292
|
-
rawTx: newNodeTx.toBytes(),
|
|
21293
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
21294
|
-
};
|
|
21295
|
-
const newDirectNodeSigningJob = newDirectNodeTx ? {
|
|
21296
|
-
signingPublicKey,
|
|
21297
|
-
rawTx: newDirectNodeTx.toBytes(),
|
|
21298
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
21299
|
-
} : void 0;
|
|
21300
|
-
const newCpfpRefundSigningJob = {
|
|
21301
|
-
signingPublicKey,
|
|
21302
|
-
rawTx: newCpfpRefundTx.toBytes(),
|
|
21303
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
21437
|
+
const unsignedParentNodeOutput = {
|
|
21438
|
+
script: parentNodeOutput.script,
|
|
21439
|
+
amount: parentNodeOutput.amount
|
|
21304
21440
|
};
|
|
21305
|
-
const newDirectRefundSigningJob = newDirectRefundTx ? {
|
|
21306
|
-
signingPublicKey,
|
|
21307
|
-
rawTx: newDirectRefundTx.toBytes(),
|
|
21308
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
21309
|
-
} : void 0;
|
|
21310
|
-
const newDirectFromCpfpRefundSigningJob = newDirectFromCpfpRefundTx ? {
|
|
21311
|
-
signingPublicKey,
|
|
21312
|
-
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
21313
|
-
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment()
|
|
21314
|
-
} : void 0;
|
|
21315
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
21316
|
-
this.config.getCoordinatorAddress()
|
|
21317
|
-
);
|
|
21318
|
-
const response = await sparkClient.extend_leaf_v2({
|
|
21319
|
-
leafId: node.id,
|
|
21320
|
-
ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
21321
|
-
nodeTxSigningJob: getSigningJobProto(newNodeSigningJob),
|
|
21322
|
-
directNodeTxSigningJob: newDirectNodeSigningJob ? getSigningJobProto(newDirectNodeSigningJob) : void 0,
|
|
21323
|
-
refundTxSigningJob: getSigningJobProto(newCpfpRefundSigningJob),
|
|
21324
|
-
directRefundTxSigningJob: newDirectRefundSigningJob ? getSigningJobProto(newDirectRefundSigningJob) : void 0,
|
|
21325
|
-
directFromCpfpRefundTxSigningJob: newDirectFromCpfpRefundSigningJob ? getSigningJobProto(newDirectFromCpfpRefundSigningJob) : void 0
|
|
21326
|
-
});
|
|
21327
|
-
if (!response.nodeTxSigningResult || !response.refundTxSigningResult) {
|
|
21328
|
-
throw new Error("Signing result does not exist");
|
|
21329
|
-
}
|
|
21330
21441
|
const keyDerivation = {
|
|
21331
21442
|
type: "leaf" /* LEAF */,
|
|
21332
21443
|
path: node.id
|
|
21333
21444
|
};
|
|
21334
|
-
const
|
|
21335
|
-
|
|
21445
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
21446
|
+
const { nodeTx: splitNodeTx, directNodeTx: splitNodeDirectTx } = createZeroTimelockNodeTx(parentTx);
|
|
21447
|
+
signingJobs.push({
|
|
21448
|
+
signingPublicKey,
|
|
21449
|
+
rawTx: splitNodeTx.toBytes(),
|
|
21450
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21451
|
+
type: "split",
|
|
21452
|
+
parentTxOut: unsignedParentNodeOutput,
|
|
21453
|
+
leafId: node.id,
|
|
21336
21454
|
keyDerivation,
|
|
21337
|
-
|
|
21338
|
-
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
21339
|
-
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
21340
|
-
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21341
|
-
adaptorPubKey: new Uint8Array()
|
|
21342
|
-
});
|
|
21343
|
-
const nodeSig = await this.config.signer.aggregateFrost({
|
|
21344
|
-
message: nodeSighash,
|
|
21345
|
-
statechainSignatures: response.nodeTxSigningResult.signingResult?.signatureShares,
|
|
21346
|
-
statechainPublicKeys: response.nodeTxSigningResult.signingResult?.publicKeys,
|
|
21347
|
-
verifyingKey: response.nodeTxSigningResult.verifyingKey,
|
|
21348
|
-
statechainCommitments: response.nodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21349
|
-
selfCommitment: newNodeSigningJob.signingNonceCommitment,
|
|
21350
|
-
publicKey: signingPublicKey,
|
|
21351
|
-
selfSignature: nodeUserSig,
|
|
21352
|
-
adaptorPubKey: new Uint8Array()
|
|
21455
|
+
verifyingKey: node.verifyingPublicKey
|
|
21353
21456
|
});
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21457
|
+
if (splitNodeDirectTx) {
|
|
21458
|
+
signingJobs.push({
|
|
21459
|
+
signingPublicKey,
|
|
21460
|
+
rawTx: splitNodeDirectTx.toBytes(),
|
|
21461
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21462
|
+
type: "directSplit",
|
|
21463
|
+
parentTxOut: unsignedParentNodeOutput,
|
|
21464
|
+
leafId: node.id,
|
|
21358
21465
|
keyDerivation,
|
|
21359
|
-
|
|
21360
|
-
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
21361
|
-
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
21362
|
-
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21363
|
-
adaptorPubKey: new Uint8Array()
|
|
21364
|
-
});
|
|
21365
|
-
directNodeSig = await this.config.signer.aggregateFrost({
|
|
21366
|
-
message: directNodeSighash,
|
|
21367
|
-
statechainSignatures: response.directNodeTxSigningResult.signingResult?.signatureShares,
|
|
21368
|
-
statechainPublicKeys: response.directNodeTxSigningResult.signingResult?.publicKeys,
|
|
21369
|
-
verifyingKey: response.directNodeTxSigningResult.verifyingKey,
|
|
21370
|
-
statechainCommitments: response.directNodeTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21371
|
-
selfCommitment: newDirectNodeSigningJob.signingNonceCommitment,
|
|
21372
|
-
publicKey: signingPublicKey,
|
|
21373
|
-
selfSignature: directNodeUserSig,
|
|
21374
|
-
adaptorPubKey: new Uint8Array()
|
|
21466
|
+
verifyingKey: node.verifyingPublicKey
|
|
21375
21467
|
});
|
|
21376
21468
|
}
|
|
21377
|
-
const
|
|
21378
|
-
|
|
21469
|
+
const splitNodeOutput = splitNodeTx.getOutput(0);
|
|
21470
|
+
const splitNodeDirectOutput = splitNodeDirectTx.getOutput(0);
|
|
21471
|
+
if (!splitNodeDirectOutput.amount || !splitNodeDirectOutput.script) {
|
|
21472
|
+
throw new Error("Could not get split node output");
|
|
21473
|
+
}
|
|
21474
|
+
const unsignedSplitNodeOutput = {
|
|
21475
|
+
script: splitNodeDirectOutput.script,
|
|
21476
|
+
amount: splitNodeDirectOutput.amount
|
|
21477
|
+
};
|
|
21478
|
+
const { nodeTx: newNodeTx, directNodeTx: newDirectNodeTx } = createInitialTimelockNodeTx(splitNodeTx);
|
|
21479
|
+
signingJobs.push({
|
|
21480
|
+
signingPublicKey,
|
|
21481
|
+
rawTx: newNodeTx.toBytes(),
|
|
21482
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21483
|
+
type: "node",
|
|
21484
|
+
parentTxOut: splitNodeOutput,
|
|
21485
|
+
leafId: node.id,
|
|
21379
21486
|
keyDerivation,
|
|
21380
|
-
|
|
21381
|
-
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
21382
|
-
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
21383
|
-
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21384
|
-
adaptorPubKey: new Uint8Array()
|
|
21385
|
-
});
|
|
21386
|
-
const cpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
21387
|
-
message: cpfpRefundSighash,
|
|
21388
|
-
statechainSignatures: response.refundTxSigningResult.signingResult?.signatureShares,
|
|
21389
|
-
statechainPublicKeys: response.refundTxSigningResult.signingResult?.publicKeys,
|
|
21390
|
-
verifyingKey: response.refundTxSigningResult.verifyingKey,
|
|
21391
|
-
statechainCommitments: response.refundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21392
|
-
selfCommitment: newCpfpRefundSigningJob.signingNonceCommitment,
|
|
21393
|
-
publicKey: signingPublicKey,
|
|
21394
|
-
selfSignature: cpfpRefundUserSig,
|
|
21395
|
-
adaptorPubKey: new Uint8Array()
|
|
21487
|
+
verifyingKey: node.verifyingPublicKey
|
|
21396
21488
|
});
|
|
21397
|
-
|
|
21398
|
-
|
|
21399
|
-
|
|
21400
|
-
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21406
|
-
adaptorPubKey: new Uint8Array()
|
|
21407
|
-
});
|
|
21408
|
-
directRefundSig = await this.config.signer.aggregateFrost({
|
|
21409
|
-
message: directRefundSighash,
|
|
21410
|
-
statechainSignatures: response.directRefundTxSigningResult.signingResult?.signatureShares,
|
|
21411
|
-
statechainPublicKeys: response.directRefundTxSigningResult.signingResult?.publicKeys,
|
|
21412
|
-
verifyingKey: response.directRefundTxSigningResult.verifyingKey,
|
|
21413
|
-
statechainCommitments: response.directRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21414
|
-
selfCommitment: newDirectRefundSigningJob.signingNonceCommitment,
|
|
21415
|
-
publicKey: signingPublicKey,
|
|
21416
|
-
selfSignature: directRefundUserSig,
|
|
21417
|
-
adaptorPubKey: new Uint8Array()
|
|
21418
|
-
});
|
|
21419
|
-
}
|
|
21420
|
-
let directFromCpfpRefundSig;
|
|
21421
|
-
if (directFromCpfpRefundSighash && newDirectFromCpfpRefundSigningJob && response.directFromCpfpRefundTxSigningResult) {
|
|
21422
|
-
const directFromCpfpRefundUserSig = await this.config.signer.signFrost({
|
|
21423
|
-
message: directFromCpfpRefundSighash,
|
|
21489
|
+
if (newDirectNodeTx) {
|
|
21490
|
+
signingJobs.push({
|
|
21491
|
+
signingPublicKey,
|
|
21492
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
21493
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21494
|
+
type: "directNode",
|
|
21495
|
+
parentTxOut: splitNodeOutput,
|
|
21496
|
+
leafId: node.id,
|
|
21424
21497
|
keyDerivation,
|
|
21425
|
-
|
|
21426
|
-
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
21427
|
-
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
21428
|
-
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21429
|
-
adaptorPubKey: new Uint8Array()
|
|
21430
|
-
});
|
|
21431
|
-
directFromCpfpRefundSig = await this.config.signer.aggregateFrost({
|
|
21432
|
-
message: directFromCpfpRefundSighash,
|
|
21433
|
-
statechainSignatures: response.directFromCpfpRefundTxSigningResult.signingResult?.signatureShares,
|
|
21434
|
-
statechainPublicKeys: response.directFromCpfpRefundTxSigningResult.signingResult?.publicKeys,
|
|
21435
|
-
verifyingKey: response.directFromCpfpRefundTxSigningResult.verifyingKey,
|
|
21436
|
-
statechainCommitments: response.directFromCpfpRefundTxSigningResult.signingResult?.signingNonceCommitments,
|
|
21437
|
-
selfCommitment: newDirectFromCpfpRefundSigningJob.signingNonceCommitment,
|
|
21438
|
-
publicKey: signingPublicKey,
|
|
21439
|
-
selfSignature: directFromCpfpRefundUserSig,
|
|
21440
|
-
adaptorPubKey: new Uint8Array()
|
|
21441
|
-
});
|
|
21442
|
-
}
|
|
21443
|
-
return await sparkClient.finalize_node_signatures_v2({
|
|
21444
|
-
intent: 4 /* EXTEND */,
|
|
21445
|
-
nodeSignatures: [
|
|
21446
|
-
{
|
|
21447
|
-
nodeId: response.leafId,
|
|
21448
|
-
nodeTxSignature: nodeSig,
|
|
21449
|
-
directNodeTxSignature: directNodeSig,
|
|
21450
|
-
refundTxSignature: cpfpRefundSig,
|
|
21451
|
-
directRefundTxSignature: directRefundSig,
|
|
21452
|
-
directFromCpfpRefundTxSignature: directFromCpfpRefundSig
|
|
21453
|
-
}
|
|
21454
|
-
]
|
|
21455
|
-
});
|
|
21456
|
-
}
|
|
21457
|
-
async testonly_expireTimeLockNodeTx(node, parentNode) {
|
|
21458
|
-
return await this.refreshTimelockNodesInternal(node, parentNode, true);
|
|
21459
|
-
}
|
|
21460
|
-
async testonly_expireTimeLockRefundtx(node) {
|
|
21461
|
-
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
21462
|
-
const directNodeTx = node.directTx.length > 0 ? getTxFromRawTxBytes(node.directTx) : void 0;
|
|
21463
|
-
const cpfpRefundTx = getTxFromRawTxBytes(node.refundTx);
|
|
21464
|
-
const currSequence = cpfpRefundTx.getInput(0).sequence || 0;
|
|
21465
|
-
const currTimelock = getCurrentTimelock(currSequence);
|
|
21466
|
-
if (currTimelock <= 100) {
|
|
21467
|
-
throw new ValidationError("Cannot expire timelock below 100", {
|
|
21468
|
-
field: "currTimelock",
|
|
21469
|
-
value: currTimelock,
|
|
21470
|
-
expected: "Timelock greater than 100"
|
|
21498
|
+
verifyingKey: node.verifyingPublicKey
|
|
21471
21499
|
});
|
|
21472
21500
|
}
|
|
21473
|
-
const
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
if (!nodeOutput) {
|
|
21477
|
-
throw Error("Could not get node output");
|
|
21478
|
-
}
|
|
21479
|
-
const keyDerivation = {
|
|
21480
|
-
type: "leaf" /* LEAF */,
|
|
21481
|
-
path: node.id
|
|
21482
|
-
};
|
|
21483
|
-
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
21484
|
-
const cpfpRefundOutPoint = {
|
|
21485
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
|
|
21486
|
-
index: 0
|
|
21487
|
-
};
|
|
21488
|
-
let directRefundOutPoint;
|
|
21489
|
-
if (directNodeTx) {
|
|
21490
|
-
directRefundOutPoint = {
|
|
21491
|
-
txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
|
|
21492
|
-
index: 0
|
|
21493
|
-
};
|
|
21501
|
+
const newCpfpNodeOutput = newNodeTx.getOutput(0);
|
|
21502
|
+
if (!newCpfpNodeOutput) {
|
|
21503
|
+
throw Error("Could not get new cpfp node output");
|
|
21494
21504
|
}
|
|
21505
|
+
const newDirectNodeOutput = newDirectNodeTx?.getOutput(0);
|
|
21495
21506
|
const {
|
|
21496
|
-
cpfpRefundTx:
|
|
21507
|
+
cpfpRefundTx: newRefundTx,
|
|
21497
21508
|
directRefundTx: newDirectRefundTx,
|
|
21498
21509
|
directFromCpfpRefundTx: newDirectFromCpfpRefundTx
|
|
21499
|
-
} =
|
|
21500
|
-
|
|
21501
|
-
|
|
21502
|
-
input: cpfpRefundOutPoint,
|
|
21503
|
-
directInput: directRefundOutPoint,
|
|
21504
|
-
amountSats: nodeOutput.amount,
|
|
21510
|
+
} = createInitialTimelockRefundTxs({
|
|
21511
|
+
nodeTx: newNodeTx,
|
|
21512
|
+
directNodeTx: newDirectNodeTx,
|
|
21505
21513
|
receivingPubkey: signingPublicKey,
|
|
21506
21514
|
network: this.config.getNetwork()
|
|
21507
21515
|
});
|
|
21508
|
-
const signingJobs = [];
|
|
21509
21516
|
signingJobs.push({
|
|
21510
21517
|
signingPublicKey,
|
|
21511
|
-
rawTx:
|
|
21518
|
+
rawTx: newRefundTx.toBytes(),
|
|
21512
21519
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21513
21520
|
type: "cpfp",
|
|
21514
|
-
parentTxOut:
|
|
21521
|
+
parentTxOut: newCpfpNodeOutput,
|
|
21522
|
+
leafId: node.id,
|
|
21523
|
+
keyDerivation,
|
|
21524
|
+
verifyingKey: node.verifyingPublicKey
|
|
21515
21525
|
});
|
|
21516
|
-
|
|
21517
|
-
if (newDirectRefundTx && directNodeTxOut) {
|
|
21526
|
+
if (newDirectRefundTx && newDirectNodeOutput) {
|
|
21518
21527
|
signingJobs.push({
|
|
21519
21528
|
signingPublicKey,
|
|
21520
21529
|
rawTx: newDirectRefundTx.toBytes(),
|
|
21521
21530
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21522
21531
|
type: "direct",
|
|
21523
|
-
parentTxOut:
|
|
21532
|
+
parentTxOut: newDirectNodeOutput,
|
|
21533
|
+
leafId: node.id,
|
|
21534
|
+
keyDerivation,
|
|
21535
|
+
verifyingKey: node.verifyingPublicKey
|
|
21524
21536
|
});
|
|
21525
21537
|
}
|
|
21526
|
-
if (newDirectFromCpfpRefundTx) {
|
|
21538
|
+
if (newDirectFromCpfpRefundTx && newDirectNodeOutput) {
|
|
21527
21539
|
signingJobs.push({
|
|
21528
21540
|
signingPublicKey,
|
|
21529
21541
|
rawTx: newDirectFromCpfpRefundTx.toBytes(),
|
|
21530
21542
|
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21531
21543
|
type: "directFromCpfp",
|
|
21532
|
-
parentTxOut:
|
|
21544
|
+
parentTxOut: newCpfpNodeOutput,
|
|
21545
|
+
leafId: node.id,
|
|
21546
|
+
keyDerivation,
|
|
21547
|
+
verifyingKey: node.verifyingPublicKey
|
|
21533
21548
|
});
|
|
21534
21549
|
}
|
|
21550
|
+
return signingJobs;
|
|
21551
|
+
}
|
|
21552
|
+
async renewZeroTimelockNodeTxn(node) {
|
|
21535
21553
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
21536
21554
|
this.config.getCoordinatorAddress()
|
|
21537
21555
|
);
|
|
21538
|
-
const
|
|
21539
|
-
|
|
21540
|
-
|
|
21541
|
-
|
|
21556
|
+
const signingJobs = await this.createRenewZeroTimelockNodeSigningJobs(node);
|
|
21557
|
+
const statechainCommitments = await sparkClient.get_signing_commitments({
|
|
21558
|
+
nodeIds: [node.id],
|
|
21559
|
+
count: signingJobs.length
|
|
21542
21560
|
});
|
|
21543
|
-
|
|
21544
|
-
|
|
21545
|
-
|
|
21546
|
-
|
|
21547
|
-
|
|
21548
|
-
|
|
21549
|
-
|
|
21550
|
-
let directFromCpfpRefundSignature;
|
|
21551
|
-
for (const [i, signingJob] of signingJobs.entries()) {
|
|
21552
|
-
const signingResult = response.signingResults[i];
|
|
21553
|
-
if (!signingResult) {
|
|
21554
|
-
throw Error("Signing result does not exist");
|
|
21561
|
+
const mappedSigningJobs = signingJobs.map((signingJob, index) => {
|
|
21562
|
+
const signingNonceCommitments = statechainCommitments.signingCommitments[index]?.signingNonceCommitments;
|
|
21563
|
+
if (!signingNonceCommitments) {
|
|
21564
|
+
throw new ValidationError("Signing nonce commitments not found", {
|
|
21565
|
+
field: "signingNonceCommitments",
|
|
21566
|
+
value: signingNonceCommitments
|
|
21567
|
+
});
|
|
21555
21568
|
}
|
|
21556
|
-
|
|
21557
|
-
|
|
21558
|
-
|
|
21559
|
-
|
|
21560
|
-
|
|
21561
|
-
|
|
21562
|
-
|
|
21563
|
-
|
|
21564
|
-
|
|
21565
|
-
|
|
21566
|
-
|
|
21567
|
-
|
|
21568
|
-
|
|
21569
|
-
|
|
21570
|
-
|
|
21571
|
-
|
|
21572
|
-
|
|
21573
|
-
|
|
21574
|
-
selfCommitment: signingJob.signingNonceCommitment,
|
|
21575
|
-
publicKey: signingPublicKey,
|
|
21576
|
-
selfSignature: userSignature,
|
|
21577
|
-
adaptorPubKey: new Uint8Array()
|
|
21578
|
-
});
|
|
21579
|
-
if (signingJob.type === "cpfp") {
|
|
21580
|
-
cpfpRefundSignature = signature;
|
|
21581
|
-
} else if (signingJob.type === "direct") {
|
|
21582
|
-
directRefundSignature = signature;
|
|
21583
|
-
} else if (signingJob.type === "directFromCpfp") {
|
|
21584
|
-
directFromCpfpRefundSignature = signature;
|
|
21569
|
+
return {
|
|
21570
|
+
...signingJob,
|
|
21571
|
+
signingNonceCommitments
|
|
21572
|
+
};
|
|
21573
|
+
});
|
|
21574
|
+
const userSignedTxSigningJobs = await this.signingService.signSigningJobs(mappedSigningJobs);
|
|
21575
|
+
const renewZeroTimelockNodeSigningJob = {
|
|
21576
|
+
nodeTxSigningJob: userSignedTxSigningJobs.get("node"),
|
|
21577
|
+
refundTxSigningJob: userSignedTxSigningJobs.get("cpfp"),
|
|
21578
|
+
directNodeTxSigningJob: userSignedTxSigningJobs.get("directNode"),
|
|
21579
|
+
directRefundTxSigningJob: void 0,
|
|
21580
|
+
directFromCpfpRefundTxSigningJob: userSignedTxSigningJobs.get("directFromCpfp")
|
|
21581
|
+
};
|
|
21582
|
+
const response = await sparkClient.renew_leaf({
|
|
21583
|
+
leafId: node.id,
|
|
21584
|
+
signingJobs: {
|
|
21585
|
+
$case: "renewNodeZeroTimelockSigningJob",
|
|
21586
|
+
renewNodeZeroTimelockSigningJob: renewZeroTimelockNodeSigningJob
|
|
21585
21587
|
}
|
|
21588
|
+
});
|
|
21589
|
+
if (response.renewResult?.$case !== "renewNodeZeroTimelockResult" || !response.renewResult?.renewNodeZeroTimelockResult.node) {
|
|
21590
|
+
throw new ValidationError("Unexpected renew result", {
|
|
21591
|
+
field: "renewResult",
|
|
21592
|
+
value: response.renewResult
|
|
21593
|
+
});
|
|
21586
21594
|
}
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21594
|
-
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21595
|
+
return response.renewResult.renewNodeZeroTimelockResult.node;
|
|
21596
|
+
}
|
|
21597
|
+
async createRenewZeroTimelockNodeSigningJobs(node) {
|
|
21598
|
+
const signingJobs = [];
|
|
21599
|
+
const keyDerivation = {
|
|
21600
|
+
type: "leaf" /* LEAF */,
|
|
21601
|
+
path: node.id
|
|
21602
|
+
};
|
|
21603
|
+
const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
21604
|
+
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
21605
|
+
const { nodeTx: newNodeTx, directNodeTx: newDirectNodeTx } = createZeroTimelockNodeTx(nodeTx);
|
|
21606
|
+
signingJobs.push({
|
|
21607
|
+
signingPublicKey,
|
|
21608
|
+
rawTx: newNodeTx.toBytes(),
|
|
21609
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21610
|
+
type: "node",
|
|
21611
|
+
parentTxOut: nodeTx.getOutput(0),
|
|
21612
|
+
leafId: node.id,
|
|
21613
|
+
keyDerivation,
|
|
21614
|
+
verifyingKey: node.verifyingPublicKey
|
|
21599
21615
|
});
|
|
21600
|
-
|
|
21616
|
+
signingJobs.push({
|
|
21617
|
+
signingPublicKey,
|
|
21618
|
+
rawTx: newDirectNodeTx.toBytes(),
|
|
21619
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21620
|
+
type: "directNode",
|
|
21621
|
+
parentTxOut: nodeTx.getOutput(0),
|
|
21622
|
+
leafId: node.id,
|
|
21623
|
+
keyDerivation,
|
|
21624
|
+
verifyingKey: node.verifyingPublicKey
|
|
21625
|
+
});
|
|
21626
|
+
const { cpfpRefundTx, directFromCpfpRefundTx } = createInitialTimelockRefundTxs({
|
|
21627
|
+
nodeTx: newNodeTx,
|
|
21628
|
+
directNodeTx: newDirectNodeTx,
|
|
21629
|
+
receivingPubkey: signingPublicKey,
|
|
21630
|
+
network: this.config.getNetwork()
|
|
21631
|
+
});
|
|
21632
|
+
signingJobs.push({
|
|
21633
|
+
signingPublicKey,
|
|
21634
|
+
rawTx: cpfpRefundTx.toBytes(),
|
|
21635
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21636
|
+
type: "cpfp",
|
|
21637
|
+
parentTxOut: newNodeTx.getOutput(0),
|
|
21638
|
+
leafId: node.id,
|
|
21639
|
+
keyDerivation,
|
|
21640
|
+
verifyingKey: node.verifyingPublicKey
|
|
21641
|
+
});
|
|
21642
|
+
if (!directFromCpfpRefundTx) {
|
|
21643
|
+
throw new Error("Could not create direct refund transactions");
|
|
21644
|
+
}
|
|
21645
|
+
signingJobs.push({
|
|
21646
|
+
signingPublicKey,
|
|
21647
|
+
rawTx: directFromCpfpRefundTx.toBytes(),
|
|
21648
|
+
signingNonceCommitment: await this.config.signer.getRandomSigningCommitment(),
|
|
21649
|
+
type: "directFromCpfp",
|
|
21650
|
+
parentTxOut: newNodeTx.getOutput(0),
|
|
21651
|
+
leafId: node.id,
|
|
21652
|
+
keyDerivation,
|
|
21653
|
+
verifyingKey: node.verifyingPublicKey
|
|
21654
|
+
});
|
|
21655
|
+
return signingJobs;
|
|
21601
21656
|
}
|
|
21602
21657
|
};
|
|
21603
21658
|
|
|
@@ -21639,71 +21694,6 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
21639
21694
|
directFromCpfpSignaturesMap
|
|
21640
21695
|
};
|
|
21641
21696
|
}
|
|
21642
|
-
createConnectorRefundTransactions(sequence, directSequence, cpfpNodeOutPoint, directNodeOutPoint, connectorOutput, amountSats, receiverPubKey) {
|
|
21643
|
-
const cpfpRefundTx = new import_btc_signer3.Transaction();
|
|
21644
|
-
if (!cpfpNodeOutPoint.txid || cpfpNodeOutPoint.index === void 0) {
|
|
21645
|
-
throw new ValidationError("Invalid CPFP node outpoint", {
|
|
21646
|
-
field: "cpfpNodeOutPoint",
|
|
21647
|
-
value: { txid: cpfpNodeOutPoint.txid, index: cpfpNodeOutPoint.index },
|
|
21648
|
-
expected: "Both txid and index must be defined"
|
|
21649
|
-
});
|
|
21650
|
-
}
|
|
21651
|
-
cpfpRefundTx.addInput({
|
|
21652
|
-
txid: cpfpNodeOutPoint.txid,
|
|
21653
|
-
index: cpfpNodeOutPoint.index,
|
|
21654
|
-
sequence
|
|
21655
|
-
});
|
|
21656
|
-
cpfpRefundTx.addInput(connectorOutput);
|
|
21657
|
-
const receiverScript = getP2TRScriptFromPublicKey(
|
|
21658
|
-
receiverPubKey,
|
|
21659
|
-
this.config.getNetwork()
|
|
21660
|
-
);
|
|
21661
|
-
cpfpRefundTx.addOutput({
|
|
21662
|
-
script: receiverScript,
|
|
21663
|
-
amount: amountSats
|
|
21664
|
-
});
|
|
21665
|
-
let directRefundTx;
|
|
21666
|
-
let directFromCpfpRefundTx;
|
|
21667
|
-
if (directNodeOutPoint) {
|
|
21668
|
-
if (!directNodeOutPoint.txid || directNodeOutPoint.index === void 0) {
|
|
21669
|
-
throw new ValidationError("Invalid direct node outpoint", {
|
|
21670
|
-
field: "directNodeOutPoint",
|
|
21671
|
-
value: {
|
|
21672
|
-
txid: directNodeOutPoint.txid,
|
|
21673
|
-
index: directNodeOutPoint.index
|
|
21674
|
-
},
|
|
21675
|
-
expected: "Both txid and index must be defined"
|
|
21676
|
-
});
|
|
21677
|
-
}
|
|
21678
|
-
directRefundTx = new import_btc_signer3.Transaction();
|
|
21679
|
-
directRefundTx.addInput({
|
|
21680
|
-
txid: directNodeOutPoint.txid,
|
|
21681
|
-
index: directNodeOutPoint.index,
|
|
21682
|
-
sequence: directSequence
|
|
21683
|
-
});
|
|
21684
|
-
directRefundTx.addInput(connectorOutput);
|
|
21685
|
-
directRefundTx.addOutput({
|
|
21686
|
-
script: receiverScript,
|
|
21687
|
-
amount: maybeApplyFee(amountSats)
|
|
21688
|
-
});
|
|
21689
|
-
directFromCpfpRefundTx = new import_btc_signer3.Transaction();
|
|
21690
|
-
directFromCpfpRefundTx.addInput({
|
|
21691
|
-
txid: cpfpNodeOutPoint.txid,
|
|
21692
|
-
index: cpfpNodeOutPoint.index,
|
|
21693
|
-
sequence: directSequence
|
|
21694
|
-
});
|
|
21695
|
-
directFromCpfpRefundTx.addInput(connectorOutput);
|
|
21696
|
-
directFromCpfpRefundTx.addOutput({
|
|
21697
|
-
script: receiverScript,
|
|
21698
|
-
amount: maybeApplyFee(amountSats)
|
|
21699
|
-
});
|
|
21700
|
-
}
|
|
21701
|
-
return {
|
|
21702
|
-
cpfpRefundTx,
|
|
21703
|
-
directRefundTx,
|
|
21704
|
-
directFromCpfpRefundTx
|
|
21705
|
-
};
|
|
21706
|
-
}
|
|
21707
21697
|
async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey, transferId) {
|
|
21708
21698
|
if (leaves.length !== connectorOutputs.length) {
|
|
21709
21699
|
throw new ValidationError(
|
|
@@ -21737,29 +21727,39 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
21737
21727
|
expected: "Valid connector output"
|
|
21738
21728
|
});
|
|
21739
21729
|
}
|
|
21730
|
+
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
21731
|
+
let directNodeTx;
|
|
21732
|
+
if (leaf.leaf.directTx.length > 0) {
|
|
21733
|
+
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
21734
|
+
}
|
|
21740
21735
|
const currentRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
21741
|
-
|
|
21742
|
-
|
|
21736
|
+
if (!currentRefundTx) {
|
|
21737
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
21738
|
+
field: "currentRefundTx",
|
|
21739
|
+
value: currentRefundTx,
|
|
21740
|
+
expected: "Non-null refund transaction"
|
|
21741
|
+
});
|
|
21742
|
+
}
|
|
21743
|
+
const currentSequence = currentRefundTx.getInput(0).sequence;
|
|
21744
|
+
if (!currentSequence) {
|
|
21743
21745
|
throw new ValidationError("Invalid refund transaction", {
|
|
21744
21746
|
field: "sequence",
|
|
21745
21747
|
value: currentRefundTx.getInput(0),
|
|
21746
21748
|
expected: "Non-null sequence"
|
|
21747
21749
|
});
|
|
21748
21750
|
}
|
|
21749
|
-
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
21750
21751
|
let currentDirectRefundTx;
|
|
21751
21752
|
if (leaf.leaf.directRefundTx.length > 0) {
|
|
21752
21753
|
currentDirectRefundTx = getTxFromRawTxBytes(leaf.leaf.directRefundTx);
|
|
21753
21754
|
}
|
|
21754
|
-
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } =
|
|
21755
|
-
|
|
21756
|
-
|
|
21757
|
-
|
|
21758
|
-
currentDirectRefundTx?.getInput(0),
|
|
21755
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createConnectorRefundTxs({
|
|
21756
|
+
nodeTx,
|
|
21757
|
+
directNodeTx,
|
|
21758
|
+
sequence: currentSequence,
|
|
21759
21759
|
connectorOutput,
|
|
21760
|
-
|
|
21761
|
-
|
|
21762
|
-
);
|
|
21760
|
+
receivingPubkey: receiverPubKey,
|
|
21761
|
+
network: this.config.getNetwork()
|
|
21762
|
+
});
|
|
21763
21763
|
const signingNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
21764
21764
|
const directSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
21765
21765
|
const directFromCpfpSigningNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
@@ -21865,13 +21865,13 @@ var CoopExitService = class extends BaseTransferService {
|
|
|
21865
21865
|
// src/services/deposit.ts
|
|
21866
21866
|
var import_secp256k14 = require("@noble/curves/secp256k1");
|
|
21867
21867
|
var import_sha26 = require("@noble/hashes/sha2");
|
|
21868
|
-
var
|
|
21869
|
-
var
|
|
21870
|
-
var
|
|
21868
|
+
var import_utils7 = require("@noble/hashes/utils");
|
|
21869
|
+
var import_btc_signer2 = require("@scure/btc-signer");
|
|
21870
|
+
var import_utils8 = require("@scure/btc-signer/utils");
|
|
21871
21871
|
|
|
21872
21872
|
// src/utils/keys.ts
|
|
21873
21873
|
var import_secp256k13 = require("@noble/curves/secp256k1");
|
|
21874
|
-
var
|
|
21874
|
+
var import_utils6 = require("@noble/curves/utils");
|
|
21875
21875
|
function addPublicKeys(a, b) {
|
|
21876
21876
|
if (a.length !== 33 || b.length !== 33) {
|
|
21877
21877
|
throw new ValidationError("Public keys must be 33 bytes", {
|
|
@@ -21928,7 +21928,7 @@ function addPrivateKeys(a, b) {
|
|
|
21928
21928
|
const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
|
|
21929
21929
|
const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
|
|
21930
21930
|
const sum2 = (privA + privB) % import_secp256k13.secp256k1.CURVE.n;
|
|
21931
|
-
return (0,
|
|
21931
|
+
return (0, import_utils6.numberToBytesBE)(sum2, 32);
|
|
21932
21932
|
}
|
|
21933
21933
|
function subtractPrivateKeys(a, b) {
|
|
21934
21934
|
if (a.length !== 32 || b.length !== 32) {
|
|
@@ -21941,7 +21941,7 @@ function subtractPrivateKeys(a, b) {
|
|
|
21941
21941
|
const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
|
|
21942
21942
|
const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
|
|
21943
21943
|
const sum2 = (import_secp256k13.secp256k1.CURVE.n - privB + privA) % import_secp256k13.secp256k1.CURVE.n;
|
|
21944
|
-
return (0,
|
|
21944
|
+
return (0, import_utils6.numberToBytesBE)(sum2, 32);
|
|
21945
21945
|
}
|
|
21946
21946
|
function sumOfPrivateKeys(keys) {
|
|
21947
21947
|
return keys.reduce((sum2, key) => {
|
|
@@ -22008,7 +22008,7 @@ var DepositService = class {
|
|
|
22008
22008
|
operatorPubkey,
|
|
22009
22009
|
address.address
|
|
22010
22010
|
);
|
|
22011
|
-
const taprootKey = (0,
|
|
22011
|
+
const taprootKey = (0, import_btc_signer2.p2tr)(
|
|
22012
22012
|
operatorPubkey.slice(1, 33),
|
|
22013
22013
|
void 0,
|
|
22014
22014
|
getNetwork(this.config.getNetwork())
|
|
@@ -22032,7 +22032,7 @@ var DepositService = class {
|
|
|
22032
22032
|
if (operator.identifier === this.config.getCoordinatorIdentifier() && !verifyCoordinatorProof) {
|
|
22033
22033
|
continue;
|
|
22034
22034
|
}
|
|
22035
|
-
const operatorPubkey2 = (0,
|
|
22035
|
+
const operatorPubkey2 = (0, import_utils7.hexToBytes)(operator.identityPublicKey);
|
|
22036
22036
|
const operatorSig = address.depositAddressProof.addressSignatures[operator.identifier];
|
|
22037
22037
|
if (!operatorSig) {
|
|
22038
22038
|
throw new ValidationError("Operator signature not found", {
|
|
@@ -22151,38 +22151,18 @@ var DepositService = class {
|
|
|
22151
22151
|
expected: "Valid output index"
|
|
22152
22152
|
});
|
|
22153
22153
|
}
|
|
22154
|
-
const
|
|
22155
|
-
|
|
22156
|
-
|
|
22157
|
-
throw new ValidationError("No script or amount found in deposit tx", {
|
|
22158
|
-
field: "output",
|
|
22159
|
-
value: output,
|
|
22160
|
-
expected: "Output with script and amount"
|
|
22161
|
-
});
|
|
22162
|
-
}
|
|
22163
|
-
const depositOutPoint = {
|
|
22164
|
-
txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
|
|
22165
|
-
index: vout
|
|
22166
|
-
};
|
|
22167
|
-
const depositTxOut = {
|
|
22168
|
-
script,
|
|
22169
|
-
amount
|
|
22170
|
-
};
|
|
22171
|
-
const [cpfpRootTx, directRootTx] = createRootTx(
|
|
22172
|
-
depositOutPoint,
|
|
22173
|
-
depositTxOut
|
|
22154
|
+
const { nodeTx: cpfpRootTx, directNodeTx: directRootTx } = createRootNodeTx(
|
|
22155
|
+
depositTx,
|
|
22156
|
+
vout
|
|
22174
22157
|
);
|
|
22175
22158
|
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
22176
22159
|
const directRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
22177
22160
|
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
22178
22161
|
const directRootTxSighash = getSigHashFromTx(directRootTx, 0, output);
|
|
22179
22162
|
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
22180
|
-
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } =
|
|
22181
|
-
|
|
22182
|
-
|
|
22183
|
-
input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
22184
|
-
directInput: { txid: (0, import_utils6.hexToBytes)(getTxId(directRootTx)), index: 0 },
|
|
22185
|
-
amountSats: amount,
|
|
22163
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createInitialTimelockRefundTxs({
|
|
22164
|
+
nodeTx: cpfpRootTx,
|
|
22165
|
+
directNodeTx: directRootTx,
|
|
22186
22166
|
receivingPubkey: signingPubKey,
|
|
22187
22167
|
network: this.config.getNetwork()
|
|
22188
22168
|
});
|
|
@@ -22311,7 +22291,7 @@ var DepositService = class {
|
|
|
22311
22291
|
}
|
|
22312
22292
|
);
|
|
22313
22293
|
}
|
|
22314
|
-
if (!(0,
|
|
22294
|
+
if (!(0, import_utils8.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
22315
22295
|
throw new ValidationError("Verifying key mismatch", {
|
|
22316
22296
|
field: "verifyingKey",
|
|
22317
22297
|
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
@@ -22474,22 +22454,12 @@ var DepositService = class {
|
|
|
22474
22454
|
expected: "Output with script and amount"
|
|
22475
22455
|
});
|
|
22476
22456
|
}
|
|
22477
|
-
const
|
|
22478
|
-
txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
|
|
22479
|
-
index: vout
|
|
22480
|
-
};
|
|
22481
|
-
const depositTxOut = {
|
|
22482
|
-
script,
|
|
22483
|
-
amount
|
|
22484
|
-
};
|
|
22485
|
-
const [cpfpRootTx, _] = createRootTx(depositOutPoint, depositTxOut);
|
|
22457
|
+
const { nodeTx: cpfpRootTx } = createRootNodeTx(depositTx, vout);
|
|
22486
22458
|
const cpfpRootNonceCommitment = await this.config.signer.getRandomSigningCommitment();
|
|
22487
22459
|
const cpfpRootTxSighash = getSigHashFromTx(cpfpRootTx, 0, output);
|
|
22488
22460
|
const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
|
|
22489
|
-
const { cpfpRefundTx } =
|
|
22490
|
-
|
|
22491
|
-
input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
|
|
22492
|
-
amountSats: amount,
|
|
22461
|
+
const { cpfpRefundTx } = createInitialTimelockRefundTxs({
|
|
22462
|
+
nodeTx: cpfpRootTx,
|
|
22493
22463
|
receivingPubkey: signingPubKey,
|
|
22494
22464
|
network: this.config.getNetwork()
|
|
22495
22465
|
});
|
|
@@ -22558,7 +22528,7 @@ var DepositService = class {
|
|
|
22558
22528
|
}
|
|
22559
22529
|
);
|
|
22560
22530
|
}
|
|
22561
|
-
if (!(0,
|
|
22531
|
+
if (!(0, import_utils8.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
|
|
22562
22532
|
throw new ValidationError("Verifying key mismatch", {
|
|
22563
22533
|
field: "verifyingKey",
|
|
22564
22534
|
value: treeResp.rootNodeSignatureShares.verifyingKey,
|
|
@@ -22634,7 +22604,7 @@ var DepositService = class {
|
|
|
22634
22604
|
|
|
22635
22605
|
// src/services/lightning.ts
|
|
22636
22606
|
var import_secp256k15 = require("@noble/curves/secp256k1");
|
|
22637
|
-
var
|
|
22607
|
+
var import_utils9 = require("@noble/curves/utils");
|
|
22638
22608
|
var import_sha27 = require("@noble/hashes/sha2");
|
|
22639
22609
|
var import_uuidv73 = require("uuidv7");
|
|
22640
22610
|
|
|
@@ -22719,8 +22689,8 @@ var LightningService = class {
|
|
|
22719
22689
|
}) {
|
|
22720
22690
|
const crypto = getCrypto();
|
|
22721
22691
|
const randBytes = crypto.getRandomValues(new Uint8Array(32));
|
|
22722
|
-
const preimage = (0,
|
|
22723
|
-
(0,
|
|
22692
|
+
const preimage = (0, import_utils9.numberToBytesBE)(
|
|
22693
|
+
(0, import_utils9.bytesToNumberBE)(randBytes) % import_secp256k15.secp256k1.CURVE.n,
|
|
22724
22694
|
32
|
|
22725
22695
|
);
|
|
22726
22696
|
return await this.createLightningInvoiceWithPreImage({
|
|
@@ -22775,12 +22745,12 @@ var LightningService = class {
|
|
|
22775
22745
|
const sparkClient = await this.connectionManager.createSparkClient(
|
|
22776
22746
|
operator.address
|
|
22777
22747
|
);
|
|
22778
|
-
const userIdentityPublicKey = receiverIdentityPubkey ? (0,
|
|
22748
|
+
const userIdentityPublicKey = receiverIdentityPubkey ? (0, import_utils9.hexToBytes)(receiverIdentityPubkey) : await this.config.signer.getIdentityPublicKey();
|
|
22779
22749
|
try {
|
|
22780
22750
|
await sparkClient.store_preimage_share({
|
|
22781
22751
|
paymentHash,
|
|
22782
22752
|
preimageShare: {
|
|
22783
|
-
secretShare: (0,
|
|
22753
|
+
secretShare: (0, import_utils9.numberToBytesBE)(share.share, 32),
|
|
22784
22754
|
proofs: share.proofs
|
|
22785
22755
|
},
|
|
22786
22756
|
threshold: this.config.getThreshold(),
|
|
@@ -22997,14 +22967,14 @@ var LightningService = class {
|
|
|
22997
22967
|
};
|
|
22998
22968
|
|
|
22999
22969
|
// src/services/token-transactions.ts
|
|
23000
|
-
var
|
|
23001
|
-
var
|
|
22970
|
+
var import_utils13 = require("@noble/curves/utils");
|
|
22971
|
+
var import_utils14 = require("@noble/hashes/utils");
|
|
23002
22972
|
|
|
23003
22973
|
// src/utils/address.ts
|
|
23004
22974
|
var import_wire5 = require("@bufbuild/protobuf/wire");
|
|
23005
22975
|
var import_secp256k16 = require("@noble/curves/secp256k1");
|
|
23006
|
-
var
|
|
23007
|
-
var
|
|
22976
|
+
var import_utils10 = require("@noble/curves/utils");
|
|
22977
|
+
var import_utils11 = require("@noble/hashes/utils");
|
|
23008
22978
|
var import_base3 = require("@scure/base");
|
|
23009
22979
|
var import_uuidv74 = require("uuidv7");
|
|
23010
22980
|
|
|
@@ -23196,7 +23166,7 @@ function encodeSparkAddress(payload) {
|
|
|
23196
23166
|
function encodeSparkAddressWithSignature(payload, signature) {
|
|
23197
23167
|
try {
|
|
23198
23168
|
isValidPublicKey(payload.identityPublicKey);
|
|
23199
|
-
const identityPublicKey = (0,
|
|
23169
|
+
const identityPublicKey = (0, import_utils11.hexToBytes)(payload.identityPublicKey);
|
|
23200
23170
|
let sparkInvoiceFields;
|
|
23201
23171
|
if (payload.sparkInvoiceFields) {
|
|
23202
23172
|
validateSparkInvoiceFields(payload.sparkInvoiceFields);
|
|
@@ -23240,8 +23210,8 @@ function decodeSparkAddress(address, network) {
|
|
|
23240
23210
|
const decoded = bech32mDecode(address);
|
|
23241
23211
|
const payload = SparkAddress.decode(import_base3.bech32m.fromWords(decoded.words));
|
|
23242
23212
|
const { identityPublicKey, sparkInvoiceFields, signature } = payload;
|
|
23243
|
-
const identityPubkeyHex = (0,
|
|
23244
|
-
const signatureHex = signature ? (0,
|
|
23213
|
+
const identityPubkeyHex = (0, import_utils11.bytesToHex)(identityPublicKey);
|
|
23214
|
+
const signatureHex = signature ? (0, import_utils11.bytesToHex)(signature) : void 0;
|
|
23245
23215
|
isValidPublicKey(identityPubkeyHex);
|
|
23246
23216
|
return {
|
|
23247
23217
|
identityPublicKey: identityPubkeyHex,
|
|
@@ -23251,10 +23221,10 @@ function decodeSparkAddress(address, network) {
|
|
|
23251
23221
|
id: import_uuidv74.UUID.ofInner(sparkInvoiceFields.id).toString(),
|
|
23252
23222
|
paymentType: sparkInvoiceFields.paymentType ? sparkInvoiceFields.paymentType.$case === "tokensPayment" ? {
|
|
23253
23223
|
type: "tokens",
|
|
23254
|
-
tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0,
|
|
23224
|
+
tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0, import_utils11.bytesToHex)(
|
|
23255
23225
|
sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier
|
|
23256
23226
|
) : void 0,
|
|
23257
|
-
amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0,
|
|
23227
|
+
amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0, import_utils10.bytesToNumberBE)(
|
|
23258
23228
|
sparkInvoiceFields.paymentType.tokensPayment.amount
|
|
23259
23229
|
) : void 0
|
|
23260
23230
|
} : sparkInvoiceFields.paymentType.$case === "satsPayment" ? {
|
|
@@ -23262,7 +23232,7 @@ function decodeSparkAddress(address, network) {
|
|
|
23262
23232
|
amount: sparkInvoiceFields.paymentType.satsPayment.amount
|
|
23263
23233
|
} : void 0 : void 0,
|
|
23264
23234
|
memo: sparkInvoiceFields.memo,
|
|
23265
|
-
senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0,
|
|
23235
|
+
senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0, import_utils11.bytesToHex)(sparkInvoiceFields.senderPublicKey) : void 0,
|
|
23266
23236
|
expiryTime: sparkInvoiceFields.expiryTime
|
|
23267
23237
|
},
|
|
23268
23238
|
signature: signatureHex
|
|
@@ -23363,7 +23333,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
|
|
|
23363
23333
|
}
|
|
23364
23334
|
if (senderPublicKey) {
|
|
23365
23335
|
try {
|
|
23366
|
-
isValidPublicKey((0,
|
|
23336
|
+
isValidPublicKey((0, import_utils11.bytesToHex)(senderPublicKey));
|
|
23367
23337
|
} catch (error) {
|
|
23368
23338
|
throw new ValidationError(
|
|
23369
23339
|
"Invalid sender public key",
|
|
@@ -23414,7 +23384,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
|
|
|
23414
23384
|
value: tokensAmount
|
|
23415
23385
|
});
|
|
23416
23386
|
}
|
|
23417
|
-
const tokensAmountBigInt = (0,
|
|
23387
|
+
const tokensAmountBigInt = (0, import_utils10.bytesToNumberBE)(tokensAmount);
|
|
23418
23388
|
if (tokensAmountBigInt < 0 || tokensAmountBigInt > MAX_UINT128) {
|
|
23419
23389
|
throw new ValidationError(
|
|
23420
23390
|
"Asset amount must be between 0 and MAX_UINT128",
|
|
@@ -27705,11 +27675,11 @@ function validateTokenTransaction(finalTokenTransaction, partialTokenTransaction
|
|
|
27705
27675
|
}
|
|
27706
27676
|
|
|
27707
27677
|
// src/utils/token-transactions.ts
|
|
27708
|
-
var
|
|
27678
|
+
var import_utils12 = require("@noble/curves/utils");
|
|
27709
27679
|
function sumAvailableTokens(outputs) {
|
|
27710
27680
|
try {
|
|
27711
27681
|
return outputs.reduce(
|
|
27712
|
-
(sum2, output) => sum2 + BigInt((0,
|
|
27682
|
+
(sum2, output) => sum2 + BigInt((0, import_utils12.bytesToNumberBE)(output.output.tokenAmount)),
|
|
27713
27683
|
BigInt(0)
|
|
27714
27684
|
);
|
|
27715
27685
|
} catch (error) {
|
|
@@ -27740,7 +27710,7 @@ function filterTokenBalanceForTokenIdentifier(tokenBalances, tokenIdentifier) {
|
|
|
27740
27710
|
}
|
|
27741
27711
|
const tokenIdentifierBytes = decodeBech32mTokenIdentifier(tokenIdentifier).tokenIdentifier;
|
|
27742
27712
|
const tokenBalance = [...tokenBalances.entries()].find(
|
|
27743
|
-
([, info]) => (0,
|
|
27713
|
+
([, info]) => (0, import_utils12.equalBytes)(info.tokenMetadata.rawTokenIdentifier, tokenIdentifierBytes)
|
|
27744
27714
|
);
|
|
27745
27715
|
if (!tokenBalance) {
|
|
27746
27716
|
return {
|
|
@@ -27834,14 +27804,14 @@ var TokenTransactionService = class {
|
|
|
27834
27804
|
}
|
|
27835
27805
|
if (receiverAddress.sparkInvoiceFields) {
|
|
27836
27806
|
return {
|
|
27837
|
-
receiverPublicKey: (0,
|
|
27807
|
+
receiverPublicKey: (0, import_utils14.hexToBytes)(receiverAddress.identityPublicKey),
|
|
27838
27808
|
rawTokenIdentifier,
|
|
27839
27809
|
tokenAmount: transfer.tokenAmount,
|
|
27840
27810
|
sparkInvoice: transfer.receiverSparkAddress
|
|
27841
27811
|
};
|
|
27842
27812
|
}
|
|
27843
27813
|
return {
|
|
27844
|
-
receiverPublicKey: (0,
|
|
27814
|
+
receiverPublicKey: (0, import_utils14.hexToBytes)(receiverAddress.identityPublicKey),
|
|
27845
27815
|
rawTokenIdentifier,
|
|
27846
27816
|
tokenAmount: transfer.tokenAmount
|
|
27847
27817
|
};
|
|
@@ -27871,7 +27841,7 @@ var TokenTransactionService = class {
|
|
|
27871
27841
|
(output) => ({
|
|
27872
27842
|
ownerPublicKey: output.receiverPublicKey,
|
|
27873
27843
|
tokenIdentifier: output.rawTokenIdentifier,
|
|
27874
|
-
tokenAmount: (0,
|
|
27844
|
+
tokenAmount: (0, import_utils13.numberToBytesBE)(output.tokenAmount, 16)
|
|
27875
27845
|
})
|
|
27876
27846
|
);
|
|
27877
27847
|
if (availableTokenAmount > totalRequestedAmount) {
|
|
@@ -27880,7 +27850,7 @@ var TokenTransactionService = class {
|
|
|
27880
27850
|
tokenOutputs.push({
|
|
27881
27851
|
ownerPublicKey: await this.config.signer.getIdentityPublicKey(),
|
|
27882
27852
|
tokenIdentifier: firstTokenIdentifierBytes,
|
|
27883
|
-
tokenAmount: (0,
|
|
27853
|
+
tokenAmount: (0, import_utils13.numberToBytesBE)(changeAmount, 16)
|
|
27884
27854
|
});
|
|
27885
27855
|
}
|
|
27886
27856
|
return {
|
|
@@ -27907,7 +27877,7 @@ var TokenTransactionService = class {
|
|
|
27907
27877
|
for (const [_, operator] of Object.entries(
|
|
27908
27878
|
this.config.getSigningOperators()
|
|
27909
27879
|
)) {
|
|
27910
|
-
operatorKeys.push((0,
|
|
27880
|
+
operatorKeys.push((0, import_utils14.hexToBytes)(operator.identityPublicKey));
|
|
27911
27881
|
}
|
|
27912
27882
|
return operatorKeys;
|
|
27913
27883
|
}
|
|
@@ -27924,7 +27894,7 @@ var TokenTransactionService = class {
|
|
|
27924
27894
|
finalTokenTransactionHash,
|
|
27925
27895
|
signingOperators
|
|
27926
27896
|
);
|
|
27927
|
-
return (0,
|
|
27897
|
+
return (0, import_utils13.bytesToHex)(finalTokenTransactionHash);
|
|
27928
27898
|
}
|
|
27929
27899
|
async startTokenTransaction(tokenTransaction, signingOperators, outputsToSpendSigningPublicKeys, outputsToSpendCommitments) {
|
|
27930
27900
|
const sparkClient = await this.connectionManager.createSparkTokenClient(
|
|
@@ -28099,10 +28069,10 @@ var TokenTransactionService = class {
|
|
|
28099
28069
|
});
|
|
28100
28070
|
}
|
|
28101
28071
|
for (const ownerPublicKey of ownerPublicKeys) {
|
|
28102
|
-
isValidPublicKey((0,
|
|
28072
|
+
isValidPublicKey((0, import_utils13.bytesToHex)(ownerPublicKey));
|
|
28103
28073
|
}
|
|
28104
28074
|
for (const issuerPublicKey of issuerPublicKeys) {
|
|
28105
|
-
isValidPublicKey((0,
|
|
28075
|
+
isValidPublicKey((0, import_utils13.bytesToHex)(issuerPublicKey));
|
|
28106
28076
|
}
|
|
28107
28077
|
for (const tokenIdentifier of tokenIdentifiers) {
|
|
28108
28078
|
if (tokenIdentifier.length !== 32) {
|
|
@@ -28170,8 +28140,8 @@ var TokenTransactionService = class {
|
|
|
28170
28140
|
this.config.getCoordinatorAddress()
|
|
28171
28141
|
);
|
|
28172
28142
|
let queryParams = {
|
|
28173
|
-
issuerPublicKeys: issuerPublicKeys?.map(
|
|
28174
|
-
ownerPublicKeys: ownerPublicKeys?.map(
|
|
28143
|
+
issuerPublicKeys: issuerPublicKeys?.map(import_utils14.hexToBytes),
|
|
28144
|
+
ownerPublicKeys: ownerPublicKeys?.map(import_utils14.hexToBytes),
|
|
28175
28145
|
tokenIdentifiers: tokenIdentifiers?.map((identifier) => {
|
|
28176
28146
|
const { tokenIdentifier } = decodeBech32mTokenIdentifier(
|
|
28177
28147
|
identifier,
|
|
@@ -28179,7 +28149,7 @@ var TokenTransactionService = class {
|
|
|
28179
28149
|
);
|
|
28180
28150
|
return tokenIdentifier;
|
|
28181
28151
|
}),
|
|
28182
|
-
tokenTransactionHashes: tokenTransactionHashes?.map(
|
|
28152
|
+
tokenTransactionHashes: tokenTransactionHashes?.map(import_utils14.hexToBytes),
|
|
28183
28153
|
outputIds: outputIds || [],
|
|
28184
28154
|
limit: pageSize,
|
|
28185
28155
|
offset
|
|
@@ -28214,7 +28184,7 @@ var TokenTransactionService = class {
|
|
|
28214
28184
|
});
|
|
28215
28185
|
}
|
|
28216
28186
|
const exactMatch = tokenOutputs.find(
|
|
28217
|
-
(item) => (0,
|
|
28187
|
+
(item) => (0, import_utils13.bytesToNumberBE)(item.output.tokenAmount) === tokenAmount
|
|
28218
28188
|
);
|
|
28219
28189
|
if (exactMatch) {
|
|
28220
28190
|
return [exactMatch];
|
|
@@ -28225,7 +28195,7 @@ var TokenTransactionService = class {
|
|
|
28225
28195
|
for (const outputWithPreviousTransactionData of tokenOutputs) {
|
|
28226
28196
|
if (remainingAmount <= 0n) break;
|
|
28227
28197
|
selectedOutputs.push(outputWithPreviousTransactionData);
|
|
28228
|
-
remainingAmount -= (0,
|
|
28198
|
+
remainingAmount -= (0, import_utils13.bytesToNumberBE)(
|
|
28229
28199
|
outputWithPreviousTransactionData.output.tokenAmount
|
|
28230
28200
|
);
|
|
28231
28201
|
}
|
|
@@ -28240,14 +28210,14 @@ var TokenTransactionService = class {
|
|
|
28240
28210
|
sortTokenOutputsByStrategy(tokenOutputs, strategy) {
|
|
28241
28211
|
if (strategy === "SMALL_FIRST") {
|
|
28242
28212
|
tokenOutputs.sort((a, b) => {
|
|
28243
|
-
const amountA = (0,
|
|
28244
|
-
const amountB = (0,
|
|
28213
|
+
const amountA = (0, import_utils13.bytesToNumberBE)(a.output.tokenAmount);
|
|
28214
|
+
const amountB = (0, import_utils13.bytesToNumberBE)(b.output.tokenAmount);
|
|
28245
28215
|
return amountA < amountB ? -1 : amountA > amountB ? 1 : 0;
|
|
28246
28216
|
});
|
|
28247
28217
|
} else {
|
|
28248
28218
|
tokenOutputs.sort((a, b) => {
|
|
28249
|
-
const amountA = (0,
|
|
28250
|
-
const amountB = (0,
|
|
28219
|
+
const amountA = (0, import_utils13.bytesToNumberBE)(a.output.tokenAmount);
|
|
28220
|
+
const amountB = (0, import_utils13.bytesToNumberBE)(b.output.tokenAmount);
|
|
28251
28221
|
return amountB < amountA ? -1 : amountB > amountA ? 1 : 0;
|
|
28252
28222
|
});
|
|
28253
28223
|
}
|
|
@@ -28255,7 +28225,7 @@ var TokenTransactionService = class {
|
|
|
28255
28225
|
// Helper function for deciding if the signer public key is the identity public key
|
|
28256
28226
|
async signMessageWithKey(message, publicKey) {
|
|
28257
28227
|
const tokenSignatures = this.config.getTokenSignatures();
|
|
28258
|
-
if ((0,
|
|
28228
|
+
if ((0, import_utils13.bytesToHex)(publicKey) === (0, import_utils13.bytesToHex)(await this.config.signer.getIdentityPublicKey())) {
|
|
28259
28229
|
if (tokenSignatures === "SCHNORR") {
|
|
28260
28230
|
return await this.config.signer.signSchnorrWithIdentityKey(message);
|
|
28261
28231
|
} else {
|
|
@@ -28264,8 +28234,8 @@ var TokenTransactionService = class {
|
|
|
28264
28234
|
} else {
|
|
28265
28235
|
throw new ValidationError("Invalid public key", {
|
|
28266
28236
|
field: "publicKey",
|
|
28267
|
-
value: (0,
|
|
28268
|
-
expected: (0,
|
|
28237
|
+
value: (0, import_utils13.bytesToHex)(publicKey),
|
|
28238
|
+
expected: (0, import_utils13.bytesToHex)(await this.config.signer.getIdentityPublicKey())
|
|
28269
28239
|
});
|
|
28270
28240
|
}
|
|
28271
28241
|
}
|
|
@@ -28284,7 +28254,7 @@ var TokenTransactionService = class {
|
|
|
28284
28254
|
}
|
|
28285
28255
|
const payload = {
|
|
28286
28256
|
finalTokenTransactionHash,
|
|
28287
|
-
operatorIdentityPublicKey: (0,
|
|
28257
|
+
operatorIdentityPublicKey: (0, import_utils14.hexToBytes)(operator.identityPublicKey)
|
|
28288
28258
|
};
|
|
28289
28259
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
28290
28260
|
const ownerSignature = await this.signMessageWithKey(
|
|
@@ -28306,7 +28276,7 @@ var TokenTransactionService = class {
|
|
|
28306
28276
|
}
|
|
28307
28277
|
const payload = {
|
|
28308
28278
|
finalTokenTransactionHash,
|
|
28309
|
-
operatorIdentityPublicKey: (0,
|
|
28279
|
+
operatorIdentityPublicKey: (0, import_utils14.hexToBytes)(operator.identityPublicKey)
|
|
28310
28280
|
};
|
|
28311
28281
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
28312
28282
|
const ownerSignature = await this.signMessageWithKey(
|
|
@@ -28322,7 +28292,7 @@ var TokenTransactionService = class {
|
|
|
28322
28292
|
for (let i = 0; i < transferInput.outputsToSpend.length; i++) {
|
|
28323
28293
|
const payload = {
|
|
28324
28294
|
finalTokenTransactionHash,
|
|
28325
|
-
operatorIdentityPublicKey: (0,
|
|
28295
|
+
operatorIdentityPublicKey: (0, import_utils14.hexToBytes)(operator.identityPublicKey)
|
|
28326
28296
|
};
|
|
28327
28297
|
const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
|
|
28328
28298
|
let ownerSignature;
|
|
@@ -28339,7 +28309,7 @@ var TokenTransactionService = class {
|
|
|
28339
28309
|
}
|
|
28340
28310
|
inputTtxoSignaturesPerOperator.push({
|
|
28341
28311
|
ttxoSignatures,
|
|
28342
|
-
operatorIdentityPublicKey: (0,
|
|
28312
|
+
operatorIdentityPublicKey: (0, import_utils14.hexToBytes)(operator.identityPublicKey)
|
|
28343
28313
|
});
|
|
28344
28314
|
}
|
|
28345
28315
|
return inputTtxoSignaturesPerOperator;
|
|
@@ -28349,22 +28319,22 @@ var TokenTransactionService = class {
|
|
|
28349
28319
|
// src/utils/adaptor-signature.ts
|
|
28350
28320
|
var import_modular = require("@noble/curves/abstract/modular");
|
|
28351
28321
|
var import_secp256k17 = require("@noble/curves/secp256k1");
|
|
28352
|
-
var
|
|
28322
|
+
var import_utils15 = require("@noble/curves/utils");
|
|
28353
28323
|
function generateSignatureFromExistingAdaptor(signature, adaptorPrivateKeyBytes) {
|
|
28354
28324
|
const { r, s } = parseSignature(signature);
|
|
28355
|
-
const sBigInt = (0,
|
|
28356
|
-
const tBigInt = (0,
|
|
28325
|
+
const sBigInt = (0, import_utils15.bytesToNumberBE)(s);
|
|
28326
|
+
const tBigInt = (0, import_utils15.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
28357
28327
|
const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
|
|
28358
|
-
const newSignature = new Uint8Array([...r, ...(0,
|
|
28328
|
+
const newSignature = new Uint8Array([...r, ...(0, import_utils15.numberToBytesBE)(newS, 32)]);
|
|
28359
28329
|
return newSignature;
|
|
28360
28330
|
}
|
|
28361
28331
|
function generateAdaptorFromSignature(signature) {
|
|
28362
28332
|
const adaptorPrivateKey = import_secp256k17.secp256k1.utils.randomPrivateKey();
|
|
28363
28333
|
const { r, s } = parseSignature(signature);
|
|
28364
|
-
const sBigInt = (0,
|
|
28365
|
-
const tBigInt = (0,
|
|
28334
|
+
const sBigInt = (0, import_utils15.bytesToNumberBE)(s);
|
|
28335
|
+
const tBigInt = (0, import_utils15.bytesToNumberBE)(adaptorPrivateKey);
|
|
28366
28336
|
const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
|
|
28367
|
-
const newSignature = new Uint8Array([...r, ...(0,
|
|
28337
|
+
const newSignature = new Uint8Array([...r, ...(0, import_utils15.numberToBytesBE)(newS, 32)]);
|
|
28368
28338
|
return {
|
|
28369
28339
|
adaptorSignature: newSignature,
|
|
28370
28340
|
adaptorPrivateKey
|
|
@@ -28381,10 +28351,10 @@ function validateOutboundAdaptorSignature(pubkey, hash, signature, adaptorPubkey
|
|
|
28381
28351
|
}
|
|
28382
28352
|
function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes) {
|
|
28383
28353
|
const { r, s } = parseSignature(signature);
|
|
28384
|
-
const sBigInt = (0,
|
|
28385
|
-
const adaptorPrivateKey = (0,
|
|
28354
|
+
const sBigInt = (0, import_utils15.bytesToNumberBE)(s);
|
|
28355
|
+
const adaptorPrivateKey = (0, import_utils15.bytesToNumberBE)(adaptorPrivateKeyBytes);
|
|
28386
28356
|
const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
|
|
28387
|
-
const newSig = new Uint8Array([...r, ...(0,
|
|
28357
|
+
const newSig = new Uint8Array([...r, ...(0, import_utils15.numberToBytesBE)(newS, 32)]);
|
|
28388
28358
|
try {
|
|
28389
28359
|
if (import_secp256k17.schnorr.verify(newSig, hash, pubkey)) {
|
|
28390
28360
|
return newSig;
|
|
@@ -28393,7 +28363,7 @@ function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes
|
|
|
28393
28363
|
console.error("[applyAdaptorToSignature] Addition verification failed:", e);
|
|
28394
28364
|
}
|
|
28395
28365
|
const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
|
|
28396
|
-
const altSig = new Uint8Array([...r, ...(0,
|
|
28366
|
+
const altSig = new Uint8Array([...r, ...(0, import_utils15.numberToBytesBE)(altS, 32)]);
|
|
28397
28367
|
try {
|
|
28398
28368
|
if (import_secp256k17.schnorr.verify(altSig, hash, pubkey)) {
|
|
28399
28369
|
return altSig;
|
|
@@ -28410,7 +28380,7 @@ function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, i
|
|
|
28410
28380
|
if (hash.length !== 32) {
|
|
28411
28381
|
throw new Error(`wrong size for message (got ${hash.length}, want 32)`);
|
|
28412
28382
|
}
|
|
28413
|
-
const pubKey = import_secp256k17.schnorr.utils.lift_x((0,
|
|
28383
|
+
const pubKey = import_secp256k17.schnorr.utils.lift_x((0, import_utils15.bytesToNumberBE)(pubKeyBytes));
|
|
28414
28384
|
pubKey.assertValidity();
|
|
28415
28385
|
const { r, s } = parseSignature(signature);
|
|
28416
28386
|
const commitmenet = import_secp256k17.schnorr.utils.taggedHash(
|
|
@@ -28422,9 +28392,9 @@ function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, i
|
|
|
28422
28392
|
if (commitmenet.length > 32) {
|
|
28423
28393
|
throw new Error("hash of (r || P || m) too big");
|
|
28424
28394
|
}
|
|
28425
|
-
const e = (0, import_modular.mod)((0,
|
|
28395
|
+
const e = (0, import_modular.mod)((0, import_utils15.bytesToNumberBE)(commitmenet), import_secp256k17.secp256k1.CURVE.n);
|
|
28426
28396
|
const negE = (0, import_modular.mod)(-e, import_secp256k17.secp256k1.CURVE.n);
|
|
28427
|
-
const sG = import_secp256k17.secp256k1.Point.BASE.multiplyUnsafe((0,
|
|
28397
|
+
const sG = import_secp256k17.secp256k1.Point.BASE.multiplyUnsafe((0, import_utils15.bytesToNumberBE)(s));
|
|
28428
28398
|
const eP = pubKey.multiplyUnsafe(negE);
|
|
28429
28399
|
const R = sG.add(eP);
|
|
28430
28400
|
if (R.is0()) {
|
|
@@ -28440,7 +28410,7 @@ function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, i
|
|
|
28440
28410
|
if (newR.y % 2n !== 0n) {
|
|
28441
28411
|
throw new Error("calculated R y-value is odd");
|
|
28442
28412
|
}
|
|
28443
|
-
const rNum = (0,
|
|
28413
|
+
const rNum = (0, import_utils15.bytesToNumberBE)(r);
|
|
28444
28414
|
if (newR.toAffine().x !== rNum) {
|
|
28445
28415
|
throw new Error("calculated R point was not given R");
|
|
28446
28416
|
}
|
|
@@ -28461,15 +28431,15 @@ function parseSignature(signature) {
|
|
|
28461
28431
|
}
|
|
28462
28432
|
const r = signature.slice(0, 32);
|
|
28463
28433
|
const s = signature.slice(32, 64);
|
|
28464
|
-
if ((0,
|
|
28434
|
+
if ((0, import_utils15.bytesToNumberBE)(r) >= import_secp256k17.secp256k1.CURVE.Fp.ORDER) {
|
|
28465
28435
|
throw new ValidationError("Invalid signature: r >= field prime", {
|
|
28466
|
-
rValue: (0,
|
|
28436
|
+
rValue: (0, import_utils15.bytesToNumberBE)(r),
|
|
28467
28437
|
fieldPrime: import_secp256k17.secp256k1.CURVE.Fp.ORDER
|
|
28468
28438
|
});
|
|
28469
28439
|
}
|
|
28470
|
-
if ((0,
|
|
28440
|
+
if ((0, import_utils15.bytesToNumberBE)(s) >= import_secp256k17.secp256k1.CURVE.n) {
|
|
28471
28441
|
throw new ValidationError("Invalid signature: s >= group order", {
|
|
28472
|
-
sValue: (0,
|
|
28442
|
+
sValue: (0, import_utils15.bytesToNumberBE)(s),
|
|
28473
28443
|
groupOrder: import_secp256k17.secp256k1.CURVE.n
|
|
28474
28444
|
});
|
|
28475
28445
|
}
|
|
@@ -28492,7 +28462,7 @@ var isWebExtension = (
|
|
|
28492
28462
|
"chrome" in globalThis && globalThis.chrome.runtime?.id
|
|
28493
28463
|
);
|
|
28494
28464
|
var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
|
|
28495
|
-
var packageVersion = true ? "0.
|
|
28465
|
+
var packageVersion = true ? "0.4.0" : "unknown";
|
|
28496
28466
|
var baseEnvStr = "unknown";
|
|
28497
28467
|
if (isBun) {
|
|
28498
28468
|
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
@@ -28513,13 +28483,10 @@ if (isBun) {
|
|
|
28513
28483
|
}
|
|
28514
28484
|
var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
|
|
28515
28485
|
|
|
28516
|
-
// src/services/signing.ts
|
|
28517
|
-
var import_utils16 = require("@noble/curves/utils");
|
|
28518
|
-
|
|
28519
28486
|
// src/utils/htlc-transactions.ts
|
|
28520
|
-
var
|
|
28487
|
+
var import_btc_signer3 = require("@scure/btc-signer");
|
|
28521
28488
|
var import_secp256k18 = require("@noble/curves/secp256k1");
|
|
28522
|
-
var
|
|
28489
|
+
var import_utils16 = require("@noble/curves/utils");
|
|
28523
28490
|
var PUB_KEY_BYTES = "0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0";
|
|
28524
28491
|
function numsPoint() {
|
|
28525
28492
|
const withdrawalPubKeyPoint = import_secp256k18.secp256k1.Point.fromHex(PUB_KEY_BYTES);
|
|
@@ -28597,10 +28564,10 @@ function createLightningHTLCTransaction({
|
|
|
28597
28564
|
outAmount = maybeApplyFee(outAmount);
|
|
28598
28565
|
}
|
|
28599
28566
|
const input = {
|
|
28600
|
-
txid: (0,
|
|
28567
|
+
txid: (0, import_utils16.hexToBytes)(getTxId(nodeTx)),
|
|
28601
28568
|
index: 0
|
|
28602
28569
|
};
|
|
28603
|
-
const htlcTransaction = new
|
|
28570
|
+
const htlcTransaction = new import_btc_signer3.Transaction({
|
|
28604
28571
|
version: 3,
|
|
28605
28572
|
allowUnknownOutputs: true
|
|
28606
28573
|
});
|
|
@@ -28639,12 +28606,12 @@ function createHTLCTaprootAddress({
|
|
|
28639
28606
|
);
|
|
28640
28607
|
const hashLockLeaf = { leafVersion: 192, script: hashLockScript };
|
|
28641
28608
|
const sequenceLockLeaf = { leafVersion: 192, script: sequenceLockScript };
|
|
28642
|
-
const scriptTree = (0,
|
|
28643
|
-
const p2trScript = (0,
|
|
28609
|
+
const scriptTree = (0, import_btc_signer3.taprootListToTree)([hashLockLeaf, sequenceLockLeaf]);
|
|
28610
|
+
const p2trScript = (0, import_btc_signer3.p2tr)(numsKey, scriptTree, network, true).script;
|
|
28644
28611
|
return p2trScript;
|
|
28645
28612
|
}
|
|
28646
28613
|
function createHashLockScript(hash, pubkey) {
|
|
28647
|
-
const result =
|
|
28614
|
+
const result = import_btc_signer3.Script.encode([
|
|
28648
28615
|
"SHA256",
|
|
28649
28616
|
hash,
|
|
28650
28617
|
"EQUALVERIFY",
|
|
@@ -28654,8 +28621,8 @@ function createHashLockScript(hash, pubkey) {
|
|
|
28654
28621
|
return result;
|
|
28655
28622
|
}
|
|
28656
28623
|
function createSequenceLockScript(sequence, sequenceLockDestinationPubkey) {
|
|
28657
|
-
const result =
|
|
28658
|
-
(0,
|
|
28624
|
+
const result = import_btc_signer3.Script.encode([
|
|
28625
|
+
(0, import_btc_signer3.ScriptNum)().encode(BigInt(sequence)),
|
|
28659
28626
|
"CHECKSEQUENCEVERIFY",
|
|
28660
28627
|
"DROP",
|
|
28661
28628
|
sequenceLockDestinationPubkey.slice(1, 33),
|
|
@@ -28719,20 +28686,7 @@ var SigningService = class {
|
|
|
28719
28686
|
});
|
|
28720
28687
|
}
|
|
28721
28688
|
const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
|
|
28722
|
-
const cpfpNodeOutPoint = {
|
|
28723
|
-
txid: (0, import_utils16.hexToBytes)(getTxId(nodeTx)),
|
|
28724
|
-
index: 0
|
|
28725
|
-
};
|
|
28726
28689
|
const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
|
|
28727
|
-
const sequence = currRefundTx.getInput(0).sequence;
|
|
28728
|
-
if (!sequence) {
|
|
28729
|
-
throw new ValidationError("Invalid refund transaction", {
|
|
28730
|
-
field: "sequence",
|
|
28731
|
-
value: currRefundTx.getInput(0),
|
|
28732
|
-
expected: "Non-null sequence"
|
|
28733
|
-
});
|
|
28734
|
-
}
|
|
28735
|
-
const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
|
|
28736
28690
|
const amountSats = currRefundTx.getOutput(0).amount;
|
|
28737
28691
|
if (amountSats === void 0) {
|
|
28738
28692
|
throw new ValidationError("Invalid refund transaction", {
|
|
@@ -28742,20 +28696,21 @@ var SigningService = class {
|
|
|
28742
28696
|
});
|
|
28743
28697
|
}
|
|
28744
28698
|
let directNodeTx;
|
|
28745
|
-
let directNodeOutPoint;
|
|
28746
28699
|
if (leaf.leaf.directTx.length > 0) {
|
|
28747
28700
|
directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
|
|
28748
|
-
directNodeOutPoint = {
|
|
28749
|
-
txid: (0, import_utils16.hexToBytes)(getTxId(directNodeTx)),
|
|
28750
|
-
index: 0
|
|
28751
|
-
};
|
|
28752
28701
|
}
|
|
28753
|
-
const
|
|
28754
|
-
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
|
|
28758
|
-
|
|
28702
|
+
const currentSequence = currRefundTx.getInput(0).sequence;
|
|
28703
|
+
if (!currentSequence) {
|
|
28704
|
+
throw new ValidationError("Invalid refund transaction", {
|
|
28705
|
+
field: "sequence",
|
|
28706
|
+
value: currRefundTx.getInput(0),
|
|
28707
|
+
expected: "Non-null sequence"
|
|
28708
|
+
});
|
|
28709
|
+
}
|
|
28710
|
+
const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createDecrementedTimelockRefundTxs({
|
|
28711
|
+
nodeTx,
|
|
28712
|
+
directNodeTx,
|
|
28713
|
+
sequence: currentSequence,
|
|
28759
28714
|
receivingPubkey: receiverIdentityPubkey,
|
|
28760
28715
|
network: this.config.getNetwork()
|
|
28761
28716
|
});
|
|
@@ -28771,7 +28726,8 @@ var SigningService = class {
|
|
|
28771
28726
|
cpfpSigningCommitments[i]?.signingNonceCommitments
|
|
28772
28727
|
);
|
|
28773
28728
|
cpfpLeafSigningJobs.push(...signingJobs);
|
|
28774
|
-
|
|
28729
|
+
const isZeroNode = getCurrentTimelock(nodeTx.getInput(0).sequence);
|
|
28730
|
+
if (directRefundTx && !isZeroNode) {
|
|
28775
28731
|
if (!directNodeTx) {
|
|
28776
28732
|
throw new ValidationError(
|
|
28777
28733
|
"Direct node transaction undefined while direct refund transaction is defined",
|
|
@@ -28796,16 +28752,6 @@ var SigningService = class {
|
|
|
28796
28752
|
directLeafSigningJobs.push(...signingJobs2);
|
|
28797
28753
|
}
|
|
28798
28754
|
if (directFromCpfpRefundTx) {
|
|
28799
|
-
if (!directNodeTx) {
|
|
28800
|
-
throw new ValidationError(
|
|
28801
|
-
"Direct node transaction undefined while direct from CPFP refund transaction is defined",
|
|
28802
|
-
{
|
|
28803
|
-
field: "directNodeTx",
|
|
28804
|
-
value: directNodeTx,
|
|
28805
|
-
expected: "Non-null direct node transaction"
|
|
28806
|
-
}
|
|
28807
|
-
);
|
|
28808
|
-
}
|
|
28809
28755
|
const refundSighash2 = getSigHashFromTx(
|
|
28810
28756
|
directFromCpfpRefundTx,
|
|
28811
28757
|
0,
|
|
@@ -28932,6 +28878,35 @@ var SigningService = class {
|
|
|
28932
28878
|
directFromCpfpLeafSigningJobs
|
|
28933
28879
|
};
|
|
28934
28880
|
}
|
|
28881
|
+
async signSigningJobs(signingJobs) {
|
|
28882
|
+
const userSignedTxSigningJobs = /* @__PURE__ */ new Map();
|
|
28883
|
+
for (const signingJob of signingJobs) {
|
|
28884
|
+
const rawTx = getTxFromRawTxBytes(signingJob.rawTx);
|
|
28885
|
+
const txOut = signingJob.parentTxOut;
|
|
28886
|
+
const rawTxSighash = getSigHashFromTx(rawTx, 0, txOut);
|
|
28887
|
+
const userSignature = await this.config.signer.signFrost({
|
|
28888
|
+
message: rawTxSighash,
|
|
28889
|
+
keyDerivation: signingJob.keyDerivation,
|
|
28890
|
+
publicKey: signingJob.signingPublicKey,
|
|
28891
|
+
verifyingKey: signingJob.verifyingKey,
|
|
28892
|
+
selfCommitment: signingJob.signingNonceCommitment,
|
|
28893
|
+
statechainCommitments: signingJob.signingNonceCommitments,
|
|
28894
|
+
adaptorPubKey: new Uint8Array()
|
|
28895
|
+
});
|
|
28896
|
+
const userSignedTxSigningJob = {
|
|
28897
|
+
leafId: signingJob.leafId,
|
|
28898
|
+
signingPublicKey: signingJob.signingPublicKey,
|
|
28899
|
+
rawTx: rawTx.toBytes(),
|
|
28900
|
+
signingNonceCommitment: signingJob.signingNonceCommitment.commitment,
|
|
28901
|
+
signingCommitments: {
|
|
28902
|
+
signingCommitments: signingJob.signingNonceCommitments
|
|
28903
|
+
},
|
|
28904
|
+
userSignature
|
|
28905
|
+
};
|
|
28906
|
+
userSignedTxSigningJobs.set(signingJob.type, userSignedTxSigningJob);
|
|
28907
|
+
}
|
|
28908
|
+
return userSignedTxSigningJobs;
|
|
28909
|
+
}
|
|
28935
28910
|
};
|
|
28936
28911
|
|
|
28937
28912
|
// src/signer/signer.ts
|
|
@@ -29731,7 +29706,7 @@ var TaprootSparkSigner = class extends DefaultSparkSigner {
|
|
|
29731
29706
|
var import_secp256k113 = require("@noble/curves/secp256k1");
|
|
29732
29707
|
var import_utils21 = require("@noble/curves/utils");
|
|
29733
29708
|
var btc3 = __toESM(require("@scure/btc-signer"), 1);
|
|
29734
|
-
var
|
|
29709
|
+
var import_btc_signer4 = require("@scure/btc-signer");
|
|
29735
29710
|
var import_utils22 = require("@scure/btc-signer/utils");
|
|
29736
29711
|
var STATIC_FAUCET_KEY = (0, import_utils21.hexToBytes)(
|
|
29737
29712
|
"deadbeef1337cafe4242424242424242deadbeef1337cafe4242424242424242"
|
|
@@ -29819,7 +29794,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29819
29794
|
);
|
|
29820
29795
|
await this.generateToAddress(1, address);
|
|
29821
29796
|
const fundingTxRaw = await this.getRawTransaction(fundingTxid);
|
|
29822
|
-
const fundingTx =
|
|
29797
|
+
const fundingTx = import_btc_signer4.Transaction.fromRaw((0, import_utils21.hexToBytes)(fundingTxRaw.hex));
|
|
29823
29798
|
for (let i = 0; i < fundingTx.outputsLength; i++) {
|
|
29824
29799
|
const output = fundingTx.getOutput(i);
|
|
29825
29800
|
if (!output.script || !output.amount) continue;
|
|
@@ -29850,7 +29825,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29850
29825
|
`Selected UTXO (${selectedUtxoAmountSats} sats) is too small to create even one faucet coin of ${COIN_AMOUNT} sats`
|
|
29851
29826
|
);
|
|
29852
29827
|
}
|
|
29853
|
-
const splitTx = new
|
|
29828
|
+
const splitTx = new import_btc_signer4.Transaction();
|
|
29854
29829
|
splitTx.addInput({
|
|
29855
29830
|
txid: selectedUtxo.txid,
|
|
29856
29831
|
index: selectedUtxo.vout
|
|
@@ -29893,7 +29868,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29893
29868
|
}
|
|
29894
29869
|
}
|
|
29895
29870
|
async sendFaucetCoinToP2WPKHAddress(pubKey) {
|
|
29896
|
-
const sendToPubKeyTx = new
|
|
29871
|
+
const sendToPubKeyTx = new import_btc_signer4.Transaction();
|
|
29897
29872
|
const p2wpkhAddress = btc3.p2wpkh(pubKey, getNetwork(4 /* LOCAL */)).address;
|
|
29898
29873
|
if (!p2wpkhAddress) {
|
|
29899
29874
|
throw new Error("Invalid P2WPKH address");
|
|
@@ -29929,7 +29904,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29929
29904
|
const sighash = unsignedTx.preimageWitnessV1(
|
|
29930
29905
|
0,
|
|
29931
29906
|
new Array(unsignedTx.inputsLength).fill(script),
|
|
29932
|
-
|
|
29907
|
+
import_btc_signer4.SigHash.DEFAULT,
|
|
29933
29908
|
new Array(unsignedTx.inputsLength).fill(fundingTxOut.amount)
|
|
29934
29909
|
);
|
|
29935
29910
|
const merkleRoot = new Uint8Array();
|
|
@@ -29948,6 +29923,14 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29948
29923
|
async mineBlocks(numBlocks) {
|
|
29949
29924
|
return await this.generateToAddress(numBlocks, this.miningAddress);
|
|
29950
29925
|
}
|
|
29926
|
+
async mineBlocksAndWaitForMiningToComplete(numBlocks) {
|
|
29927
|
+
const startBlock = await this.getBlockCount();
|
|
29928
|
+
await this.mineBlocks(numBlocks);
|
|
29929
|
+
await this.waitForBlocksMined({
|
|
29930
|
+
startBlock,
|
|
29931
|
+
expectedIncrease: numBlocks
|
|
29932
|
+
});
|
|
29933
|
+
}
|
|
29951
29934
|
async call(method, params) {
|
|
29952
29935
|
try {
|
|
29953
29936
|
const { fetch, Headers: Headers3 } = getFetch();
|
|
@@ -30000,27 +29983,62 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
30000
29983
|
async getBlock(blockHash) {
|
|
30001
29984
|
return await this.call("getblock", [blockHash, 2]);
|
|
30002
29985
|
}
|
|
29986
|
+
async getBlockCount() {
|
|
29987
|
+
return await this.call("getblockcount", []);
|
|
29988
|
+
}
|
|
29989
|
+
async waitForBlocksMined({
|
|
29990
|
+
startBlock,
|
|
29991
|
+
expectedIncrease,
|
|
29992
|
+
timeoutMs = 3e4,
|
|
29993
|
+
intervalMs = 5e3
|
|
29994
|
+
}) {
|
|
29995
|
+
const deadline = Date.now() + timeoutMs;
|
|
29996
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
29997
|
+
const start = startBlock;
|
|
29998
|
+
const target = start + expectedIncrease;
|
|
29999
|
+
while (Date.now() < deadline) {
|
|
30000
|
+
const currentBlock = await this.getBlockCount();
|
|
30001
|
+
if (currentBlock >= target) return currentBlock;
|
|
30002
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
30003
|
+
}
|
|
30004
|
+
throw new Error(
|
|
30005
|
+
`Timed out waiting for ${expectedIncrease} blocks (target height ${target})`
|
|
30006
|
+
);
|
|
30007
|
+
}
|
|
30003
30008
|
async broadcastTx(txHex) {
|
|
30004
30009
|
let response = await this.call("sendrawtransaction", [txHex, 0]);
|
|
30005
30010
|
return response;
|
|
30006
30011
|
}
|
|
30012
|
+
async submitPackage(txHexs) {
|
|
30013
|
+
let response = await this.call("submitpackage", [txHexs]);
|
|
30014
|
+
return response;
|
|
30015
|
+
}
|
|
30007
30016
|
async getNewAddress() {
|
|
30008
30017
|
const key = import_secp256k113.secp256k1.utils.randomPrivateKey();
|
|
30009
30018
|
const pubKey = import_secp256k113.secp256k1.getPublicKey(key);
|
|
30010
30019
|
return getP2TRAddressFromPublicKey(pubKey, 4 /* LOCAL */);
|
|
30011
30020
|
}
|
|
30021
|
+
async getNewExternalWallet() {
|
|
30022
|
+
const key = import_secp256k113.secp256k1.utils.randomPrivateKey();
|
|
30023
|
+
const pubKey = import_secp256k113.secp256k1.getPublicKey(key);
|
|
30024
|
+
return {
|
|
30025
|
+
address: getP2TRAddressFromPublicKey(pubKey, 4 /* LOCAL */),
|
|
30026
|
+
key,
|
|
30027
|
+
pubKey
|
|
30028
|
+
};
|
|
30029
|
+
}
|
|
30012
30030
|
async sendToAddress(address, amount, blocksToGenerate = 1) {
|
|
30013
30031
|
const coin = await this.fund();
|
|
30014
30032
|
if (!coin) {
|
|
30015
30033
|
throw new Error("No coins available");
|
|
30016
30034
|
}
|
|
30017
|
-
const tx = new
|
|
30035
|
+
const tx = new import_btc_signer4.Transaction();
|
|
30018
30036
|
tx.addInput(coin.outpoint);
|
|
30019
30037
|
const availableAmount = COIN_AMOUNT - FEE_AMOUNT;
|
|
30020
|
-
const destinationAddress = (0,
|
|
30038
|
+
const destinationAddress = (0, import_btc_signer4.Address)(getNetwork(4 /* LOCAL */)).decode(
|
|
30021
30039
|
address
|
|
30022
30040
|
);
|
|
30023
|
-
const destinationScript =
|
|
30041
|
+
const destinationScript = import_btc_signer4.OutScript.encode(destinationAddress);
|
|
30024
30042
|
tx.addOutput({
|
|
30025
30043
|
script: destinationScript,
|
|
30026
30044
|
amount
|
|
@@ -30109,75 +30127,6 @@ function chunkArray(arr, size) {
|
|
|
30109
30127
|
return chunks;
|
|
30110
30128
|
}
|
|
30111
30129
|
|
|
30112
|
-
// src/utils/optimize.ts
|
|
30113
|
-
var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
|
|
30114
|
-
function assert(condition, message) {
|
|
30115
|
-
if (!condition) {
|
|
30116
|
-
throw new InternalValidationError(message || "Assertion failed");
|
|
30117
|
-
}
|
|
30118
|
-
}
|
|
30119
|
-
function sum(arr) {
|
|
30120
|
-
return arr.reduce((a, b) => a + b, 0);
|
|
30121
|
-
}
|
|
30122
|
-
function sorted(arr) {
|
|
30123
|
-
return [...arr].sort((a, b) => a - b);
|
|
30124
|
-
}
|
|
30125
|
-
function equals(a, b) {
|
|
30126
|
-
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
30127
|
-
}
|
|
30128
|
-
function greedyLeaves(amount) {
|
|
30129
|
-
const leaves = [];
|
|
30130
|
-
let remaining = amount;
|
|
30131
|
-
for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
|
|
30132
|
-
const leaf = DENOMINATIONS[i];
|
|
30133
|
-
if (typeof leaf === "number" && leaf > 0) {
|
|
30134
|
-
while (remaining >= leaf) {
|
|
30135
|
-
remaining -= leaf;
|
|
30136
|
-
leaves.push(leaf);
|
|
30137
|
-
}
|
|
30138
|
-
}
|
|
30139
|
-
}
|
|
30140
|
-
assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
|
|
30141
|
-
return sorted(leaves);
|
|
30142
|
-
}
|
|
30143
|
-
var Swap = class {
|
|
30144
|
-
inLeaves;
|
|
30145
|
-
outLeaves;
|
|
30146
|
-
constructor(inLeaves, outLeaves) {
|
|
30147
|
-
this.inLeaves = [...inLeaves];
|
|
30148
|
-
this.outLeaves = [...outLeaves];
|
|
30149
|
-
assert(
|
|
30150
|
-
sum(this.inLeaves) === sum(this.outLeaves),
|
|
30151
|
-
"Swap in/out leaves must sum to same value for swap: " + this.toString()
|
|
30152
|
-
);
|
|
30153
|
-
}
|
|
30154
|
-
toString() {
|
|
30155
|
-
return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
|
|
30156
|
-
}
|
|
30157
|
-
};
|
|
30158
|
-
function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
|
|
30159
|
-
const swaps = [];
|
|
30160
|
-
let batch = [];
|
|
30161
|
-
let leaves = sorted(inputLeaves);
|
|
30162
|
-
while (leaves.length > 0) {
|
|
30163
|
-
batch.push(leaves.shift());
|
|
30164
|
-
const target = greedyLeaves(sum(batch));
|
|
30165
|
-
if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
|
|
30166
|
-
if (!equals(target, batch)) {
|
|
30167
|
-
swaps.push(new Swap([...batch], target));
|
|
30168
|
-
}
|
|
30169
|
-
batch = [];
|
|
30170
|
-
}
|
|
30171
|
-
}
|
|
30172
|
-
if (batch.length > 0) {
|
|
30173
|
-
const target = greedyLeaves(sum(batch));
|
|
30174
|
-
if (!equals(target, batch)) {
|
|
30175
|
-
swaps.push(new Swap([...batch], target));
|
|
30176
|
-
}
|
|
30177
|
-
}
|
|
30178
|
-
return swaps;
|
|
30179
|
-
}
|
|
30180
|
-
|
|
30181
30130
|
// src/utils/retry.ts
|
|
30182
30131
|
var DEFAULT_RETRY_CONFIG = {
|
|
30183
30132
|
maxAttempts: 5,
|
|
@@ -30254,6 +30203,199 @@ var SparkWalletEvent = {
|
|
|
30254
30203
|
StreamReconnecting: "stream:reconnecting"
|
|
30255
30204
|
};
|
|
30256
30205
|
|
|
30206
|
+
// src/utils/optimize.ts
|
|
30207
|
+
var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
|
|
30208
|
+
function assert(condition, message) {
|
|
30209
|
+
if (!condition) {
|
|
30210
|
+
throw new InternalValidationError(message || "Assertion failed");
|
|
30211
|
+
}
|
|
30212
|
+
}
|
|
30213
|
+
function sum(arr) {
|
|
30214
|
+
return arr.reduce((a, b) => a + b, 0);
|
|
30215
|
+
}
|
|
30216
|
+
function sorted(arr) {
|
|
30217
|
+
return [...arr].sort((a, b) => a - b);
|
|
30218
|
+
}
|
|
30219
|
+
function equals(a, b) {
|
|
30220
|
+
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
30221
|
+
}
|
|
30222
|
+
function countOccurrences(arr) {
|
|
30223
|
+
const map = /* @__PURE__ */ new Map();
|
|
30224
|
+
for (const x of arr) {
|
|
30225
|
+
map.set(x, (map.get(x) ?? 0) + 1);
|
|
30226
|
+
}
|
|
30227
|
+
return map;
|
|
30228
|
+
}
|
|
30229
|
+
function subtractCounters(a, b) {
|
|
30230
|
+
const result = /* @__PURE__ */ new Map();
|
|
30231
|
+
for (const [key, value] of a.entries()) {
|
|
30232
|
+
const diff = value - (b.get(key) ?? 0);
|
|
30233
|
+
if (diff > 0) {
|
|
30234
|
+
result.set(key, diff);
|
|
30235
|
+
}
|
|
30236
|
+
}
|
|
30237
|
+
return result;
|
|
30238
|
+
}
|
|
30239
|
+
function counterToFlatArray(counter) {
|
|
30240
|
+
const arr = [];
|
|
30241
|
+
for (const [k, v] of Array.from(counter.entries()).sort(
|
|
30242
|
+
(a, b) => a[0] - b[0]
|
|
30243
|
+
)) {
|
|
30244
|
+
for (let i = 0; i < v; i++) {
|
|
30245
|
+
arr.push(k);
|
|
30246
|
+
}
|
|
30247
|
+
}
|
|
30248
|
+
return arr;
|
|
30249
|
+
}
|
|
30250
|
+
function greedyLeaves(amount) {
|
|
30251
|
+
const leaves = [];
|
|
30252
|
+
let remaining = amount;
|
|
30253
|
+
for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
|
|
30254
|
+
const leaf = DENOMINATIONS[i];
|
|
30255
|
+
if (typeof leaf === "number" && leaf > 0) {
|
|
30256
|
+
while (remaining >= leaf) {
|
|
30257
|
+
remaining -= leaf;
|
|
30258
|
+
leaves.push(leaf);
|
|
30259
|
+
}
|
|
30260
|
+
}
|
|
30261
|
+
}
|
|
30262
|
+
assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
|
|
30263
|
+
return sorted(leaves);
|
|
30264
|
+
}
|
|
30265
|
+
function swapMinimizingLeaves(amount, multiplicity = 1) {
|
|
30266
|
+
const leaves = [];
|
|
30267
|
+
let remaining = amount;
|
|
30268
|
+
assert(multiplicity > 0, "multiplicity must be > 0");
|
|
30269
|
+
for (const leaf of DENOMINATIONS) {
|
|
30270
|
+
if (typeof leaf === "number" && leaf > 0) {
|
|
30271
|
+
for (let i = 0; i < multiplicity; i++) {
|
|
30272
|
+
if (remaining >= leaf) {
|
|
30273
|
+
remaining -= leaf;
|
|
30274
|
+
leaves.push(leaf);
|
|
30275
|
+
}
|
|
30276
|
+
}
|
|
30277
|
+
}
|
|
30278
|
+
}
|
|
30279
|
+
leaves.push(...greedyLeaves(remaining));
|
|
30280
|
+
assert(sum(leaves) === amount, "swap_minimizing_leaves: sum mismatch");
|
|
30281
|
+
return sorted(leaves);
|
|
30282
|
+
}
|
|
30283
|
+
var Swap = class {
|
|
30284
|
+
inLeaves;
|
|
30285
|
+
outLeaves;
|
|
30286
|
+
constructor(inLeaves, outLeaves) {
|
|
30287
|
+
this.inLeaves = [...inLeaves];
|
|
30288
|
+
this.outLeaves = [...outLeaves];
|
|
30289
|
+
assert(
|
|
30290
|
+
sum(this.inLeaves) === sum(this.outLeaves),
|
|
30291
|
+
"Swap in/out leaves must sum to same value for swap: " + this.toString()
|
|
30292
|
+
);
|
|
30293
|
+
}
|
|
30294
|
+
toString() {
|
|
30295
|
+
return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
|
|
30296
|
+
}
|
|
30297
|
+
};
|
|
30298
|
+
function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
|
|
30299
|
+
const swaps = [];
|
|
30300
|
+
let batch = [];
|
|
30301
|
+
let leaves = sorted(inputLeaves);
|
|
30302
|
+
while (leaves.length > 0) {
|
|
30303
|
+
batch.push(leaves.shift());
|
|
30304
|
+
const target = greedyLeaves(sum(batch));
|
|
30305
|
+
if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
|
|
30306
|
+
if (!equals(target, batch)) {
|
|
30307
|
+
swaps.push(new Swap([...batch], target));
|
|
30308
|
+
}
|
|
30309
|
+
batch = [];
|
|
30310
|
+
}
|
|
30311
|
+
}
|
|
30312
|
+
if (batch.length > 0) {
|
|
30313
|
+
const target = greedyLeaves(sum(batch));
|
|
30314
|
+
if (!equals(target, batch)) {
|
|
30315
|
+
swaps.push(new Swap([...batch], target));
|
|
30316
|
+
}
|
|
30317
|
+
}
|
|
30318
|
+
return swaps;
|
|
30319
|
+
}
|
|
30320
|
+
function minimizeTransferSwap(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30321
|
+
const balance = sum(inputLeaves);
|
|
30322
|
+
const optimalLeaves = swapMinimizingLeaves(balance, multiplicity);
|
|
30323
|
+
const walletCounter = countOccurrences(inputLeaves);
|
|
30324
|
+
const optimalCounter = countOccurrences(optimalLeaves);
|
|
30325
|
+
const leavesToGive = subtractCounters(walletCounter, optimalCounter);
|
|
30326
|
+
const leavesToReceive = subtractCounters(optimalCounter, walletCounter);
|
|
30327
|
+
const leavesToGiveFlat = counterToFlatArray(leavesToGive);
|
|
30328
|
+
const leavesToReceiveFlat = counterToFlatArray(leavesToReceive);
|
|
30329
|
+
const swaps = [];
|
|
30330
|
+
let toGiveBatch = [];
|
|
30331
|
+
let toReceiveBatch = [];
|
|
30332
|
+
let give = [...leavesToGiveFlat];
|
|
30333
|
+
let receive = [...leavesToReceiveFlat];
|
|
30334
|
+
while (give.length > 0 || receive.length > 0) {
|
|
30335
|
+
if (sum(toGiveBatch) > sum(toReceiveBatch)) {
|
|
30336
|
+
if (receive.length === 0) break;
|
|
30337
|
+
toReceiveBatch.push(receive.shift());
|
|
30338
|
+
} else {
|
|
30339
|
+
if (give.length === 0) break;
|
|
30340
|
+
toGiveBatch.push(give.shift());
|
|
30341
|
+
}
|
|
30342
|
+
if (toGiveBatch.length > 0 && toReceiveBatch.length > 0 && sum(toGiveBatch) === sum(toReceiveBatch)) {
|
|
30343
|
+
if (toGiveBatch.length > maxLeavesPerSwap) {
|
|
30344
|
+
for (let i = 0; i < toGiveBatch.length; i += maxLeavesPerSwap) {
|
|
30345
|
+
const subset = toGiveBatch.slice(i, i + maxLeavesPerSwap);
|
|
30346
|
+
swaps.push(new Swap(subset, greedyLeaves(sum(subset))));
|
|
30347
|
+
}
|
|
30348
|
+
} else if (toReceiveBatch.length > maxLeavesPerSwap) {
|
|
30349
|
+
for (let cutoff = maxLeavesPerSwap; cutoff > 0; cutoff--) {
|
|
30350
|
+
const sumCut = sum(toReceiveBatch.slice(0, cutoff));
|
|
30351
|
+
const remainder = sum(toGiveBatch) - sumCut;
|
|
30352
|
+
const alternateBatch = [
|
|
30353
|
+
...toReceiveBatch.slice(0, cutoff),
|
|
30354
|
+
...greedyLeaves(remainder)
|
|
30355
|
+
];
|
|
30356
|
+
if (alternateBatch.length <= maxLeavesPerSwap) {
|
|
30357
|
+
swaps.push(new Swap([...toGiveBatch], alternateBatch));
|
|
30358
|
+
break;
|
|
30359
|
+
}
|
|
30360
|
+
}
|
|
30361
|
+
} else {
|
|
30362
|
+
swaps.push(new Swap([...toGiveBatch], [...toReceiveBatch]));
|
|
30363
|
+
}
|
|
30364
|
+
toGiveBatch = [];
|
|
30365
|
+
toReceiveBatch = [];
|
|
30366
|
+
}
|
|
30367
|
+
}
|
|
30368
|
+
return swaps;
|
|
30369
|
+
}
|
|
30370
|
+
function shouldOptimize(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30371
|
+
if (multiplicity == 0) {
|
|
30372
|
+
const swaps = maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap);
|
|
30373
|
+
const numInputs = sum(swaps.map((swap) => swap.inLeaves.length));
|
|
30374
|
+
const numOutputs = sum(swaps.map((swap) => swap.outLeaves.length));
|
|
30375
|
+
return numOutputs * 5 < numInputs;
|
|
30376
|
+
} else {
|
|
30377
|
+
const swaps = minimizeTransferSwap(
|
|
30378
|
+
inputLeaves,
|
|
30379
|
+
multiplicity,
|
|
30380
|
+
maxLeavesPerSwap
|
|
30381
|
+
);
|
|
30382
|
+
const inputCounter = countOccurrences(
|
|
30383
|
+
swaps.flatMap((swap) => swap.inLeaves)
|
|
30384
|
+
);
|
|
30385
|
+
const outputCounter = countOccurrences(
|
|
30386
|
+
swaps.flatMap((swap) => swap.outLeaves)
|
|
30387
|
+
);
|
|
30388
|
+
return Math.abs(inputCounter.size - outputCounter.size) > 1;
|
|
30389
|
+
}
|
|
30390
|
+
}
|
|
30391
|
+
function optimize(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30392
|
+
if (multiplicity == 0) {
|
|
30393
|
+
return maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap);
|
|
30394
|
+
} else {
|
|
30395
|
+
return minimizeTransferSwap(inputLeaves, multiplicity, maxLeavesPerSwap);
|
|
30396
|
+
}
|
|
30397
|
+
}
|
|
30398
|
+
|
|
30257
30399
|
// src/spark-wallet/spark-wallet.ts
|
|
30258
30400
|
var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
30259
30401
|
config;
|
|
@@ -30358,16 +30500,13 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30358
30500
|
if (event.transfer.transfer && !(0, import_utils24.equalBytes)(senderIdentityPublicKey, receiverIdentityPublicKey)) {
|
|
30359
30501
|
await this.claimTransfer({
|
|
30360
30502
|
transfer: event.transfer.transfer,
|
|
30361
|
-
emit: true
|
|
30362
|
-
optimize: true
|
|
30503
|
+
emit: true
|
|
30363
30504
|
});
|
|
30364
30505
|
}
|
|
30365
30506
|
} else if (isDepositStreamEvent(event)) {
|
|
30366
30507
|
const deposit = event.deposit.deposit;
|
|
30367
|
-
|
|
30368
|
-
|
|
30369
|
-
type: "leaf" /* LEAF */,
|
|
30370
|
-
path: deposit.id
|
|
30508
|
+
await this.withLeaves(async () => {
|
|
30509
|
+
this.leaves.push(deposit);
|
|
30371
30510
|
});
|
|
30372
30511
|
this.emit(
|
|
30373
30512
|
SparkWalletEvent.DepositConfirmed,
|
|
@@ -30543,19 +30682,6 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30543
30682
|
}
|
|
30544
30683
|
return availableLeaves.filter(([_, node]) => !leavesToIgnore.has(node.id)).map(([_, node]) => node);
|
|
30545
30684
|
}
|
|
30546
|
-
async checkExtendLeaves(leaves) {
|
|
30547
|
-
await this.withLeaves(async () => {
|
|
30548
|
-
for (const leaf of leaves) {
|
|
30549
|
-
if (!leaf.parentNodeId && leaf.status === "AVAILABLE") {
|
|
30550
|
-
const res = await this.transferService.extendTimelock(leaf);
|
|
30551
|
-
await this.transferLeavesToSelf(res.nodes, {
|
|
30552
|
-
type: "leaf" /* LEAF */,
|
|
30553
|
-
path: leaf.id
|
|
30554
|
-
});
|
|
30555
|
-
}
|
|
30556
|
-
}
|
|
30557
|
-
});
|
|
30558
|
-
}
|
|
30559
30685
|
verifyKey(pubkey1, pubkey2, verifyingKey) {
|
|
30560
30686
|
return (0, import_utils24.equalBytes)(addPublicKeys(pubkey1, pubkey2), verifyingKey);
|
|
30561
30687
|
}
|
|
@@ -30665,75 +30791,84 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30665
30791
|
}
|
|
30666
30792
|
return nodes;
|
|
30667
30793
|
}
|
|
30668
|
-
|
|
30669
|
-
const
|
|
30670
|
-
if (
|
|
30671
|
-
|
|
30794
|
+
async *optimizeLeaves(multiplicity = void 0) {
|
|
30795
|
+
const multiplicityValue = multiplicity ?? this.config.getOptimizationOptions().multiplicity ?? 0;
|
|
30796
|
+
if (multiplicityValue < 0) {
|
|
30797
|
+
throw new ValidationError("Multiplicity cannot be negative");
|
|
30798
|
+
} else if (multiplicityValue > 5) {
|
|
30799
|
+
throw new ValidationError("Multiplicity cannot be greater than 5");
|
|
30672
30800
|
}
|
|
30673
|
-
|
|
30674
|
-
|
|
30675
|
-
|
|
30676
|
-
|
|
30677
|
-
const denomination = 2 ** i;
|
|
30678
|
-
while (remainingAmount >= denomination) {
|
|
30679
|
-
remainingAmount -= denomination;
|
|
30680
|
-
optimalLeavesLength++;
|
|
30681
|
-
}
|
|
30682
|
-
}
|
|
30683
|
-
return this.leaves.length > optimalLeavesLength * 5;
|
|
30684
|
-
}
|
|
30685
|
-
async optimizeLeaves() {
|
|
30686
|
-
if (this.optimizationInProgress || !this.areLeavesInefficient()) {
|
|
30801
|
+
if (this.optimizationInProgress || !shouldOptimize(
|
|
30802
|
+
this.leaves.map((leaf) => leaf.value),
|
|
30803
|
+
multiplicityValue
|
|
30804
|
+
)) {
|
|
30687
30805
|
return;
|
|
30688
30806
|
}
|
|
30689
|
-
|
|
30807
|
+
const controller = new AbortController();
|
|
30808
|
+
const release = await this.leavesMutex.acquire();
|
|
30809
|
+
try {
|
|
30690
30810
|
this.optimizationInProgress = true;
|
|
30691
|
-
|
|
30692
|
-
|
|
30693
|
-
|
|
30694
|
-
|
|
30695
|
-
|
|
30696
|
-
|
|
30697
|
-
|
|
30698
|
-
|
|
30699
|
-
|
|
30700
|
-
|
|
30701
|
-
|
|
30702
|
-
|
|
30703
|
-
|
|
30704
|
-
|
|
30705
|
-
|
|
30706
|
-
|
|
30707
|
-
|
|
30708
|
-
|
|
30709
|
-
|
|
30710
|
-
|
|
30711
|
-
|
|
30712
|
-
|
|
30713
|
-
|
|
30714
|
-
|
|
30811
|
+
this.leaves = await this.getLeaves();
|
|
30812
|
+
const swaps = optimize(
|
|
30813
|
+
this.leaves.map((leaf) => leaf.value),
|
|
30814
|
+
multiplicityValue
|
|
30815
|
+
);
|
|
30816
|
+
if (swaps.length === 0) {
|
|
30817
|
+
return;
|
|
30818
|
+
}
|
|
30819
|
+
yield {
|
|
30820
|
+
step: 0,
|
|
30821
|
+
total: swaps.length,
|
|
30822
|
+
controller
|
|
30823
|
+
};
|
|
30824
|
+
const valueToNodes = /* @__PURE__ */ new Map();
|
|
30825
|
+
this.leaves.forEach((leaf) => {
|
|
30826
|
+
if (!valueToNodes.has(leaf.value)) {
|
|
30827
|
+
valueToNodes.set(leaf.value, []);
|
|
30828
|
+
}
|
|
30829
|
+
valueToNodes.get(leaf.value).push(leaf);
|
|
30830
|
+
});
|
|
30831
|
+
for (const swap of swaps) {
|
|
30832
|
+
if (controller.signal.aborted) {
|
|
30833
|
+
break;
|
|
30834
|
+
}
|
|
30835
|
+
const leavesToSend = [];
|
|
30836
|
+
for (const leafValue of swap.inLeaves) {
|
|
30837
|
+
const nodes = valueToNodes.get(leafValue);
|
|
30838
|
+
if (nodes && nodes.length > 0) {
|
|
30839
|
+
const node = nodes.shift();
|
|
30840
|
+
leavesToSend.push(node);
|
|
30841
|
+
} else {
|
|
30842
|
+
throw new InternalValidationError(
|
|
30843
|
+
`No unused leaf with value ${leafValue} found in leaves`
|
|
30844
|
+
);
|
|
30715
30845
|
}
|
|
30716
|
-
await this.requestLeavesSwap({
|
|
30717
|
-
leaves: leavesToSend,
|
|
30718
|
-
targetAmounts: swap.outLeaves
|
|
30719
|
-
});
|
|
30720
30846
|
}
|
|
30721
|
-
|
|
30722
|
-
|
|
30723
|
-
|
|
30847
|
+
await this.requestLeavesSwap({
|
|
30848
|
+
leaves: leavesToSend,
|
|
30849
|
+
targetAmounts: swap.outLeaves
|
|
30850
|
+
});
|
|
30851
|
+
yield {
|
|
30852
|
+
step: swaps.indexOf(swap) + 1,
|
|
30853
|
+
total: swaps.length,
|
|
30854
|
+
controller
|
|
30855
|
+
};
|
|
30724
30856
|
}
|
|
30725
|
-
|
|
30857
|
+
this.leaves = await this.getLeaves();
|
|
30858
|
+
} finally {
|
|
30859
|
+
this.optimizationInProgress = false;
|
|
30860
|
+
release();
|
|
30861
|
+
}
|
|
30726
30862
|
}
|
|
30727
30863
|
async syncWallet() {
|
|
30728
30864
|
await this.syncTokenOutputs();
|
|
30729
30865
|
let leaves = await this.getLeaves();
|
|
30730
|
-
leaves = await this.
|
|
30731
|
-
leaves = await this.checkExtendTimeLockNodes(leaves);
|
|
30866
|
+
leaves = await this.checkRenewLeaves(leaves);
|
|
30732
30867
|
this.leaves = leaves;
|
|
30733
|
-
this.
|
|
30734
|
-
|
|
30735
|
-
|
|
30736
|
-
}
|
|
30868
|
+
if (this.config.getOptimizationOptions().auto) {
|
|
30869
|
+
for await (const _ of this.optimizeLeaves()) {
|
|
30870
|
+
}
|
|
30871
|
+
}
|
|
30737
30872
|
}
|
|
30738
30873
|
async withLeaves(operation) {
|
|
30739
30874
|
const release = await this.leavesMutex.acquire();
|
|
@@ -31316,8 +31451,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31316
31451
|
}
|
|
31317
31452
|
return await this.claimTransfer({
|
|
31318
31453
|
transfer: incomingTransfer,
|
|
31319
|
-
emit: false
|
|
31320
|
-
optimize: false
|
|
31454
|
+
emit: false
|
|
31321
31455
|
});
|
|
31322
31456
|
} catch (e) {
|
|
31323
31457
|
console.error("[processSwapBatch] Error details:", {
|
|
@@ -31711,16 +31845,16 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31711
31845
|
}
|
|
31712
31846
|
);
|
|
31713
31847
|
}
|
|
31714
|
-
const tx = new
|
|
31848
|
+
const tx = new import_btc_signer5.Transaction();
|
|
31715
31849
|
tx.addInput({
|
|
31716
31850
|
txid: depositTransactionId,
|
|
31717
31851
|
index: outputIndex,
|
|
31718
31852
|
witnessScript: new Uint8Array()
|
|
31719
31853
|
});
|
|
31720
|
-
const addressDecoded = (0,
|
|
31854
|
+
const addressDecoded = (0, import_btc_signer5.Address)(getNetwork(network)).decode(
|
|
31721
31855
|
destinationAddress
|
|
31722
31856
|
);
|
|
31723
|
-
const outputScript =
|
|
31857
|
+
const outputScript = import_btc_signer5.OutScript.encode(addressDecoded);
|
|
31724
31858
|
tx.addOutput({
|
|
31725
31859
|
script: outputScript,
|
|
31726
31860
|
amount: BigInt(creditAmountSats)
|
|
@@ -31904,8 +32038,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31904
32038
|
if (!output) {
|
|
31905
32039
|
continue;
|
|
31906
32040
|
}
|
|
31907
|
-
const parsedScript =
|
|
31908
|
-
const address = (0,
|
|
32041
|
+
const parsedScript = import_btc_signer5.OutScript.decode(output.script);
|
|
32042
|
+
const address = (0, import_btc_signer5.Address)(getNetwork(this.config.getNetwork())).encode(
|
|
31909
32043
|
parsedScript
|
|
31910
32044
|
);
|
|
31911
32045
|
if (staticDepositAddresses.has(address)) {
|
|
@@ -31982,26 +32116,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31982
32116
|
depositTx,
|
|
31983
32117
|
vout
|
|
31984
32118
|
});
|
|
31985
|
-
|
|
31986
|
-
for (const node of res.nodes) {
|
|
31987
|
-
if (node.status === "AVAILABLE") {
|
|
31988
|
-
const { nodes } = await this.transferService.extendTimelock(node);
|
|
31989
|
-
for (const n of nodes) {
|
|
31990
|
-
if (n.status === "AVAILABLE") {
|
|
31991
|
-
const transfer = await this.transferLeavesToSelf([n], {
|
|
31992
|
-
type: "leaf" /* LEAF */,
|
|
31993
|
-
path: node.id
|
|
31994
|
-
});
|
|
31995
|
-
resultingNodes.push(...transfer);
|
|
31996
|
-
} else {
|
|
31997
|
-
resultingNodes.push(n);
|
|
31998
|
-
}
|
|
31999
|
-
}
|
|
32000
|
-
} else {
|
|
32001
|
-
resultingNodes.push(node);
|
|
32002
|
-
}
|
|
32003
|
-
}
|
|
32004
|
-
return resultingNodes;
|
|
32119
|
+
return res.nodes;
|
|
32005
32120
|
}
|
|
32006
32121
|
/**
|
|
32007
32122
|
* Gets all unused deposit addresses for the wallet.
|
|
@@ -32110,8 +32225,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32110
32225
|
if (!output) {
|
|
32111
32226
|
continue;
|
|
32112
32227
|
}
|
|
32113
|
-
const parsedScript =
|
|
32114
|
-
const address = (0,
|
|
32228
|
+
const parsedScript = import_btc_signer5.OutScript.decode(output.script);
|
|
32229
|
+
const address = (0, import_btc_signer5.Address)(getNetwork(this.config.getNetwork())).encode(
|
|
32115
32230
|
parsedScript
|
|
32116
32231
|
);
|
|
32117
32232
|
if (unusedDepositAddresses.has(address)) {
|
|
@@ -32143,6 +32258,9 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32143
32258
|
depositTx,
|
|
32144
32259
|
vout
|
|
32145
32260
|
});
|
|
32261
|
+
await this.withLeaves(async () => {
|
|
32262
|
+
this.leaves.push(...nodes2);
|
|
32263
|
+
});
|
|
32146
32264
|
return nodes2;
|
|
32147
32265
|
});
|
|
32148
32266
|
this.mutexes.delete(txid);
|
|
@@ -32171,8 +32289,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32171
32289
|
if (!output) {
|
|
32172
32290
|
continue;
|
|
32173
32291
|
}
|
|
32174
|
-
const parsedScript =
|
|
32175
|
-
const address = (0,
|
|
32292
|
+
const parsedScript = import_btc_signer5.OutScript.decode(output.script);
|
|
32293
|
+
const address = (0, import_btc_signer5.Address)(getNetwork(this.config.getNetwork())).encode(
|
|
32176
32294
|
parsedScript
|
|
32177
32295
|
);
|
|
32178
32296
|
const unusedDepositAddress = unusedDepositAddresses.get(address);
|
|
@@ -32319,8 +32437,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32319
32437
|
`TreeNode group at index ${groupIndex} not found for amount ${amount} after selection`
|
|
32320
32438
|
);
|
|
32321
32439
|
}
|
|
32322
|
-
|
|
32323
|
-
available = await this.checkExtendTimeLockNodes(available);
|
|
32440
|
+
const available = await this.checkRenewLeaves(group);
|
|
32324
32441
|
if (available.length < group.length) {
|
|
32325
32442
|
throw new Error(
|
|
32326
32443
|
`Not enough available nodes after refresh/extend. Expected ${group.length}, got ${available.length}`
|
|
@@ -32363,7 +32480,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32363
32480
|
transfer.id
|
|
32364
32481
|
);
|
|
32365
32482
|
if (pending) {
|
|
32366
|
-
await this.claimTransfer({ transfer: pending
|
|
32483
|
+
await this.claimTransfer({ transfer: pending });
|
|
32367
32484
|
}
|
|
32368
32485
|
}
|
|
32369
32486
|
return {
|
|
@@ -32413,75 +32530,45 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32413
32530
|
newKeyDerivation: { type: "random" /* RANDOM */ }
|
|
32414
32531
|
};
|
|
32415
32532
|
}
|
|
32416
|
-
async
|
|
32417
|
-
const
|
|
32533
|
+
async checkRenewLeaves(nodes) {
|
|
32534
|
+
const nodesToRenewNode = [];
|
|
32535
|
+
const nodesToRenewRefund = [];
|
|
32536
|
+
const nodesToRenewZeroTimelock = [];
|
|
32418
32537
|
const nodeIds = [];
|
|
32419
32538
|
const validNodes = [];
|
|
32420
32539
|
for (const node of nodes) {
|
|
32421
32540
|
const nodeTx = getTxFromRawTxBytes(node.nodeTx);
|
|
32422
|
-
const
|
|
32423
|
-
|
|
32541
|
+
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
32542
|
+
const nodeSequence = nodeTx.getInput(0).sequence;
|
|
32543
|
+
const refundSequence = refundTx.getInput(0).sequence;
|
|
32544
|
+
if (nodeSequence === void 0) {
|
|
32424
32545
|
throw new ValidationError("Invalid node transaction", {
|
|
32425
32546
|
field: "sequence",
|
|
32426
32547
|
value: nodeTx.getInput(0),
|
|
32427
32548
|
expected: "Non-null sequence"
|
|
32428
32549
|
});
|
|
32429
32550
|
}
|
|
32430
|
-
|
|
32431
|
-
if (needsRefresh) {
|
|
32432
|
-
nodesToExtend.push(node);
|
|
32433
|
-
nodeIds.push(node.id);
|
|
32434
|
-
} else {
|
|
32435
|
-
validNodes.push(node);
|
|
32436
|
-
}
|
|
32437
|
-
}
|
|
32438
|
-
if (nodesToExtend.length === 0) {
|
|
32439
|
-
return validNodes;
|
|
32440
|
-
}
|
|
32441
|
-
const nodesToAdd = [];
|
|
32442
|
-
for (const node of nodesToExtend) {
|
|
32443
|
-
const { nodes: nodes2 } = await this.transferService.extendTimelock(node);
|
|
32444
|
-
this.leaves = this.leaves.filter((leaf) => leaf.id !== node.id);
|
|
32445
|
-
const newNodes = await this.transferLeavesToSelf(nodes2, {
|
|
32446
|
-
type: "leaf" /* LEAF */,
|
|
32447
|
-
path: node.id
|
|
32448
|
-
});
|
|
32449
|
-
nodesToAdd.push(...newNodes);
|
|
32450
|
-
}
|
|
32451
|
-
this.updateLeaves(nodeIds, nodesToAdd);
|
|
32452
|
-
validNodes.push(...nodesToAdd);
|
|
32453
|
-
return validNodes;
|
|
32454
|
-
}
|
|
32455
|
-
/**
|
|
32456
|
-
* Internal method to refresh timelock nodes.
|
|
32457
|
-
*
|
|
32458
|
-
* @param {string} nodeId - The optional ID of the node to refresh. If not provided, all nodes will be checked.
|
|
32459
|
-
* @returns {Promise<void>}
|
|
32460
|
-
* @private
|
|
32461
|
-
*/
|
|
32462
|
-
async checkRefreshTimelockNodes(nodes) {
|
|
32463
|
-
const nodesToRefresh = [];
|
|
32464
|
-
const nodeIds = [];
|
|
32465
|
-
const validNodes = [];
|
|
32466
|
-
for (const node of nodes) {
|
|
32467
|
-
const refundTx = getTxFromRawTxBytes(node.refundTx);
|
|
32468
|
-
const sequence = refundTx.getInput(0).sequence;
|
|
32469
|
-
if (!sequence) {
|
|
32551
|
+
if (!refundSequence) {
|
|
32470
32552
|
throw new ValidationError("Invalid refund transaction", {
|
|
32471
32553
|
field: "sequence",
|
|
32472
32554
|
value: refundTx.getInput(0),
|
|
32473
32555
|
expected: "Non-null sequence"
|
|
32474
32556
|
});
|
|
32475
32557
|
}
|
|
32476
|
-
|
|
32477
|
-
|
|
32478
|
-
|
|
32558
|
+
if (doesTxnNeedRenewed(refundSequence)) {
|
|
32559
|
+
if (isZeroTimelock(nodeSequence)) {
|
|
32560
|
+
nodesToRenewZeroTimelock.push(node);
|
|
32561
|
+
} else if (doesTxnNeedRenewed(nodeSequence)) {
|
|
32562
|
+
nodesToRenewNode.push(node);
|
|
32563
|
+
} else {
|
|
32564
|
+
nodesToRenewRefund.push(node);
|
|
32565
|
+
}
|
|
32479
32566
|
nodeIds.push(node.id);
|
|
32480
32567
|
} else {
|
|
32481
32568
|
validNodes.push(node);
|
|
32482
32569
|
}
|
|
32483
32570
|
}
|
|
32484
|
-
if (
|
|
32571
|
+
if (nodesToRenewNode.length === 0 && nodesToRenewRefund.length === 0 && nodesToRenewZeroTimelock.length === 0) {
|
|
32485
32572
|
return validNodes;
|
|
32486
32573
|
}
|
|
32487
32574
|
const nodesResp = await this.queryNodes({
|
|
@@ -32499,7 +32586,18 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32499
32586
|
nodesMap.set(node.id, node);
|
|
32500
32587
|
}
|
|
32501
32588
|
const nodesToAdd = [];
|
|
32502
|
-
for (const node of
|
|
32589
|
+
for (const node of nodesToRenewNode) {
|
|
32590
|
+
if (!node.parentNodeId) {
|
|
32591
|
+
throw new Error(`node ${node.id} has no parent`);
|
|
32592
|
+
}
|
|
32593
|
+
const parentNode = nodesMap.get(node.parentNodeId);
|
|
32594
|
+
if (!parentNode) {
|
|
32595
|
+
throw new Error(`parent node ${node.parentNodeId} not found`);
|
|
32596
|
+
}
|
|
32597
|
+
const newNode = await this.transferService.renewNodeTxn(node, parentNode);
|
|
32598
|
+
nodesToAdd.push(newNode);
|
|
32599
|
+
}
|
|
32600
|
+
for (const node of nodesToRenewRefund) {
|
|
32503
32601
|
if (!node.parentNodeId) {
|
|
32504
32602
|
throw new Error(`node ${node.id} has no parent`);
|
|
32505
32603
|
}
|
|
@@ -32507,17 +32605,14 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32507
32605
|
if (!parentNode) {
|
|
32508
32606
|
throw new Error(`parent node ${node.parentNodeId} not found`);
|
|
32509
32607
|
}
|
|
32510
|
-
const
|
|
32608
|
+
const newNode = await this.transferService.renewRefundTxn(
|
|
32511
32609
|
node,
|
|
32512
32610
|
parentNode
|
|
32513
32611
|
);
|
|
32514
|
-
|
|
32515
|
-
|
|
32516
|
-
|
|
32517
|
-
const newNode =
|
|
32518
|
-
if (!newNode) {
|
|
32519
|
-
throw new Error("Failed to refresh timelock node");
|
|
32520
|
-
}
|
|
32612
|
+
nodesToAdd.push(newNode);
|
|
32613
|
+
}
|
|
32614
|
+
for (const node of nodesToRenewZeroTimelock) {
|
|
32615
|
+
const newNode = await this.transferService.renewZeroTimelockNodeTxn(node);
|
|
32521
32616
|
nodesToAdd.push(newNode);
|
|
32522
32617
|
}
|
|
32523
32618
|
this.updateLeaves(nodeIds, nodesToAdd);
|
|
@@ -32558,14 +32653,14 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32558
32653
|
return response.nodes;
|
|
32559
32654
|
});
|
|
32560
32655
|
}
|
|
32561
|
-
async processClaimedTransferResults(result, transfer, emit
|
|
32562
|
-
result = await this.
|
|
32563
|
-
result = await this.checkExtendTimeLockNodes(result);
|
|
32656
|
+
async processClaimedTransferResults(result, transfer, emit) {
|
|
32657
|
+
result = await this.checkRenewLeaves(result);
|
|
32564
32658
|
const existingIds = new Set(this.leaves.map((leaf) => leaf.id));
|
|
32565
32659
|
const uniqueResults = result.filter((node) => !existingIds.has(node.id));
|
|
32566
32660
|
this.leaves.push(...uniqueResults);
|
|
32567
|
-
if (
|
|
32568
|
-
await this.optimizeLeaves()
|
|
32661
|
+
if (this.config.getOptimizationOptions().auto && transfer.type !== 40 /* COUNTER_SWAP */) {
|
|
32662
|
+
for await (const _ of this.optimizeLeaves()) {
|
|
32663
|
+
}
|
|
32569
32664
|
}
|
|
32570
32665
|
if (emit) {
|
|
32571
32666
|
this.emit(
|
|
@@ -32584,8 +32679,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32584
32679
|
*/
|
|
32585
32680
|
async claimTransfer({
|
|
32586
32681
|
transfer,
|
|
32587
|
-
emit
|
|
32588
|
-
optimize
|
|
32682
|
+
emit
|
|
32589
32683
|
}) {
|
|
32590
32684
|
const onError = async (context) => {
|
|
32591
32685
|
const error = context.error;
|
|
@@ -32630,12 +32724,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32630
32724
|
if (result.length === 0) {
|
|
32631
32725
|
return [];
|
|
32632
32726
|
}
|
|
32633
|
-
return await this.processClaimedTransferResults(
|
|
32634
|
-
result,
|
|
32635
|
-
transfer,
|
|
32636
|
-
emit,
|
|
32637
|
-
optimize
|
|
32638
|
-
);
|
|
32727
|
+
return await this.processClaimedTransferResults(result, transfer, emit);
|
|
32639
32728
|
} catch (error) {
|
|
32640
32729
|
console.warn(
|
|
32641
32730
|
`Failed to claim transfer after all retries. Please try reinitializing your wallet in a few minutes. Transfer ID: ${transfer.id}`,
|
|
@@ -32668,7 +32757,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32668
32757
|
continue;
|
|
32669
32758
|
}
|
|
32670
32759
|
promises.push(
|
|
32671
|
-
this.claimTransfer({ transfer, emit
|
|
32760
|
+
this.claimTransfer({ transfer, emit }).then(() => transfer.id).catch((error) => {
|
|
32672
32761
|
console.warn(`Failed to claim transfer ${transfer.id}:`, error);
|
|
32673
32762
|
return null;
|
|
32674
32763
|
})
|
|
@@ -32939,8 +33028,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32939
33028
|
selectedLeaves,
|
|
32940
33029
|
`no leaves for ${totalAmount}`
|
|
32941
33030
|
);
|
|
32942
|
-
leaves = await this.
|
|
32943
|
-
leaves = await this.checkExtendTimeLockNodes(leaves);
|
|
33031
|
+
leaves = await this.checkRenewLeaves(leaves);
|
|
32944
33032
|
const leavesToSend = await Promise.all(
|
|
32945
33033
|
leaves.map(async (leaf) => ({
|
|
32946
33034
|
leaf,
|
|
@@ -33271,10 +33359,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33271
33359
|
leavesToSendToSsp = leavesForTargetAmount;
|
|
33272
33360
|
leavesToSendToSE = leavesForFee;
|
|
33273
33361
|
}
|
|
33274
|
-
leavesToSendToSsp = await this.
|
|
33275
|
-
|
|
33276
|
-
leavesToSendToSE = await this.checkRefreshTimelockNodes(leavesToSendToSE);
|
|
33277
|
-
leavesToSendToSE = await this.checkExtendTimeLockNodes(leavesToSendToSE);
|
|
33362
|
+
leavesToSendToSsp = await this.checkRenewLeaves(leavesToSendToSsp);
|
|
33363
|
+
leavesToSendToSE = await this.checkRenewLeaves(leavesToSendToSE);
|
|
33278
33364
|
const leafKeyTweaks = await Promise.all(
|
|
33279
33365
|
[...leavesToSendToSE, ...leavesToSendToSsp].map(async (leaf) => ({
|
|
33280
33366
|
leaf,
|
|
@@ -33360,8 +33446,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33360
33446
|
(await this.selectLeaves([amountSats])).get(amountSats),
|
|
33361
33447
|
`no leaves for ${amountSats}`
|
|
33362
33448
|
);
|
|
33363
|
-
leaves = await this.
|
|
33364
|
-
leaves = await this.checkExtendTimeLockNodes(leaves);
|
|
33449
|
+
leaves = await this.checkRenewLeaves(leaves);
|
|
33365
33450
|
const feeEstimate = await sspClient.getCoopExitFeeQuote({
|
|
33366
33451
|
leafExternalIds: leaves.map((leaf) => leaf.id),
|
|
33367
33452
|
withdrawalAddress
|
|
@@ -33649,7 +33734,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33649
33734
|
*/
|
|
33650
33735
|
async signTransaction(txHex, keyType = "auto-detect") {
|
|
33651
33736
|
try {
|
|
33652
|
-
const tx =
|
|
33737
|
+
const tx = import_btc_signer5.Transaction.fromRaw((0, import_utils24.hexToBytes)(txHex));
|
|
33653
33738
|
let publicKey;
|
|
33654
33739
|
switch (keyType.toLowerCase()) {
|
|
33655
33740
|
case "identity":
|
|
@@ -33856,15 +33941,6 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33856
33941
|
}
|
|
33857
33942
|
);
|
|
33858
33943
|
}
|
|
33859
|
-
if (!nodeInput.sequence) {
|
|
33860
|
-
throw new ValidationError(
|
|
33861
|
-
`Node transaction has no sequence for ${isRootNode ? "root" : "non-root"} node`,
|
|
33862
|
-
{
|
|
33863
|
-
field: "sequence",
|
|
33864
|
-
value: nodeInput.sequence
|
|
33865
|
-
}
|
|
33866
|
-
);
|
|
33867
|
-
}
|
|
33868
33944
|
const refundInput = refundTx.getInput(0);
|
|
33869
33945
|
if (!refundInput) {
|
|
33870
33946
|
throw new ValidationError(
|
|
@@ -33900,89 +33976,6 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
33900
33976
|
);
|
|
33901
33977
|
}
|
|
33902
33978
|
}
|
|
33903
|
-
/**
|
|
33904
|
-
* Refresh the timelock of a specific node.
|
|
33905
|
-
*
|
|
33906
|
-
* @param {string} nodeId - The ID of the node to refresh
|
|
33907
|
-
* @returns {Promise<void>} Promise that resolves when the timelock is refreshed
|
|
33908
|
-
*/
|
|
33909
|
-
async testOnly_expireTimelock(nodeId) {
|
|
33910
|
-
const sparkClient = await this.connectionManager.createSparkClient(
|
|
33911
|
-
this.config.getCoordinatorAddress()
|
|
33912
|
-
);
|
|
33913
|
-
try {
|
|
33914
|
-
const response = await sparkClient.query_nodes({
|
|
33915
|
-
source: {
|
|
33916
|
-
$case: "nodeIds",
|
|
33917
|
-
nodeIds: {
|
|
33918
|
-
nodeIds: [nodeId]
|
|
33919
|
-
}
|
|
33920
|
-
},
|
|
33921
|
-
includeParents: true
|
|
33922
|
-
});
|
|
33923
|
-
let leaf = response.nodes[nodeId];
|
|
33924
|
-
if (!leaf) {
|
|
33925
|
-
throw new ValidationError("Node not found", {
|
|
33926
|
-
field: "nodeId",
|
|
33927
|
-
value: nodeId
|
|
33928
|
-
});
|
|
33929
|
-
}
|
|
33930
|
-
let parentNode;
|
|
33931
|
-
let hasParentNode = false;
|
|
33932
|
-
if (!leaf.parentNodeId) {
|
|
33933
|
-
} else {
|
|
33934
|
-
hasParentNode = true;
|
|
33935
|
-
parentNode = response.nodes[leaf.parentNodeId];
|
|
33936
|
-
if (!parentNode) {
|
|
33937
|
-
throw new ValidationError("Parent node not found", {
|
|
33938
|
-
field: "parentNodeId",
|
|
33939
|
-
value: leaf.parentNodeId
|
|
33940
|
-
});
|
|
33941
|
-
}
|
|
33942
|
-
}
|
|
33943
|
-
const nodeTx = getTxFromRawTxBytes(leaf.nodeTx);
|
|
33944
|
-
const refundTx = getTxFromRawTxBytes(leaf.refundTx);
|
|
33945
|
-
if (hasParentNode) {
|
|
33946
|
-
const nodeTimelock = getCurrentTimelock(nodeTx.getInput(0).sequence);
|
|
33947
|
-
if (nodeTimelock > 100) {
|
|
33948
|
-
const expiredNodeTxLeaf = await this.transferService.testonly_expireTimeLockNodeTx(
|
|
33949
|
-
leaf,
|
|
33950
|
-
parentNode
|
|
33951
|
-
);
|
|
33952
|
-
if (!expiredNodeTxLeaf.nodes[0]) {
|
|
33953
|
-
throw new ValidationError("No expired node tx leaf", {
|
|
33954
|
-
field: "expiredNodeTxLeaf",
|
|
33955
|
-
value: expiredNodeTxLeaf
|
|
33956
|
-
});
|
|
33957
|
-
}
|
|
33958
|
-
leaf = expiredNodeTxLeaf.nodes[0];
|
|
33959
|
-
}
|
|
33960
|
-
}
|
|
33961
|
-
const refundTimelock = getCurrentTimelock(refundTx.getInput(0).sequence);
|
|
33962
|
-
if (refundTimelock > 100) {
|
|
33963
|
-
const expiredTxLeaf = await this.transferService.testonly_expireTimeLockRefundtx(leaf);
|
|
33964
|
-
if (!expiredTxLeaf.nodes[0]) {
|
|
33965
|
-
throw new ValidationError("No expired tx leaf", {
|
|
33966
|
-
field: "expiredTxLeaf",
|
|
33967
|
-
value: expiredTxLeaf
|
|
33968
|
-
});
|
|
33969
|
-
}
|
|
33970
|
-
leaf = expiredTxLeaf.nodes[0];
|
|
33971
|
-
}
|
|
33972
|
-
const leafIndex = this.leaves.findIndex((leaf2) => leaf2.id === leaf2.id);
|
|
33973
|
-
if (leafIndex !== -1) {
|
|
33974
|
-
this.leaves[leafIndex] = leaf;
|
|
33975
|
-
}
|
|
33976
|
-
} catch (error) {
|
|
33977
|
-
throw new NetworkError(
|
|
33978
|
-
"Failed to refresh timelock",
|
|
33979
|
-
{
|
|
33980
|
-
method: "refresh_timelock"
|
|
33981
|
-
},
|
|
33982
|
-
error
|
|
33983
|
-
);
|
|
33984
|
-
}
|
|
33985
|
-
}
|
|
33986
33979
|
cleanup() {
|
|
33987
33980
|
if (this.claimTransfersInterval) {
|
|
33988
33981
|
clearInterval(this.claimTransfersInterval);
|
|
@@ -34137,8 +34130,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
34137
34130
|
"getLightningReceiveRequest",
|
|
34138
34131
|
"getLightningSendRequest",
|
|
34139
34132
|
"getCoopExitRequest",
|
|
34140
|
-
"checkTimelock"
|
|
34141
|
-
"testOnly_expireTimelock"
|
|
34133
|
+
"checkTimelock"
|
|
34142
34134
|
];
|
|
34143
34135
|
methods.forEach((m) => this.wrapPublicSparkWalletMethodWithOtelSpan(m));
|
|
34144
34136
|
this.initWallet = this.wrapWithOtelSpan(
|
|
@@ -35718,7 +35710,6 @@ setFetch(sparkBareFetch, Headers2);
|
|
|
35718
35710
|
DIRECT_TIMELOCK_OFFSET,
|
|
35719
35711
|
DefaultSparkSigner,
|
|
35720
35712
|
HTLC_TIMELOCK_OFFSET,
|
|
35721
|
-
INITIAL_DIRECT_SEQUENCE,
|
|
35722
35713
|
INITIAL_SEQUENCE,
|
|
35723
35714
|
InternalValidationError,
|
|
35724
35715
|
LOGGER_NAMES,
|
|
@@ -35751,21 +35742,24 @@ setFetch(sparkBareFetch, Headers2);
|
|
|
35751
35742
|
constructFeeBumpTx,
|
|
35752
35743
|
constructUnilateralExitFeeBumpPackages,
|
|
35753
35744
|
constructUnilateralExitTxs,
|
|
35754
|
-
|
|
35755
|
-
|
|
35756
|
-
|
|
35757
|
-
|
|
35758
|
-
|
|
35759
|
-
|
|
35760
|
-
|
|
35745
|
+
createConnectorRefundTxs,
|
|
35746
|
+
createCurrentTimelockRefundTxs,
|
|
35747
|
+
createDecrementedTimelockNodeTx,
|
|
35748
|
+
createDecrementedTimelockRefundTxs,
|
|
35749
|
+
createInitialTimelockNodeTx,
|
|
35750
|
+
createInitialTimelockRefundTxs,
|
|
35751
|
+
createRootNodeTx,
|
|
35761
35752
|
createSigningCommitment,
|
|
35762
35753
|
createSigningNonce,
|
|
35763
|
-
|
|
35754
|
+
createTestUnilateralRefundTxs,
|
|
35755
|
+
createTestUnilateralTimelockNodeTx,
|
|
35756
|
+
createZeroTimelockNodeTx,
|
|
35764
35757
|
decodeBech32mTokenIdentifier,
|
|
35765
35758
|
decodeBytesToSigningCommitment,
|
|
35766
35759
|
decodeBytesToSigningNonce,
|
|
35767
35760
|
decodeSparkAddress,
|
|
35768
35761
|
doesLeafNeedRefresh,
|
|
35762
|
+
doesTxnNeedRenewed,
|
|
35769
35763
|
encodeBech32mTokenIdentifier,
|
|
35770
35764
|
encodeSigningCommitmentToBytes,
|
|
35771
35765
|
encodeSigningNonceToBytes,
|
|
@@ -35803,12 +35797,14 @@ setFetch(sparkBareFetch, Headers2);
|
|
|
35803
35797
|
getTxFromRawTxHex,
|
|
35804
35798
|
getTxId,
|
|
35805
35799
|
getTxIdNoReverse,
|
|
35800
|
+
hash160,
|
|
35806
35801
|
isEphemeralAnchorOutput,
|
|
35807
35802
|
isLegacySparkAddress,
|
|
35808
35803
|
isSafeForNumber,
|
|
35809
35804
|
isTxBroadcast,
|
|
35810
35805
|
isValidPublicKey,
|
|
35811
35806
|
isValidSparkAddress,
|
|
35807
|
+
isZeroTimelock,
|
|
35812
35808
|
lastKeyWithTarget,
|
|
35813
35809
|
maybeApplyFee,
|
|
35814
35810
|
modInverse,
|