@buildonspark/spark-sdk 0.1.39 → 0.1.41
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 +14 -0
- package/README.md +1 -1
- package/dist/{RequestLightningSendInput-39_zGri6.d.cts → RequestLightningSendInput-DXcLoiCe.d.cts} +10 -2
- package/dist/{RequestLightningSendInput-B4JdzclX.d.ts → RequestLightningSendInput-mXUWn_cp.d.ts} +10 -2
- package/dist/address/index.cjs +138 -6
- package/dist/address/index.d.cts +18 -6
- package/dist/address/index.d.ts +18 -6
- package/dist/address/index.js +5 -2
- package/dist/{chunk-FWQPAPXK.js → chunk-2ZXXLPG2.js} +1 -1
- package/dist/{chunk-S7KD6DDL.js → chunk-6YVPOQ2A.js} +41 -20
- package/dist/{chunk-ZUVYYR5T.js → chunk-7EFSUADA.js} +1 -0
- package/dist/{chunk-NS4UZRQ7.js → chunk-ABZA6R5S.js} +1 -1
- package/dist/{chunk-57XLH3ZR.js → chunk-ATEHMLKP.js} +23 -23
- package/dist/{chunk-VJTDG4BQ.js → chunk-HK6LPV6Z.js} +10 -1
- package/dist/{chunk-W3EC5XSA.js → chunk-J5W5Q2ZP.js} +337 -72
- package/dist/{chunk-TKYOYOYJ.js → chunk-KKSU7OZO.js} +653 -76
- package/dist/chunk-L3EHBOUX.js +0 -0
- package/dist/{chunk-C5LTJBI7.js → chunk-M6A4KFIG.js} +125 -226
- package/dist/{chunk-A74XSEW3.js → chunk-MIVX3GHD.js} +1 -1
- package/dist/{chunk-RGWBSZIO.js → chunk-ROKY5KS4.js} +23 -3
- package/dist/{chunk-LIP2K6KR.js → chunk-TM4TOEOX.js} +26 -8
- package/dist/{chunk-RAPBVYJY.js → chunk-UKT6OFLO.js} +125 -35
- package/dist/chunk-VA7MV4MZ.js +1073 -0
- package/dist/chunk-YEZDPUFY.js +840 -0
- package/dist/{chunk-DI7QXUQJ.js → chunk-ZXDE2XMU.js} +8 -5
- package/dist/graphql/objects/index.cjs +6 -3
- package/dist/graphql/objects/index.d.cts +6 -5
- package/dist/graphql/objects/index.d.ts +6 -5
- package/dist/graphql/objects/index.js +1 -1
- package/dist/{index-DEo_hdN3.d.cts → index-CFh4uWzi.d.cts} +60 -6
- package/dist/{index-BVY0yH_H.d.ts → index-OSDtPMmC.d.ts} +60 -6
- package/dist/index.cjs +3316 -954
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +48 -26
- package/dist/index.node.cjs +3316 -954
- package/dist/index.node.d.cts +9 -8
- package/dist/index.node.d.ts +9 -8
- package/dist/index.node.js +48 -26
- package/dist/native/index.cjs +3323 -961
- package/dist/native/index.d.cts +542 -260
- package/dist/native/index.d.ts +542 -260
- package/dist/native/index.js +3192 -838
- package/dist/{network-DobHpaV6.d.ts → network-BF2GYPye.d.ts} +9 -2
- package/dist/{network-GFGEHkS4.d.cts → network-BiwBmoOg.d.cts} +9 -2
- package/dist/proto/lrc20.d.cts +1 -1
- package/dist/proto/lrc20.d.ts +1 -1
- package/dist/proto/lrc20.js +2 -2
- package/dist/proto/spark.cjs +125 -226
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +3 -5
- package/dist/proto/spark_token.cjs +1364 -0
- package/dist/proto/spark_token.d.cts +209 -0
- package/dist/proto/spark_token.d.ts +209 -0
- package/dist/proto/spark_token.js +32 -0
- package/dist/{sdk-types-BuVMn2rX.d.cts → sdk-types-CfhdFnsA.d.cts} +1 -1
- package/dist/{sdk-types-BeI6DM_M.d.ts → sdk-types-MnQrHolg.d.ts} +1 -1
- package/dist/services/config.cjs +64 -40
- package/dist/services/config.d.cts +6 -5
- package/dist/services/config.d.ts +6 -5
- package/dist/services/config.js +7 -7
- package/dist/services/connection.cjs +1108 -306
- package/dist/services/connection.d.cts +10 -5
- package/dist/services/connection.d.ts +10 -5
- package/dist/services/connection.js +3 -2
- package/dist/services/index.cjs +1702 -488
- package/dist/services/index.d.cts +6 -5
- package/dist/services/index.d.ts +6 -5
- package/dist/services/index.js +16 -14
- package/dist/services/lrc-connection.d.cts +5 -5
- package/dist/services/lrc-connection.d.ts +5 -5
- package/dist/services/lrc-connection.js +3 -3
- package/dist/services/token-transactions.cjs +637 -247
- package/dist/services/token-transactions.d.cts +19 -8
- package/dist/services/token-transactions.d.ts +19 -8
- package/dist/services/token-transactions.js +5 -4
- package/dist/services/wallet-config.cjs +1 -0
- package/dist/services/wallet-config.d.cts +6 -5
- package/dist/services/wallet-config.d.ts +6 -5
- package/dist/services/wallet-config.js +1 -1
- package/dist/signer/signer.cjs +122 -35
- package/dist/signer/signer.d.cts +4 -3
- package/dist/signer/signer.d.ts +4 -3
- package/dist/signer/signer.js +8 -4
- package/dist/{signer-C1t40Wus.d.cts → signer-BhLS7SYR.d.cts} +35 -14
- package/dist/{signer-DFGw9RRp.d.ts → signer-CylxIujU.d.ts} +35 -14
- package/dist/{spark-DXYE9gMM.d.ts → spark-DjR1b3TC.d.cts} +13 -21
- package/dist/{spark-DXYE9gMM.d.cts → spark-DjR1b3TC.d.ts} +13 -21
- package/dist/types/index.cjs +130 -227
- package/dist/types/index.d.cts +6 -5
- package/dist/types/index.d.ts +6 -5
- package/dist/types/index.js +3 -3
- package/dist/utils/index.cjs +1169 -3
- package/dist/utils/index.d.cts +66 -6
- package/dist/utils/index.d.ts +66 -6
- package/dist/utils/index.js +35 -14
- package/package.json +6 -2
- package/src/address/address.ts +41 -6
- package/src/graphql/client.ts +15 -0
- package/src/graphql/objects/Transfer.ts +7 -0
- package/src/graphql/queries/Transfer.ts +10 -0
- package/src/proto/spark.ts +215 -337
- package/src/proto/spark_token.ts +1407 -0
- package/src/services/config.ts +4 -0
- package/src/services/connection.ts +37 -1
- package/src/services/deposit.ts +23 -5
- package/src/services/token-transactions.ts +426 -75
- package/src/services/transfer.ts +182 -11
- package/src/services/tree-creation.ts +29 -14
- package/src/services/wallet-config.ts +2 -0
- package/src/signer/signer.ts +190 -48
- package/src/spark-wallet/spark-wallet.ts +510 -6
- package/src/tests/integration/transfer.test.ts +186 -214
- package/src/tests/integration/tree-creation.test.ts +5 -1
- package/src/tests/signer.test.ts +34 -0
- package/src/tests/transaction.test.ts +12 -0
- package/src/tests/xchain-address.test.ts +28 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/mempool.ts +26 -1
- package/src/utils/network.ts +15 -0
- package/src/utils/transaction.ts +51 -3
- package/src/utils/unilateral-exit.ts +729 -0
- package/src/utils/xchain-address.ts +36 -0
- package/dist/chunk-E5SL7XTO.js +0 -301
package/dist/utils/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: tr
|
|
|
30
30
|
// src/utils/index.ts
|
|
31
31
|
var utils_exports = {};
|
|
32
32
|
__export(utils_exports, {
|
|
33
|
+
DEFAULT_FEE_SATS: () => DEFAULT_FEE_SATS,
|
|
33
34
|
LRC_WALLET_NETWORK: () => LRC_WALLET_NETWORK,
|
|
34
35
|
LRC_WALLET_NETWORK_TYPE: () => LRC_WALLET_NETWORK_TYPE,
|
|
35
36
|
Network: () => Network2,
|
|
@@ -41,9 +42,13 @@ __export(utils_exports, {
|
|
|
41
42
|
bigIntToPrivateKey: () => bigIntToPrivateKey,
|
|
42
43
|
calculateAvailableTokenAmount: () => calculateAvailableTokenAmount,
|
|
43
44
|
checkIfSelectedOutputsAreAvailable: () => checkIfSelectedOutputsAreAvailable,
|
|
45
|
+
checkIfValidSequence: () => checkIfValidSequence,
|
|
44
46
|
collectResponses: () => collectResponses,
|
|
45
47
|
computeTaprootKeyNoScript: () => computeTaprootKeyNoScript,
|
|
46
48
|
computerLagrangeCoefficients: () => computerLagrangeCoefficients,
|
|
49
|
+
constructFeeBumpTx: () => constructFeeBumpTx,
|
|
50
|
+
constructUnilateralExitFeeBumpPackages: () => constructUnilateralExitFeeBumpPackages,
|
|
51
|
+
constructUnilateralExitTxs: () => constructUnilateralExitTxs,
|
|
47
52
|
createRefundTx: () => createRefundTx,
|
|
48
53
|
createSigningCommitment: () => createSigningCommitment,
|
|
49
54
|
createSigningNonce: () => createSigningNonce,
|
|
@@ -62,6 +67,7 @@ __export(utils_exports, {
|
|
|
62
67
|
getLatestDepositTxId: () => getLatestDepositTxId,
|
|
63
68
|
getNetwork: () => getNetwork,
|
|
64
69
|
getNetworkFromAddress: () => getNetworkFromAddress,
|
|
70
|
+
getNetworkFromString: () => getNetworkFromString,
|
|
65
71
|
getNextTransactionSequence: () => getNextTransactionSequence,
|
|
66
72
|
getP2TRAddressFromPkScript: () => getP2TRAddressFromPkScript,
|
|
67
73
|
getP2TRAddressFromPublicKey: () => getP2TRAddressFromPublicKey,
|
|
@@ -71,13 +77,17 @@ __export(utils_exports, {
|
|
|
71
77
|
getRandomSigningNonce: () => getRandomSigningNonce,
|
|
72
78
|
getSigHashFromTx: () => getSigHashFromTx,
|
|
73
79
|
getSigningCommitmentFromNonce: () => getSigningCommitmentFromNonce,
|
|
80
|
+
getSparkAddressFromTaproot: () => getSparkAddressFromTaproot,
|
|
74
81
|
getTransactionSequence: () => getTransactionSequence,
|
|
75
82
|
getTransferPackageSigningPayload: () => getTransferPackageSigningPayload,
|
|
76
83
|
getTxFromRawTxBytes: () => getTxFromRawTxBytes,
|
|
77
84
|
getTxFromRawTxHex: () => getTxFromRawTxHex,
|
|
78
85
|
getTxId: () => getTxId,
|
|
79
86
|
getTxIdNoReverse: () => getTxIdNoReverse,
|
|
87
|
+
isEphemeralAnchorOutput: () => isEphemeralAnchorOutput,
|
|
88
|
+
isTxBroadcast: () => isTxBroadcast,
|
|
80
89
|
lastKeyWithTarget: () => lastKeyWithTarget,
|
|
90
|
+
maybeApplyFee: () => maybeApplyFee,
|
|
81
91
|
modInverse: () => modInverse,
|
|
82
92
|
proofOfPossessionMessageHashForDepositAddress: () => proofOfPossessionMessageHashForDepositAddress,
|
|
83
93
|
recoverSecret: () => recoverSecret,
|
|
@@ -302,6 +312,564 @@ var import_wire2 = require("@bufbuild/protobuf/wire");
|
|
|
302
312
|
// src/proto/google/protobuf/timestamp.ts
|
|
303
313
|
var import_wire3 = require("@bufbuild/protobuf/wire");
|
|
304
314
|
|
|
315
|
+
// src/proto/spark.ts
|
|
316
|
+
function networkFromJSON(object) {
|
|
317
|
+
switch (object) {
|
|
318
|
+
case 0:
|
|
319
|
+
case "UNSPECIFIED":
|
|
320
|
+
return 0 /* UNSPECIFIED */;
|
|
321
|
+
case 1:
|
|
322
|
+
case "MAINNET":
|
|
323
|
+
return 1 /* MAINNET */;
|
|
324
|
+
case 2:
|
|
325
|
+
case "REGTEST":
|
|
326
|
+
return 2 /* REGTEST */;
|
|
327
|
+
case 3:
|
|
328
|
+
case "TESTNET":
|
|
329
|
+
return 3 /* TESTNET */;
|
|
330
|
+
case 4:
|
|
331
|
+
case "SIGNET":
|
|
332
|
+
return 4 /* SIGNET */;
|
|
333
|
+
case -1:
|
|
334
|
+
case "UNRECOGNIZED":
|
|
335
|
+
default:
|
|
336
|
+
return -1 /* UNRECOGNIZED */;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function networkToJSON(object) {
|
|
340
|
+
switch (object) {
|
|
341
|
+
case 0 /* UNSPECIFIED */:
|
|
342
|
+
return "UNSPECIFIED";
|
|
343
|
+
case 1 /* MAINNET */:
|
|
344
|
+
return "MAINNET";
|
|
345
|
+
case 2 /* REGTEST */:
|
|
346
|
+
return "REGTEST";
|
|
347
|
+
case 3 /* TESTNET */:
|
|
348
|
+
return "TESTNET";
|
|
349
|
+
case 4 /* SIGNET */:
|
|
350
|
+
return "SIGNET";
|
|
351
|
+
case -1 /* UNRECOGNIZED */:
|
|
352
|
+
default:
|
|
353
|
+
return "UNRECOGNIZED";
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function createBaseSigningKeyshare() {
|
|
357
|
+
return { ownerIdentifiers: [], threshold: 0, publicKey: new Uint8Array(0) };
|
|
358
|
+
}
|
|
359
|
+
var SigningKeyshare = {
|
|
360
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
361
|
+
for (const v of message.ownerIdentifiers) {
|
|
362
|
+
writer.uint32(10).string(v);
|
|
363
|
+
}
|
|
364
|
+
if (message.threshold !== 0) {
|
|
365
|
+
writer.uint32(16).uint32(message.threshold);
|
|
366
|
+
}
|
|
367
|
+
if (message.publicKey.length !== 0) {
|
|
368
|
+
writer.uint32(26).bytes(message.publicKey);
|
|
369
|
+
}
|
|
370
|
+
return writer;
|
|
371
|
+
},
|
|
372
|
+
decode(input, length) {
|
|
373
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
374
|
+
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
375
|
+
const message = createBaseSigningKeyshare();
|
|
376
|
+
while (reader.pos < end) {
|
|
377
|
+
const tag = reader.uint32();
|
|
378
|
+
switch (tag >>> 3) {
|
|
379
|
+
case 1: {
|
|
380
|
+
if (tag !== 10) {
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
message.ownerIdentifiers.push(reader.string());
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
case 2: {
|
|
387
|
+
if (tag !== 16) {
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
message.threshold = reader.uint32();
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
case 3: {
|
|
394
|
+
if (tag !== 26) {
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
message.publicKey = reader.bytes();
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
reader.skip(tag & 7);
|
|
405
|
+
}
|
|
406
|
+
return message;
|
|
407
|
+
},
|
|
408
|
+
fromJSON(object) {
|
|
409
|
+
return {
|
|
410
|
+
ownerIdentifiers: globalThis.Array.isArray(object?.ownerIdentifiers) ? object.ownerIdentifiers.map((e) => globalThis.String(e)) : [],
|
|
411
|
+
threshold: isSet(object.threshold) ? globalThis.Number(object.threshold) : 0,
|
|
412
|
+
publicKey: isSet(object.publicKey) ? bytesFromBase64(object.publicKey) : new Uint8Array(0)
|
|
413
|
+
};
|
|
414
|
+
},
|
|
415
|
+
toJSON(message) {
|
|
416
|
+
const obj = {};
|
|
417
|
+
if (message.ownerIdentifiers?.length) {
|
|
418
|
+
obj.ownerIdentifiers = message.ownerIdentifiers;
|
|
419
|
+
}
|
|
420
|
+
if (message.threshold !== 0) {
|
|
421
|
+
obj.threshold = Math.round(message.threshold);
|
|
422
|
+
}
|
|
423
|
+
if (message.publicKey.length !== 0) {
|
|
424
|
+
obj.publicKey = base64FromBytes(message.publicKey);
|
|
425
|
+
}
|
|
426
|
+
return obj;
|
|
427
|
+
},
|
|
428
|
+
create(base) {
|
|
429
|
+
return SigningKeyshare.fromPartial(base ?? {});
|
|
430
|
+
},
|
|
431
|
+
fromPartial(object) {
|
|
432
|
+
const message = createBaseSigningKeyshare();
|
|
433
|
+
message.ownerIdentifiers = object.ownerIdentifiers?.map((e) => e) || [];
|
|
434
|
+
message.threshold = object.threshold ?? 0;
|
|
435
|
+
message.publicKey = object.publicKey ?? new Uint8Array(0);
|
|
436
|
+
return message;
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
function createBaseTreeNode() {
|
|
440
|
+
return {
|
|
441
|
+
id: "",
|
|
442
|
+
treeId: "",
|
|
443
|
+
value: 0,
|
|
444
|
+
parentNodeId: void 0,
|
|
445
|
+
nodeTx: new Uint8Array(0),
|
|
446
|
+
refundTx: new Uint8Array(0),
|
|
447
|
+
vout: 0,
|
|
448
|
+
verifyingPublicKey: new Uint8Array(0),
|
|
449
|
+
ownerIdentityPublicKey: new Uint8Array(0),
|
|
450
|
+
signingKeyshare: void 0,
|
|
451
|
+
status: "",
|
|
452
|
+
network: 0
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
var TreeNode = {
|
|
456
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
457
|
+
if (message.id !== "") {
|
|
458
|
+
writer.uint32(10).string(message.id);
|
|
459
|
+
}
|
|
460
|
+
if (message.treeId !== "") {
|
|
461
|
+
writer.uint32(18).string(message.treeId);
|
|
462
|
+
}
|
|
463
|
+
if (message.value !== 0) {
|
|
464
|
+
writer.uint32(24).uint64(message.value);
|
|
465
|
+
}
|
|
466
|
+
if (message.parentNodeId !== void 0) {
|
|
467
|
+
writer.uint32(34).string(message.parentNodeId);
|
|
468
|
+
}
|
|
469
|
+
if (message.nodeTx.length !== 0) {
|
|
470
|
+
writer.uint32(42).bytes(message.nodeTx);
|
|
471
|
+
}
|
|
472
|
+
if (message.refundTx.length !== 0) {
|
|
473
|
+
writer.uint32(50).bytes(message.refundTx);
|
|
474
|
+
}
|
|
475
|
+
if (message.vout !== 0) {
|
|
476
|
+
writer.uint32(56).uint32(message.vout);
|
|
477
|
+
}
|
|
478
|
+
if (message.verifyingPublicKey.length !== 0) {
|
|
479
|
+
writer.uint32(66).bytes(message.verifyingPublicKey);
|
|
480
|
+
}
|
|
481
|
+
if (message.ownerIdentityPublicKey.length !== 0) {
|
|
482
|
+
writer.uint32(74).bytes(message.ownerIdentityPublicKey);
|
|
483
|
+
}
|
|
484
|
+
if (message.signingKeyshare !== void 0) {
|
|
485
|
+
SigningKeyshare.encode(message.signingKeyshare, writer.uint32(82).fork()).join();
|
|
486
|
+
}
|
|
487
|
+
if (message.status !== "") {
|
|
488
|
+
writer.uint32(90).string(message.status);
|
|
489
|
+
}
|
|
490
|
+
if (message.network !== 0) {
|
|
491
|
+
writer.uint32(96).int32(message.network);
|
|
492
|
+
}
|
|
493
|
+
return writer;
|
|
494
|
+
},
|
|
495
|
+
decode(input, length) {
|
|
496
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
497
|
+
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
498
|
+
const message = createBaseTreeNode();
|
|
499
|
+
while (reader.pos < end) {
|
|
500
|
+
const tag = reader.uint32();
|
|
501
|
+
switch (tag >>> 3) {
|
|
502
|
+
case 1: {
|
|
503
|
+
if (tag !== 10) {
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
message.id = reader.string();
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
case 2: {
|
|
510
|
+
if (tag !== 18) {
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
message.treeId = reader.string();
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
case 3: {
|
|
517
|
+
if (tag !== 24) {
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
message.value = longToNumber(reader.uint64());
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
case 4: {
|
|
524
|
+
if (tag !== 34) {
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
message.parentNodeId = reader.string();
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
case 5: {
|
|
531
|
+
if (tag !== 42) {
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
message.nodeTx = reader.bytes();
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
case 6: {
|
|
538
|
+
if (tag !== 50) {
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
message.refundTx = reader.bytes();
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
case 7: {
|
|
545
|
+
if (tag !== 56) {
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
message.vout = reader.uint32();
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
case 8: {
|
|
552
|
+
if (tag !== 66) {
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
message.verifyingPublicKey = reader.bytes();
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
case 9: {
|
|
559
|
+
if (tag !== 74) {
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
message.ownerIdentityPublicKey = reader.bytes();
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
case 10: {
|
|
566
|
+
if (tag !== 82) {
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
message.signingKeyshare = SigningKeyshare.decode(reader, reader.uint32());
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
case 11: {
|
|
573
|
+
if (tag !== 90) {
|
|
574
|
+
break;
|
|
575
|
+
}
|
|
576
|
+
message.status = reader.string();
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
case 12: {
|
|
580
|
+
if (tag !== 96) {
|
|
581
|
+
break;
|
|
582
|
+
}
|
|
583
|
+
message.network = reader.int32();
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
reader.skip(tag & 7);
|
|
591
|
+
}
|
|
592
|
+
return message;
|
|
593
|
+
},
|
|
594
|
+
fromJSON(object) {
|
|
595
|
+
return {
|
|
596
|
+
id: isSet(object.id) ? globalThis.String(object.id) : "",
|
|
597
|
+
treeId: isSet(object.treeId) ? globalThis.String(object.treeId) : "",
|
|
598
|
+
value: isSet(object.value) ? globalThis.Number(object.value) : 0,
|
|
599
|
+
parentNodeId: isSet(object.parentNodeId) ? globalThis.String(object.parentNodeId) : void 0,
|
|
600
|
+
nodeTx: isSet(object.nodeTx) ? bytesFromBase64(object.nodeTx) : new Uint8Array(0),
|
|
601
|
+
refundTx: isSet(object.refundTx) ? bytesFromBase64(object.refundTx) : new Uint8Array(0),
|
|
602
|
+
vout: isSet(object.vout) ? globalThis.Number(object.vout) : 0,
|
|
603
|
+
verifyingPublicKey: isSet(object.verifyingPublicKey) ? bytesFromBase64(object.verifyingPublicKey) : new Uint8Array(0),
|
|
604
|
+
ownerIdentityPublicKey: isSet(object.ownerIdentityPublicKey) ? bytesFromBase64(object.ownerIdentityPublicKey) : new Uint8Array(0),
|
|
605
|
+
signingKeyshare: isSet(object.signingKeyshare) ? SigningKeyshare.fromJSON(object.signingKeyshare) : void 0,
|
|
606
|
+
status: isSet(object.status) ? globalThis.String(object.status) : "",
|
|
607
|
+
network: isSet(object.network) ? networkFromJSON(object.network) : 0
|
|
608
|
+
};
|
|
609
|
+
},
|
|
610
|
+
toJSON(message) {
|
|
611
|
+
const obj = {};
|
|
612
|
+
if (message.id !== "") {
|
|
613
|
+
obj.id = message.id;
|
|
614
|
+
}
|
|
615
|
+
if (message.treeId !== "") {
|
|
616
|
+
obj.treeId = message.treeId;
|
|
617
|
+
}
|
|
618
|
+
if (message.value !== 0) {
|
|
619
|
+
obj.value = Math.round(message.value);
|
|
620
|
+
}
|
|
621
|
+
if (message.parentNodeId !== void 0) {
|
|
622
|
+
obj.parentNodeId = message.parentNodeId;
|
|
623
|
+
}
|
|
624
|
+
if (message.nodeTx.length !== 0) {
|
|
625
|
+
obj.nodeTx = base64FromBytes(message.nodeTx);
|
|
626
|
+
}
|
|
627
|
+
if (message.refundTx.length !== 0) {
|
|
628
|
+
obj.refundTx = base64FromBytes(message.refundTx);
|
|
629
|
+
}
|
|
630
|
+
if (message.vout !== 0) {
|
|
631
|
+
obj.vout = Math.round(message.vout);
|
|
632
|
+
}
|
|
633
|
+
if (message.verifyingPublicKey.length !== 0) {
|
|
634
|
+
obj.verifyingPublicKey = base64FromBytes(message.verifyingPublicKey);
|
|
635
|
+
}
|
|
636
|
+
if (message.ownerIdentityPublicKey.length !== 0) {
|
|
637
|
+
obj.ownerIdentityPublicKey = base64FromBytes(message.ownerIdentityPublicKey);
|
|
638
|
+
}
|
|
639
|
+
if (message.signingKeyshare !== void 0) {
|
|
640
|
+
obj.signingKeyshare = SigningKeyshare.toJSON(message.signingKeyshare);
|
|
641
|
+
}
|
|
642
|
+
if (message.status !== "") {
|
|
643
|
+
obj.status = message.status;
|
|
644
|
+
}
|
|
645
|
+
if (message.network !== 0) {
|
|
646
|
+
obj.network = networkToJSON(message.network);
|
|
647
|
+
}
|
|
648
|
+
return obj;
|
|
649
|
+
},
|
|
650
|
+
create(base) {
|
|
651
|
+
return TreeNode.fromPartial(base ?? {});
|
|
652
|
+
},
|
|
653
|
+
fromPartial(object) {
|
|
654
|
+
const message = createBaseTreeNode();
|
|
655
|
+
message.id = object.id ?? "";
|
|
656
|
+
message.treeId = object.treeId ?? "";
|
|
657
|
+
message.value = object.value ?? 0;
|
|
658
|
+
message.parentNodeId = object.parentNodeId ?? void 0;
|
|
659
|
+
message.nodeTx = object.nodeTx ?? new Uint8Array(0);
|
|
660
|
+
message.refundTx = object.refundTx ?? new Uint8Array(0);
|
|
661
|
+
message.vout = object.vout ?? 0;
|
|
662
|
+
message.verifyingPublicKey = object.verifyingPublicKey ?? new Uint8Array(0);
|
|
663
|
+
message.ownerIdentityPublicKey = object.ownerIdentityPublicKey ?? new Uint8Array(0);
|
|
664
|
+
message.signingKeyshare = object.signingKeyshare !== void 0 && object.signingKeyshare !== null ? SigningKeyshare.fromPartial(object.signingKeyshare) : void 0;
|
|
665
|
+
message.status = object.status ?? "";
|
|
666
|
+
message.network = object.network ?? 0;
|
|
667
|
+
return message;
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
function createBaseSparkAddress() {
|
|
671
|
+
return { identityPublicKey: new Uint8Array(0), paymentIntentFields: void 0 };
|
|
672
|
+
}
|
|
673
|
+
var SparkAddress = {
|
|
674
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
675
|
+
if (message.identityPublicKey.length !== 0) {
|
|
676
|
+
writer.uint32(10).bytes(message.identityPublicKey);
|
|
677
|
+
}
|
|
678
|
+
if (message.paymentIntentFields !== void 0) {
|
|
679
|
+
PaymentIntentFields.encode(message.paymentIntentFields, writer.uint32(18).fork()).join();
|
|
680
|
+
}
|
|
681
|
+
return writer;
|
|
682
|
+
},
|
|
683
|
+
decode(input, length) {
|
|
684
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
685
|
+
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
686
|
+
const message = createBaseSparkAddress();
|
|
687
|
+
while (reader.pos < end) {
|
|
688
|
+
const tag = reader.uint32();
|
|
689
|
+
switch (tag >>> 3) {
|
|
690
|
+
case 1: {
|
|
691
|
+
if (tag !== 10) {
|
|
692
|
+
break;
|
|
693
|
+
}
|
|
694
|
+
message.identityPublicKey = reader.bytes();
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
case 2: {
|
|
698
|
+
if (tag !== 18) {
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
message.paymentIntentFields = PaymentIntentFields.decode(reader, reader.uint32());
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
reader.skip(tag & 7);
|
|
709
|
+
}
|
|
710
|
+
return message;
|
|
711
|
+
},
|
|
712
|
+
fromJSON(object) {
|
|
713
|
+
return {
|
|
714
|
+
identityPublicKey: isSet(object.identityPublicKey) ? bytesFromBase64(object.identityPublicKey) : new Uint8Array(0),
|
|
715
|
+
paymentIntentFields: isSet(object.paymentIntentFields) ? PaymentIntentFields.fromJSON(object.paymentIntentFields) : void 0
|
|
716
|
+
};
|
|
717
|
+
},
|
|
718
|
+
toJSON(message) {
|
|
719
|
+
const obj = {};
|
|
720
|
+
if (message.identityPublicKey.length !== 0) {
|
|
721
|
+
obj.identityPublicKey = base64FromBytes(message.identityPublicKey);
|
|
722
|
+
}
|
|
723
|
+
if (message.paymentIntentFields !== void 0) {
|
|
724
|
+
obj.paymentIntentFields = PaymentIntentFields.toJSON(message.paymentIntentFields);
|
|
725
|
+
}
|
|
726
|
+
return obj;
|
|
727
|
+
},
|
|
728
|
+
create(base) {
|
|
729
|
+
return SparkAddress.fromPartial(base ?? {});
|
|
730
|
+
},
|
|
731
|
+
fromPartial(object) {
|
|
732
|
+
const message = createBaseSparkAddress();
|
|
733
|
+
message.identityPublicKey = object.identityPublicKey ?? new Uint8Array(0);
|
|
734
|
+
message.paymentIntentFields = object.paymentIntentFields !== void 0 && object.paymentIntentFields !== null ? PaymentIntentFields.fromPartial(object.paymentIntentFields) : void 0;
|
|
735
|
+
return message;
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
function createBasePaymentIntentFields() {
|
|
739
|
+
return { id: new Uint8Array(0), assetIdentifier: void 0, assetAmount: new Uint8Array(0), memo: void 0 };
|
|
740
|
+
}
|
|
741
|
+
var PaymentIntentFields = {
|
|
742
|
+
encode(message, writer = new import_wire4.BinaryWriter()) {
|
|
743
|
+
if (message.id.length !== 0) {
|
|
744
|
+
writer.uint32(10).bytes(message.id);
|
|
745
|
+
}
|
|
746
|
+
if (message.assetIdentifier !== void 0) {
|
|
747
|
+
writer.uint32(18).bytes(message.assetIdentifier);
|
|
748
|
+
}
|
|
749
|
+
if (message.assetAmount.length !== 0) {
|
|
750
|
+
writer.uint32(26).bytes(message.assetAmount);
|
|
751
|
+
}
|
|
752
|
+
if (message.memo !== void 0) {
|
|
753
|
+
writer.uint32(34).string(message.memo);
|
|
754
|
+
}
|
|
755
|
+
return writer;
|
|
756
|
+
},
|
|
757
|
+
decode(input, length) {
|
|
758
|
+
const reader = input instanceof import_wire4.BinaryReader ? input : new import_wire4.BinaryReader(input);
|
|
759
|
+
let end = length === void 0 ? reader.len : reader.pos + length;
|
|
760
|
+
const message = createBasePaymentIntentFields();
|
|
761
|
+
while (reader.pos < end) {
|
|
762
|
+
const tag = reader.uint32();
|
|
763
|
+
switch (tag >>> 3) {
|
|
764
|
+
case 1: {
|
|
765
|
+
if (tag !== 10) {
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
message.id = reader.bytes();
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
case 2: {
|
|
772
|
+
if (tag !== 18) {
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
message.assetIdentifier = reader.bytes();
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
case 3: {
|
|
779
|
+
if (tag !== 26) {
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
message.assetAmount = reader.bytes();
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
case 4: {
|
|
786
|
+
if (tag !== 34) {
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
message.memo = reader.string();
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
794
|
+
break;
|
|
795
|
+
}
|
|
796
|
+
reader.skip(tag & 7);
|
|
797
|
+
}
|
|
798
|
+
return message;
|
|
799
|
+
},
|
|
800
|
+
fromJSON(object) {
|
|
801
|
+
return {
|
|
802
|
+
id: isSet(object.id) ? bytesFromBase64(object.id) : new Uint8Array(0),
|
|
803
|
+
assetIdentifier: isSet(object.assetIdentifier) ? bytesFromBase64(object.assetIdentifier) : void 0,
|
|
804
|
+
assetAmount: isSet(object.assetAmount) ? bytesFromBase64(object.assetAmount) : new Uint8Array(0),
|
|
805
|
+
memo: isSet(object.memo) ? globalThis.String(object.memo) : void 0
|
|
806
|
+
};
|
|
807
|
+
},
|
|
808
|
+
toJSON(message) {
|
|
809
|
+
const obj = {};
|
|
810
|
+
if (message.id.length !== 0) {
|
|
811
|
+
obj.id = base64FromBytes(message.id);
|
|
812
|
+
}
|
|
813
|
+
if (message.assetIdentifier !== void 0) {
|
|
814
|
+
obj.assetIdentifier = base64FromBytes(message.assetIdentifier);
|
|
815
|
+
}
|
|
816
|
+
if (message.assetAmount.length !== 0) {
|
|
817
|
+
obj.assetAmount = base64FromBytes(message.assetAmount);
|
|
818
|
+
}
|
|
819
|
+
if (message.memo !== void 0) {
|
|
820
|
+
obj.memo = message.memo;
|
|
821
|
+
}
|
|
822
|
+
return obj;
|
|
823
|
+
},
|
|
824
|
+
create(base) {
|
|
825
|
+
return PaymentIntentFields.fromPartial(base ?? {});
|
|
826
|
+
},
|
|
827
|
+
fromPartial(object) {
|
|
828
|
+
const message = createBasePaymentIntentFields();
|
|
829
|
+
message.id = object.id ?? new Uint8Array(0);
|
|
830
|
+
message.assetIdentifier = object.assetIdentifier ?? void 0;
|
|
831
|
+
message.assetAmount = object.assetAmount ?? new Uint8Array(0);
|
|
832
|
+
message.memo = object.memo ?? void 0;
|
|
833
|
+
return message;
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
function bytesFromBase64(b64) {
|
|
837
|
+
if (globalThis.Buffer) {
|
|
838
|
+
return Uint8Array.from(globalThis.Buffer.from(b64, "base64"));
|
|
839
|
+
} else {
|
|
840
|
+
const bin = globalThis.atob(b64);
|
|
841
|
+
const arr = new Uint8Array(bin.length);
|
|
842
|
+
for (let i = 0; i < bin.length; ++i) {
|
|
843
|
+
arr[i] = bin.charCodeAt(i);
|
|
844
|
+
}
|
|
845
|
+
return arr;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
function base64FromBytes(arr) {
|
|
849
|
+
if (globalThis.Buffer) {
|
|
850
|
+
return globalThis.Buffer.from(arr).toString("base64");
|
|
851
|
+
} else {
|
|
852
|
+
const bin = [];
|
|
853
|
+
arr.forEach((byte) => {
|
|
854
|
+
bin.push(globalThis.String.fromCharCode(byte));
|
|
855
|
+
});
|
|
856
|
+
return globalThis.btoa(bin.join(""));
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function longToNumber(int64) {
|
|
860
|
+
const num = globalThis.Number(int64.toString());
|
|
861
|
+
if (num > globalThis.Number.MAX_SAFE_INTEGER) {
|
|
862
|
+
throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
|
|
863
|
+
}
|
|
864
|
+
if (num < globalThis.Number.MIN_SAFE_INTEGER) {
|
|
865
|
+
throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
|
|
866
|
+
}
|
|
867
|
+
return num;
|
|
868
|
+
}
|
|
869
|
+
function isSet(value) {
|
|
870
|
+
return value !== null && value !== void 0;
|
|
871
|
+
}
|
|
872
|
+
|
|
305
873
|
// src/graphql/objects/BitcoinNetwork.ts
|
|
306
874
|
var BitcoinNetwork = /* @__PURE__ */ ((BitcoinNetwork2) => {
|
|
307
875
|
BitcoinNetwork2["FUTURE_VALUE"] = "FUTURE_VALUE";
|
|
@@ -372,6 +940,14 @@ function getNetworkFromAddress(address2) {
|
|
|
372
940
|
}
|
|
373
941
|
return null;
|
|
374
942
|
}
|
|
943
|
+
function getNetworkFromString(network) {
|
|
944
|
+
const net = (network ?? "REGTEST").toUpperCase();
|
|
945
|
+
if (net === "MAINNET") return 0 /* MAINNET */;
|
|
946
|
+
if (net === "TESTNET") return 1 /* TESTNET */;
|
|
947
|
+
if (net === "SIGNET") return 2 /* SIGNET */;
|
|
948
|
+
if (net === "LOCAL") return 4 /* LOCAL */;
|
|
949
|
+
return 3 /* REGTEST */;
|
|
950
|
+
}
|
|
375
951
|
|
|
376
952
|
// src/utils/bitcoin.ts
|
|
377
953
|
function computeTaprootKeyNoScript(pubkey) {
|
|
@@ -743,6 +1319,7 @@ var BASE_CONFIG = {
|
|
|
743
1319
|
threshold: 2,
|
|
744
1320
|
signingOperators: getLocalSigningOperators(),
|
|
745
1321
|
tokenSignatures: "SCHNORR",
|
|
1322
|
+
tokenTransactionVersion: "V0",
|
|
746
1323
|
electrsUrl: getElectrsUrl("LOCAL"),
|
|
747
1324
|
expectedWithdrawBondSats: 1e4,
|
|
748
1325
|
expectedWithdrawRelativeBlockLocktime: 1e3,
|
|
@@ -921,6 +1498,23 @@ async function getLatestDepositTxId(address2) {
|
|
|
921
1498
|
}
|
|
922
1499
|
return null;
|
|
923
1500
|
}
|
|
1501
|
+
async function isTxBroadcast(txid, baseUrl, network) {
|
|
1502
|
+
const headers = {};
|
|
1503
|
+
if (network === 3 /* REGTEST */) {
|
|
1504
|
+
const auth = btoa(
|
|
1505
|
+
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`
|
|
1506
|
+
);
|
|
1507
|
+
headers["Authorization"] = `Basic ${auth}`;
|
|
1508
|
+
}
|
|
1509
|
+
const response = await fetch(`${baseUrl}/tx/${txid}`, {
|
|
1510
|
+
headers
|
|
1511
|
+
});
|
|
1512
|
+
const tx = await response.json();
|
|
1513
|
+
if (tx.error) {
|
|
1514
|
+
return false;
|
|
1515
|
+
}
|
|
1516
|
+
return true;
|
|
1517
|
+
}
|
|
924
1518
|
|
|
925
1519
|
// src/utils/proof.ts
|
|
926
1520
|
var import_sha22 = require("@noble/hashes/sha2");
|
|
@@ -1316,8 +1910,20 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
|
|
|
1316
1910
|
// src/utils/transaction.ts
|
|
1317
1911
|
var import_btc_signer = require("@scure/btc-signer");
|
|
1318
1912
|
var TIME_LOCK_INTERVAL = 100;
|
|
1913
|
+
var ESTIMATED_TX_SIZE = 191;
|
|
1914
|
+
var DEFAULT_SATS_PER_VBYTE = 5;
|
|
1915
|
+
var DEFAULT_FEE_SATS = ESTIMATED_TX_SIZE * DEFAULT_SATS_PER_VBYTE;
|
|
1916
|
+
function maybeApplyFee(amount) {
|
|
1917
|
+
if (amount > BigInt(DEFAULT_FEE_SATS)) {
|
|
1918
|
+
return amount - BigInt(DEFAULT_FEE_SATS);
|
|
1919
|
+
}
|
|
1920
|
+
return amount;
|
|
1921
|
+
}
|
|
1319
1922
|
function createRefundTx(sequence, nodeOutPoint, amountSats, receivingPubkey, network) {
|
|
1320
|
-
const newRefundTx = new import_btc_signer.Transaction({
|
|
1923
|
+
const newRefundTx = new import_btc_signer.Transaction({
|
|
1924
|
+
version: 3,
|
|
1925
|
+
allowUnknownOutputs: true
|
|
1926
|
+
});
|
|
1321
1927
|
newRefundTx.addInput({
|
|
1322
1928
|
...nodeOutPoint,
|
|
1323
1929
|
sequence
|
|
@@ -1337,17 +1943,35 @@ function getTransactionSequence(currSequence) {
|
|
|
1337
1943
|
const timelock = getCurrentTimelock(currSequence);
|
|
1338
1944
|
return 1 << 30 | timelock;
|
|
1339
1945
|
}
|
|
1946
|
+
function checkIfValidSequence(currSequence) {
|
|
1947
|
+
const TIME_LOCK_ACTIVE = (currSequence || 0) & 2147483648;
|
|
1948
|
+
if (TIME_LOCK_ACTIVE !== 0) {
|
|
1949
|
+
throw new ValidationError("Timelock not active", {
|
|
1950
|
+
field: "currSequence",
|
|
1951
|
+
value: currSequence
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1954
|
+
const RELATIVE_TIME_LOCK_ACTIVE = (currSequence || 0) & 4194304;
|
|
1955
|
+
if (RELATIVE_TIME_LOCK_ACTIVE !== 0) {
|
|
1956
|
+
throw new ValidationError("Block based timelock not active", {
|
|
1957
|
+
field: "currSequence",
|
|
1958
|
+
value: currSequence
|
|
1959
|
+
});
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1340
1962
|
function getNextTransactionSequence(currSequence, forRefresh) {
|
|
1963
|
+
checkIfValidSequence(currSequence);
|
|
1341
1964
|
const currentTimelock = getCurrentTimelock(currSequence);
|
|
1342
1965
|
const nextTimelock = currentTimelock - TIME_LOCK_INTERVAL;
|
|
1966
|
+
checkIfValidSequence(nextTimelock);
|
|
1343
1967
|
if (forRefresh && nextTimelock <= 100 && currentTimelock > 0) {
|
|
1344
1968
|
return {
|
|
1345
1969
|
nextSequence: 1 << 30 | nextTimelock,
|
|
1346
1970
|
needRefresh: true
|
|
1347
1971
|
};
|
|
1348
1972
|
}
|
|
1349
|
-
if (nextTimelock
|
|
1350
|
-
throw new ValidationError("timelock interval is less than
|
|
1973
|
+
if (nextTimelock < 100) {
|
|
1974
|
+
throw new ValidationError("timelock interval is less than 100", {
|
|
1351
1975
|
field: "nextTimelock",
|
|
1352
1976
|
value: nextTimelock
|
|
1353
1977
|
});
|
|
@@ -1364,8 +1988,541 @@ function getEphemeralAnchorOutput() {
|
|
|
1364
1988
|
amount: 0n
|
|
1365
1989
|
};
|
|
1366
1990
|
}
|
|
1991
|
+
|
|
1992
|
+
// src/utils/unilateral-exit.ts
|
|
1993
|
+
var import_utils8 = require("@noble/curves/abstract/utils");
|
|
1994
|
+
var import_legacy = require("@noble/hashes/legacy");
|
|
1995
|
+
var import_sha24 = require("@noble/hashes/sha2");
|
|
1996
|
+
var btc3 = __toESM(require("@scure/btc-signer"), 1);
|
|
1997
|
+
function isEphemeralAnchorOutput(script, amount) {
|
|
1998
|
+
return Boolean(
|
|
1999
|
+
amount === 0n && script && // Pattern 1: Bare OP_TRUE (single byte 0x51)
|
|
2000
|
+
(script.length === 1 && script[0] === 81 || // Pattern 2: Push OP_TRUE (two bytes 0x01 0x51) - MALFORMED but we detect it
|
|
2001
|
+
script.length === 2 && script[0] === 1 && script[1] === 81 || // Pattern 3: Bitcoin v29 ephemeral anchor script (7 bytes: 015152014e0173)
|
|
2002
|
+
script.length === 7 && script[0] === 1 && script[1] === 81 && script[2] === 82 && script[3] === 1 && script[4] === 78 && script[5] === 1 && script[6] === 115 || // Pattern 4: Bitcoin ephemeral anchor OP_1 + push 2 bytes (4 bytes: 51024e73)
|
|
2003
|
+
script.length === 4 && script[0] === 81 && script[1] === 2 && script[2] === 78 && script[3] === 115)
|
|
2004
|
+
);
|
|
2005
|
+
}
|
|
2006
|
+
async function constructUnilateralExitTxs(nodeHexStrings, sparkClient, network) {
|
|
2007
|
+
const result = [];
|
|
2008
|
+
const nodes = nodeHexStrings.map((hex) => TreeNode.decode((0, import_utils8.hexToBytes)(hex)));
|
|
2009
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
2010
|
+
for (const node of nodes) {
|
|
2011
|
+
nodeMap.set(node.id, node);
|
|
2012
|
+
}
|
|
2013
|
+
for (const node of nodes) {
|
|
2014
|
+
const transactions = [];
|
|
2015
|
+
const chain = [];
|
|
2016
|
+
let currentNode = node;
|
|
2017
|
+
while (currentNode) {
|
|
2018
|
+
chain.unshift(currentNode);
|
|
2019
|
+
if (currentNode.parentNodeId) {
|
|
2020
|
+
let parentNode = nodeMap.get(currentNode.parentNodeId);
|
|
2021
|
+
if (!parentNode && sparkClient) {
|
|
2022
|
+
try {
|
|
2023
|
+
const response = await sparkClient.query_nodes({
|
|
2024
|
+
source: {
|
|
2025
|
+
$case: "nodeIds",
|
|
2026
|
+
nodeIds: {
|
|
2027
|
+
nodeIds: [currentNode.parentNodeId]
|
|
2028
|
+
}
|
|
2029
|
+
},
|
|
2030
|
+
includeParents: true,
|
|
2031
|
+
network: network || 0
|
|
2032
|
+
// Default to mainnet if not provided
|
|
2033
|
+
});
|
|
2034
|
+
parentNode = response.nodes[currentNode.parentNodeId];
|
|
2035
|
+
if (parentNode) {
|
|
2036
|
+
nodeMap.set(currentNode.parentNodeId, parentNode);
|
|
2037
|
+
}
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
console.warn(
|
|
2040
|
+
`Failed to query parent node ${currentNode.parentNodeId}: ${error}`
|
|
2041
|
+
);
|
|
2042
|
+
break;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
if (parentNode) {
|
|
2046
|
+
currentNode = parentNode;
|
|
2047
|
+
} else {
|
|
2048
|
+
if (!sparkClient) {
|
|
2049
|
+
console.warn(
|
|
2050
|
+
`Parent node ${currentNode.parentNodeId} not found. Provide a sparkClient to fetch missing parents.`
|
|
2051
|
+
);
|
|
2052
|
+
} else {
|
|
2053
|
+
console.warn(
|
|
2054
|
+
`Parent node ${currentNode.parentNodeId} not found in database. Chain may be incomplete.`
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
break;
|
|
2058
|
+
}
|
|
2059
|
+
} else {
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
for (const chainNode of chain) {
|
|
2064
|
+
const nodeTx = (0, import_utils8.bytesToHex)(chainNode.nodeTx);
|
|
2065
|
+
transactions.push(nodeTx);
|
|
2066
|
+
if (chainNode.id === node.id) {
|
|
2067
|
+
const refundTx = (0, import_utils8.bytesToHex)(chainNode.refundTx);
|
|
2068
|
+
transactions.push(refundTx);
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
result.push({
|
|
2072
|
+
leafId: node.id,
|
|
2073
|
+
transactions
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
return result;
|
|
2077
|
+
}
|
|
2078
|
+
async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, feeRate, electrsUrl, sparkClient, network) {
|
|
2079
|
+
const result = [];
|
|
2080
|
+
const availableUtxos = [...utxos].sort((a, b) => {
|
|
2081
|
+
if (a.value > b.value) return -1;
|
|
2082
|
+
if (a.value < b.value) return 1;
|
|
2083
|
+
return 0;
|
|
2084
|
+
});
|
|
2085
|
+
const nodes = [];
|
|
2086
|
+
for (let i = 0; i < nodeHexStrings.length; i++) {
|
|
2087
|
+
const hex = nodeHexStrings[i];
|
|
2088
|
+
try {
|
|
2089
|
+
if (!hex || hex.length === 0) {
|
|
2090
|
+
throw new Error(`Node hex string at index ${i} is empty`);
|
|
2091
|
+
}
|
|
2092
|
+
if (hex.startsWith("03000000") || hex.startsWith("02000000") || hex.startsWith("01000000")) {
|
|
2093
|
+
throw new Error(
|
|
2094
|
+
`Node hex string at index ${i} appears to be a raw transaction hex, not a TreeNode protobuf. Use 'leafidtohex' command to convert node IDs to proper hex strings.`
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
const nodeBytes = (0, import_utils8.hexToBytes)(hex);
|
|
2098
|
+
const node = TreeNode.decode(nodeBytes);
|
|
2099
|
+
if (!node.id) {
|
|
2100
|
+
throw new Error(
|
|
2101
|
+
`Decoded TreeNode at index ${i} is missing required 'id' field`
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
if (!node.nodeTx || node.nodeTx.length === 0) {
|
|
2105
|
+
throw new Error(
|
|
2106
|
+
`Decoded TreeNode at index ${i} is missing required 'nodeTx' field`
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
nodes.push(node);
|
|
2110
|
+
} catch (decodeError) {
|
|
2111
|
+
throw new Error(
|
|
2112
|
+
`Failed to decode TreeNode hex string at index ${i}: ${decodeError}. Make sure you're providing TreeNode protobuf hex strings, not raw transaction hex. Use 'leafidtohex' command to get proper hex strings.`
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
const nodeMap = /* @__PURE__ */ new Map();
|
|
2117
|
+
for (const node of nodes) {
|
|
2118
|
+
nodeMap.set(node.id, node);
|
|
2119
|
+
}
|
|
2120
|
+
const broadcastTxs = /* @__PURE__ */ new Map();
|
|
2121
|
+
for (const node of nodes) {
|
|
2122
|
+
const txPackages = [];
|
|
2123
|
+
let previousFeeBumpTx;
|
|
2124
|
+
const chain = [];
|
|
2125
|
+
let currentNode = node;
|
|
2126
|
+
while (currentNode) {
|
|
2127
|
+
chain.unshift(currentNode);
|
|
2128
|
+
if (currentNode.parentNodeId) {
|
|
2129
|
+
let parentNode = nodeMap.get(currentNode.parentNodeId);
|
|
2130
|
+
if (!parentNode && sparkClient) {
|
|
2131
|
+
try {
|
|
2132
|
+
const response = await sparkClient.query_nodes({
|
|
2133
|
+
source: {
|
|
2134
|
+
$case: "nodeIds",
|
|
2135
|
+
nodeIds: {
|
|
2136
|
+
nodeIds: [currentNode.parentNodeId]
|
|
2137
|
+
}
|
|
2138
|
+
},
|
|
2139
|
+
includeParents: true,
|
|
2140
|
+
network: network || 0
|
|
2141
|
+
// Default to mainnet if not provided
|
|
2142
|
+
});
|
|
2143
|
+
parentNode = response.nodes[currentNode.parentNodeId];
|
|
2144
|
+
if (parentNode) {
|
|
2145
|
+
nodeMap.set(currentNode.parentNodeId, parentNode);
|
|
2146
|
+
}
|
|
2147
|
+
} catch (error) {
|
|
2148
|
+
console.warn(
|
|
2149
|
+
`Failed to query parent node ${currentNode.parentNodeId}: ${error}`
|
|
2150
|
+
);
|
|
2151
|
+
break;
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
if (parentNode) {
|
|
2155
|
+
currentNode = parentNode;
|
|
2156
|
+
} else {
|
|
2157
|
+
if (!sparkClient) {
|
|
2158
|
+
console.warn(
|
|
2159
|
+
`Parent node ${currentNode.parentNodeId} not found. Provide a sparkClient to fetch missing parents.`
|
|
2160
|
+
);
|
|
2161
|
+
} else {
|
|
2162
|
+
console.warn(
|
|
2163
|
+
`Parent node ${currentNode.parentNodeId} not found in database. Chain may be incomplete.`
|
|
2164
|
+
);
|
|
2165
|
+
}
|
|
2166
|
+
break;
|
|
2167
|
+
}
|
|
2168
|
+
} else {
|
|
2169
|
+
break;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
for (const chainNode of chain) {
|
|
2173
|
+
let nodeTxHex = (0, import_utils8.bytesToHex)(chainNode.nodeTx);
|
|
2174
|
+
try {
|
|
2175
|
+
const txObj = getTxFromRawTxHex(nodeTxHex);
|
|
2176
|
+
const txid = getTxId(txObj);
|
|
2177
|
+
if (broadcastTxs.get(txid)) {
|
|
2178
|
+
continue;
|
|
2179
|
+
}
|
|
2180
|
+
broadcastTxs.set(txid, true);
|
|
2181
|
+
const isBroadcast = await isTxBroadcast(txid, electrsUrl, network);
|
|
2182
|
+
if (isBroadcast) {
|
|
2183
|
+
continue;
|
|
2184
|
+
} else {
|
|
2185
|
+
}
|
|
2186
|
+
let anchorOutputScriptHex;
|
|
2187
|
+
for (let i = txObj.outputsLength - 1; i >= 0; i--) {
|
|
2188
|
+
const output = txObj.getOutput(i);
|
|
2189
|
+
if (output?.amount === 0n && output.script) {
|
|
2190
|
+
anchorOutputScriptHex = (0, import_utils8.bytesToHex)(output.script);
|
|
2191
|
+
break;
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
} catch (parseError) {
|
|
2195
|
+
console.error(
|
|
2196
|
+
`\u274C Error parsing nodeTx for anchor check (node ${chainNode.id}): ${parseError}`
|
|
2197
|
+
);
|
|
2198
|
+
console.log(
|
|
2199
|
+
` This may indicate a corrupted transaction in the TreeNode.`
|
|
2200
|
+
);
|
|
2201
|
+
console.log(` Transaction hex: ${nodeTxHex}`);
|
|
2202
|
+
console.log(
|
|
2203
|
+
` Attempting to continue with original hex, but fee bump may fail.`
|
|
2204
|
+
);
|
|
2205
|
+
}
|
|
2206
|
+
const {
|
|
2207
|
+
feeBumpPsbt: nodeFeeBumpPsbt,
|
|
2208
|
+
usedUtxos,
|
|
2209
|
+
correctedParentTx
|
|
2210
|
+
} = constructFeeBumpTx(nodeTxHex, availableUtxos, feeRate, void 0);
|
|
2211
|
+
const feeBumpTx = btc3.Transaction.fromPSBT((0, import_utils8.hexToBytes)(nodeFeeBumpPsbt));
|
|
2212
|
+
var feeBumpOut = feeBumpTx.outputsLength === 1 ? feeBumpTx.getOutput(0) : null;
|
|
2213
|
+
var feeBumpOutPubKey = null;
|
|
2214
|
+
for (const usedUtxo of usedUtxos) {
|
|
2215
|
+
if (feeBumpOut && (0, import_utils8.bytesToHex)(feeBumpOut.script) == usedUtxo.script) {
|
|
2216
|
+
feeBumpOutPubKey = usedUtxo.publicKey;
|
|
2217
|
+
}
|
|
2218
|
+
const index = availableUtxos.findIndex(
|
|
2219
|
+
(u) => u.txid === usedUtxo.txid && u.vout === usedUtxo.vout
|
|
2220
|
+
);
|
|
2221
|
+
if (index !== -1) {
|
|
2222
|
+
availableUtxos.splice(index, 1);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
if (feeBumpOut)
|
|
2226
|
+
availableUtxos.unshift({
|
|
2227
|
+
txid: getTxId(feeBumpTx),
|
|
2228
|
+
vout: 0,
|
|
2229
|
+
value: feeBumpOut.amount,
|
|
2230
|
+
script: (0, import_utils8.bytesToHex)(feeBumpOut.script),
|
|
2231
|
+
publicKey: feeBumpOutPubKey
|
|
2232
|
+
});
|
|
2233
|
+
const finalNodeTx = correctedParentTx || nodeTxHex;
|
|
2234
|
+
txPackages.push({ tx: finalNodeTx, feeBumpPsbt: nodeFeeBumpPsbt });
|
|
2235
|
+
if (chainNode.id === node.id) {
|
|
2236
|
+
let refundTxHex = (0, import_utils8.bytesToHex)(chainNode.refundTx);
|
|
2237
|
+
try {
|
|
2238
|
+
const txObj = getTxFromRawTxHex(refundTxHex);
|
|
2239
|
+
let anchorOutputScriptHex;
|
|
2240
|
+
for (let i = txObj.outputsLength - 1; i >= 0; i--) {
|
|
2241
|
+
const output = txObj.getOutput(i);
|
|
2242
|
+
if (output?.amount === 0n && output.script) {
|
|
2243
|
+
anchorOutputScriptHex = (0, import_utils8.bytesToHex)(output.script);
|
|
2244
|
+
break;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
} catch (parseError) {
|
|
2248
|
+
console.error(
|
|
2249
|
+
`\u274C Error parsing refundTx for anchor check (node ${chainNode.id}): ${parseError}`
|
|
2250
|
+
);
|
|
2251
|
+
console.log(
|
|
2252
|
+
` This may indicate a corrupted refund transaction in the TreeNode.`
|
|
2253
|
+
);
|
|
2254
|
+
console.log(` Refund transaction hex: ${refundTxHex}`);
|
|
2255
|
+
console.log(
|
|
2256
|
+
` Attempting to continue with original refund hex, but this transaction may be invalid.`
|
|
2257
|
+
);
|
|
2258
|
+
}
|
|
2259
|
+
const refundFeeBump = constructFeeBumpTx(
|
|
2260
|
+
refundTxHex,
|
|
2261
|
+
availableUtxos,
|
|
2262
|
+
feeRate,
|
|
2263
|
+
void 0
|
|
2264
|
+
);
|
|
2265
|
+
txPackages.push({
|
|
2266
|
+
tx: refundTxHex,
|
|
2267
|
+
feeBumpPsbt: refundFeeBump.feeBumpPsbt
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
result.push({
|
|
2272
|
+
leafId: node.id,
|
|
2273
|
+
txPackages
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
return result;
|
|
2277
|
+
}
|
|
2278
|
+
function hash160(data) {
|
|
2279
|
+
const sha256Hash = (0, import_sha24.sha256)(data);
|
|
2280
|
+
return (0, import_legacy.ripemd160)(sha256Hash);
|
|
2281
|
+
}
|
|
2282
|
+
function constructFeeBumpTx(txHex, utxos, feeRate, previousFeeBumpTx) {
|
|
2283
|
+
if (!txHex || txHex.length === 0) {
|
|
2284
|
+
throw new Error("Transaction hex string is empty or undefined");
|
|
2285
|
+
}
|
|
2286
|
+
if (utxos.length === 0) {
|
|
2287
|
+
throw new Error("No UTXOs available for fee bump");
|
|
2288
|
+
}
|
|
2289
|
+
let correctedTxHex = txHex;
|
|
2290
|
+
let parentTx;
|
|
2291
|
+
try {
|
|
2292
|
+
parentTx = getTxFromRawTxHex(correctedTxHex);
|
|
2293
|
+
if (!parentTx) {
|
|
2294
|
+
throw new Error("getTxFromRawTxHex returned null/undefined");
|
|
2295
|
+
}
|
|
2296
|
+
} catch (parseError) {
|
|
2297
|
+
throw new Error(
|
|
2298
|
+
`Failed to parse parent transaction hex: ${parseError}. Transaction hex: ${correctedTxHex}`
|
|
2299
|
+
);
|
|
2300
|
+
}
|
|
2301
|
+
try {
|
|
2302
|
+
const outputsLength = parentTx.outputsLength;
|
|
2303
|
+
const inputsLength = parentTx.inputsLength;
|
|
2304
|
+
if (typeof outputsLength !== "number" || outputsLength < 0) {
|
|
2305
|
+
throw new Error(
|
|
2306
|
+
"Invalid transaction: outputsLength is not a valid number"
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
if (typeof inputsLength !== "number" || inputsLength < 0) {
|
|
2310
|
+
throw new Error(
|
|
2311
|
+
"Invalid transaction: inputsLength is not a valid number"
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2314
|
+
} catch (validationError) {
|
|
2315
|
+
throw new Error(
|
|
2316
|
+
`Transaction validation failed: ${validationError}. This may indicate a corrupted or malformed transaction.`
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2319
|
+
const parentTxIdFromLib = parentTx.id;
|
|
2320
|
+
let ephemeralAnchorIndex = -1;
|
|
2321
|
+
for (let i = 0; i < parentTx.outputsLength; i++) {
|
|
2322
|
+
const output = parentTx.getOutput(i);
|
|
2323
|
+
const isEphemeralAnchor = isEphemeralAnchorOutput(
|
|
2324
|
+
output?.script,
|
|
2325
|
+
output?.amount
|
|
2326
|
+
);
|
|
2327
|
+
if (isEphemeralAnchor) {
|
|
2328
|
+
ephemeralAnchorIndex = i;
|
|
2329
|
+
break;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
if (ephemeralAnchorIndex === -1) {
|
|
2333
|
+
throw new Error(
|
|
2334
|
+
"No ephemeral anchor output found in parent transaction. Expected a 0-value output with OP_TRUE script (0x51), malformed OP_TRUE (0x0151), Bitcoin v29 ephemeral anchor script (015152014e0173), or Bitcoin OP_1 + push 2 bytes script (51024e73)."
|
|
2335
|
+
);
|
|
2336
|
+
}
|
|
2337
|
+
const ephemeralAnchorOutput = parentTx.getOutput(ephemeralAnchorIndex);
|
|
2338
|
+
if (!ephemeralAnchorOutput)
|
|
2339
|
+
throw new Error("No ephemeral anchor output found");
|
|
2340
|
+
if (!ephemeralAnchorOutput.script)
|
|
2341
|
+
throw new Error("No script found in ephemeral anchor output");
|
|
2342
|
+
if (utxos.length === 0) {
|
|
2343
|
+
throw new Error("No UTXOs available for fee bump");
|
|
2344
|
+
}
|
|
2345
|
+
const builder = new btc3.Transaction({
|
|
2346
|
+
version: 3,
|
|
2347
|
+
allowUnknown: true,
|
|
2348
|
+
allowLegacyWitnessUtxo: true
|
|
2349
|
+
});
|
|
2350
|
+
let totalValue = 0n;
|
|
2351
|
+
const processedUtxos = [];
|
|
2352
|
+
for (let i = 0; i < utxos.length; i++) {
|
|
2353
|
+
const fundingUtxo = utxos[i];
|
|
2354
|
+
if (!fundingUtxo) {
|
|
2355
|
+
throw new Error(`UTXO at index ${i} is undefined`);
|
|
2356
|
+
}
|
|
2357
|
+
const pubKeyHash = hash160((0, import_utils8.hexToBytes)(fundingUtxo.publicKey));
|
|
2358
|
+
const scriptToUse = new Uint8Array([0, 20, ...pubKeyHash]);
|
|
2359
|
+
const providedScript = (0, import_utils8.hexToBytes)(fundingUtxo.script);
|
|
2360
|
+
if ((0, import_utils8.bytesToHex)(scriptToUse) !== (0, import_utils8.bytesToHex)(providedScript)) {
|
|
2361
|
+
throw new Error(
|
|
2362
|
+
`\u274C Derived script doesn't match provided script for UTXO ${i + 1}.`
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
builder.addInput({
|
|
2366
|
+
txid: fundingUtxo.txid,
|
|
2367
|
+
index: fundingUtxo.vout,
|
|
2368
|
+
sequence: 4294967295,
|
|
2369
|
+
witnessUtxo: {
|
|
2370
|
+
script: scriptToUse,
|
|
2371
|
+
// Always P2WPKH
|
|
2372
|
+
amount: fundingUtxo.value
|
|
2373
|
+
}
|
|
2374
|
+
});
|
|
2375
|
+
totalValue += fundingUtxo.value;
|
|
2376
|
+
processedUtxos.push({
|
|
2377
|
+
utxo: fundingUtxo,
|
|
2378
|
+
p2wpkhScript: scriptToUse
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
builder.addInput({
|
|
2382
|
+
txid: parentTxIdFromLib,
|
|
2383
|
+
index: ephemeralAnchorIndex,
|
|
2384
|
+
sequence: 4294967295,
|
|
2385
|
+
witnessUtxo: {
|
|
2386
|
+
script: ephemeralAnchorOutput.script,
|
|
2387
|
+
// Use the original script directly (not P2WSH wrapped)
|
|
2388
|
+
amount: 0n
|
|
2389
|
+
}
|
|
2390
|
+
});
|
|
2391
|
+
const fee = 1500n;
|
|
2392
|
+
const remainingValue = totalValue - fee;
|
|
2393
|
+
if (remainingValue <= 0n) {
|
|
2394
|
+
throw new Error(
|
|
2395
|
+
`Insufficient funds for fee bump. Required fee: ${fee} sats, Available: ${totalValue} sats`
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
if (processedUtxos.length === 0) {
|
|
2399
|
+
throw new Error("No processed UTXOs available for change output");
|
|
2400
|
+
}
|
|
2401
|
+
const firstProcessedUtxo = processedUtxos[0];
|
|
2402
|
+
if (!firstProcessedUtxo) {
|
|
2403
|
+
throw new Error("First processed UTXO is undefined");
|
|
2404
|
+
}
|
|
2405
|
+
builder.addOutput({
|
|
2406
|
+
script: firstProcessedUtxo.p2wpkhScript,
|
|
2407
|
+
amount: remainingValue
|
|
2408
|
+
});
|
|
2409
|
+
for (let i = 0; i < processedUtxos.length; i++) {
|
|
2410
|
+
const processed = processedUtxos[i];
|
|
2411
|
+
if (!processed) {
|
|
2412
|
+
throw new Error(`Processed UTXO at index ${i} is undefined`);
|
|
2413
|
+
}
|
|
2414
|
+
try {
|
|
2415
|
+
builder.updateInput(i, {
|
|
2416
|
+
witnessScript: processed.p2wpkhScript
|
|
2417
|
+
});
|
|
2418
|
+
builder.signIdx;
|
|
2419
|
+
} catch (error) {
|
|
2420
|
+
throw new Error(`Failed to handle funding UTXO input ${i + 1}: ${error}`);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
let psbtHex;
|
|
2424
|
+
try {
|
|
2425
|
+
psbtHex = (0, import_utils8.bytesToHex)(builder.toPSBT());
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
throw new Error(`Failed to extract transaction: ${error}`);
|
|
2428
|
+
}
|
|
2429
|
+
return {
|
|
2430
|
+
feeBumpPsbt: psbtHex,
|
|
2431
|
+
usedUtxos: utxos,
|
|
2432
|
+
correctedParentTx: correctedTxHex !== txHex ? correctedTxHex : void 0
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
// src/address/address.ts
|
|
2437
|
+
var import_secp256k16 = require("@noble/curves/secp256k1");
|
|
2438
|
+
var import_utils9 = require("@noble/hashes/utils");
|
|
2439
|
+
var import_base2 = require("@scure/base");
|
|
2440
|
+
var import_uuidv7 = require("uuidv7");
|
|
2441
|
+
var import_utils10 = require("@noble/curves/abstract/utils");
|
|
2442
|
+
var AddressNetwork = {
|
|
2443
|
+
MAINNET: "sp",
|
|
2444
|
+
TESTNET: "spt",
|
|
2445
|
+
REGTEST: "sprt",
|
|
2446
|
+
SIGNET: "sps",
|
|
2447
|
+
LOCAL: "spl"
|
|
2448
|
+
};
|
|
2449
|
+
function encodeSparkAddress(payload) {
|
|
2450
|
+
try {
|
|
2451
|
+
isValidPublicKey(payload.identityPublicKey);
|
|
2452
|
+
let paymentIntentFields;
|
|
2453
|
+
if (payload.paymentIntentFields) {
|
|
2454
|
+
paymentIntentFields = payload.paymentIntentFields;
|
|
2455
|
+
}
|
|
2456
|
+
const sparkAddressProto = SparkAddress.create({
|
|
2457
|
+
identityPublicKey: (0, import_utils9.hexToBytes)(payload.identityPublicKey),
|
|
2458
|
+
paymentIntentFields
|
|
2459
|
+
});
|
|
2460
|
+
const serializedPayload = SparkAddress.encode(sparkAddressProto).finish();
|
|
2461
|
+
const words = import_base2.bech32m.toWords(serializedPayload);
|
|
2462
|
+
return import_base2.bech32m.encode(
|
|
2463
|
+
AddressNetwork[payload.network],
|
|
2464
|
+
words,
|
|
2465
|
+
500
|
|
2466
|
+
);
|
|
2467
|
+
} catch (error) {
|
|
2468
|
+
throw new ValidationError(
|
|
2469
|
+
"Failed to encode Spark address",
|
|
2470
|
+
{
|
|
2471
|
+
field: "publicKey",
|
|
2472
|
+
value: payload.identityPublicKey
|
|
2473
|
+
},
|
|
2474
|
+
error
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
function isValidPublicKey(publicKey) {
|
|
2479
|
+
try {
|
|
2480
|
+
const point = import_secp256k16.secp256k1.ProjectivePoint.fromHex(publicKey);
|
|
2481
|
+
point.assertValidity();
|
|
2482
|
+
} catch (error) {
|
|
2483
|
+
throw new ValidationError(
|
|
2484
|
+
"Invalid public key",
|
|
2485
|
+
{
|
|
2486
|
+
field: "publicKey",
|
|
2487
|
+
value: publicKey
|
|
2488
|
+
},
|
|
2489
|
+
error
|
|
2490
|
+
);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
// src/utils/xchain-address.ts
|
|
2495
|
+
var btc4 = __toESM(require("@scure/btc-signer"), 1);
|
|
2496
|
+
var networkByType = {
|
|
2497
|
+
MAINNET: btc4.NETWORK,
|
|
2498
|
+
TESTNET: btc4.TEST_NETWORK,
|
|
2499
|
+
REGTEST: {
|
|
2500
|
+
...btc4.TEST_NETWORK,
|
|
2501
|
+
bech32: "bcrt"
|
|
2502
|
+
}
|
|
2503
|
+
};
|
|
2504
|
+
function getSparkAddressFromTaproot(taprootAddress) {
|
|
2505
|
+
for (const networkType of ["MAINNET", "TESTNET", "REGTEST"]) {
|
|
2506
|
+
try {
|
|
2507
|
+
const result = btc4.Address(networkByType[networkType]).decode(taprootAddress);
|
|
2508
|
+
if (result.type === "tr") {
|
|
2509
|
+
const outputPublicKey = result.pubkey;
|
|
2510
|
+
return encodeSparkAddress({
|
|
2511
|
+
identityPublicKey: import_buffer.Buffer.concat([
|
|
2512
|
+
import_buffer.Buffer.from([2]),
|
|
2513
|
+
outputPublicKey
|
|
2514
|
+
]).toString("hex"),
|
|
2515
|
+
network: networkType
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
} catch (_) {
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
throw new ValidationError("Invalid taproot address");
|
|
2522
|
+
}
|
|
1367
2523
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1368
2524
|
0 && (module.exports = {
|
|
2525
|
+
DEFAULT_FEE_SATS,
|
|
1369
2526
|
LRC_WALLET_NETWORK,
|
|
1370
2527
|
LRC_WALLET_NETWORK_TYPE,
|
|
1371
2528
|
Network,
|
|
@@ -1377,9 +2534,13 @@ function getEphemeralAnchorOutput() {
|
|
|
1377
2534
|
bigIntToPrivateKey,
|
|
1378
2535
|
calculateAvailableTokenAmount,
|
|
1379
2536
|
checkIfSelectedOutputsAreAvailable,
|
|
2537
|
+
checkIfValidSequence,
|
|
1380
2538
|
collectResponses,
|
|
1381
2539
|
computeTaprootKeyNoScript,
|
|
1382
2540
|
computerLagrangeCoefficients,
|
|
2541
|
+
constructFeeBumpTx,
|
|
2542
|
+
constructUnilateralExitFeeBumpPackages,
|
|
2543
|
+
constructUnilateralExitTxs,
|
|
1383
2544
|
createRefundTx,
|
|
1384
2545
|
createSigningCommitment,
|
|
1385
2546
|
createSigningNonce,
|
|
@@ -1398,6 +2559,7 @@ function getEphemeralAnchorOutput() {
|
|
|
1398
2559
|
getLatestDepositTxId,
|
|
1399
2560
|
getNetwork,
|
|
1400
2561
|
getNetworkFromAddress,
|
|
2562
|
+
getNetworkFromString,
|
|
1401
2563
|
getNextTransactionSequence,
|
|
1402
2564
|
getP2TRAddressFromPkScript,
|
|
1403
2565
|
getP2TRAddressFromPublicKey,
|
|
@@ -1407,13 +2569,17 @@ function getEphemeralAnchorOutput() {
|
|
|
1407
2569
|
getRandomSigningNonce,
|
|
1408
2570
|
getSigHashFromTx,
|
|
1409
2571
|
getSigningCommitmentFromNonce,
|
|
2572
|
+
getSparkAddressFromTaproot,
|
|
1410
2573
|
getTransactionSequence,
|
|
1411
2574
|
getTransferPackageSigningPayload,
|
|
1412
2575
|
getTxFromRawTxBytes,
|
|
1413
2576
|
getTxFromRawTxHex,
|
|
1414
2577
|
getTxId,
|
|
1415
2578
|
getTxIdNoReverse,
|
|
2579
|
+
isEphemeralAnchorOutput,
|
|
2580
|
+
isTxBroadcast,
|
|
1416
2581
|
lastKeyWithTarget,
|
|
2582
|
+
maybeApplyFee,
|
|
1417
2583
|
modInverse,
|
|
1418
2584
|
proofOfPossessionMessageHashForDepositAddress,
|
|
1419
2585
|
recoverSecret,
|