@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.
Files changed (125) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/dist/{RequestLightningSendInput-39_zGri6.d.cts → RequestLightningSendInput-DXcLoiCe.d.cts} +10 -2
  4. package/dist/{RequestLightningSendInput-B4JdzclX.d.ts → RequestLightningSendInput-mXUWn_cp.d.ts} +10 -2
  5. package/dist/address/index.cjs +138 -6
  6. package/dist/address/index.d.cts +18 -6
  7. package/dist/address/index.d.ts +18 -6
  8. package/dist/address/index.js +5 -2
  9. package/dist/{chunk-FWQPAPXK.js → chunk-2ZXXLPG2.js} +1 -1
  10. package/dist/{chunk-S7KD6DDL.js → chunk-6YVPOQ2A.js} +41 -20
  11. package/dist/{chunk-ZUVYYR5T.js → chunk-7EFSUADA.js} +1 -0
  12. package/dist/{chunk-NS4UZRQ7.js → chunk-ABZA6R5S.js} +1 -1
  13. package/dist/{chunk-57XLH3ZR.js → chunk-ATEHMLKP.js} +23 -23
  14. package/dist/{chunk-VJTDG4BQ.js → chunk-HK6LPV6Z.js} +10 -1
  15. package/dist/{chunk-W3EC5XSA.js → chunk-J5W5Q2ZP.js} +337 -72
  16. package/dist/{chunk-TKYOYOYJ.js → chunk-KKSU7OZO.js} +653 -76
  17. package/dist/chunk-L3EHBOUX.js +0 -0
  18. package/dist/{chunk-C5LTJBI7.js → chunk-M6A4KFIG.js} +125 -226
  19. package/dist/{chunk-A74XSEW3.js → chunk-MIVX3GHD.js} +1 -1
  20. package/dist/{chunk-RGWBSZIO.js → chunk-ROKY5KS4.js} +23 -3
  21. package/dist/{chunk-LIP2K6KR.js → chunk-TM4TOEOX.js} +26 -8
  22. package/dist/{chunk-RAPBVYJY.js → chunk-UKT6OFLO.js} +125 -35
  23. package/dist/chunk-VA7MV4MZ.js +1073 -0
  24. package/dist/chunk-YEZDPUFY.js +840 -0
  25. package/dist/{chunk-DI7QXUQJ.js → chunk-ZXDE2XMU.js} +8 -5
  26. package/dist/graphql/objects/index.cjs +6 -3
  27. package/dist/graphql/objects/index.d.cts +6 -5
  28. package/dist/graphql/objects/index.d.ts +6 -5
  29. package/dist/graphql/objects/index.js +1 -1
  30. package/dist/{index-DEo_hdN3.d.cts → index-CFh4uWzi.d.cts} +60 -6
  31. package/dist/{index-BVY0yH_H.d.ts → index-OSDtPMmC.d.ts} +60 -6
  32. package/dist/index.cjs +3316 -954
  33. package/dist/index.d.cts +9 -8
  34. package/dist/index.d.ts +9 -8
  35. package/dist/index.js +48 -26
  36. package/dist/index.node.cjs +3316 -954
  37. package/dist/index.node.d.cts +9 -8
  38. package/dist/index.node.d.ts +9 -8
  39. package/dist/index.node.js +48 -26
  40. package/dist/native/index.cjs +3323 -961
  41. package/dist/native/index.d.cts +542 -260
  42. package/dist/native/index.d.ts +542 -260
  43. package/dist/native/index.js +3192 -838
  44. package/dist/{network-DobHpaV6.d.ts → network-BF2GYPye.d.ts} +9 -2
  45. package/dist/{network-GFGEHkS4.d.cts → network-BiwBmoOg.d.cts} +9 -2
  46. package/dist/proto/lrc20.d.cts +1 -1
  47. package/dist/proto/lrc20.d.ts +1 -1
  48. package/dist/proto/lrc20.js +2 -2
  49. package/dist/proto/spark.cjs +125 -226
  50. package/dist/proto/spark.d.cts +1 -1
  51. package/dist/proto/spark.d.ts +1 -1
  52. package/dist/proto/spark.js +3 -5
  53. package/dist/proto/spark_token.cjs +1364 -0
  54. package/dist/proto/spark_token.d.cts +209 -0
  55. package/dist/proto/spark_token.d.ts +209 -0
  56. package/dist/proto/spark_token.js +32 -0
  57. package/dist/{sdk-types-BuVMn2rX.d.cts → sdk-types-CfhdFnsA.d.cts} +1 -1
  58. package/dist/{sdk-types-BeI6DM_M.d.ts → sdk-types-MnQrHolg.d.ts} +1 -1
  59. package/dist/services/config.cjs +64 -40
  60. package/dist/services/config.d.cts +6 -5
  61. package/dist/services/config.d.ts +6 -5
  62. package/dist/services/config.js +7 -7
  63. package/dist/services/connection.cjs +1108 -306
  64. package/dist/services/connection.d.cts +10 -5
  65. package/dist/services/connection.d.ts +10 -5
  66. package/dist/services/connection.js +3 -2
  67. package/dist/services/index.cjs +1702 -488
  68. package/dist/services/index.d.cts +6 -5
  69. package/dist/services/index.d.ts +6 -5
  70. package/dist/services/index.js +16 -14
  71. package/dist/services/lrc-connection.d.cts +5 -5
  72. package/dist/services/lrc-connection.d.ts +5 -5
  73. package/dist/services/lrc-connection.js +3 -3
  74. package/dist/services/token-transactions.cjs +637 -247
  75. package/dist/services/token-transactions.d.cts +19 -8
  76. package/dist/services/token-transactions.d.ts +19 -8
  77. package/dist/services/token-transactions.js +5 -4
  78. package/dist/services/wallet-config.cjs +1 -0
  79. package/dist/services/wallet-config.d.cts +6 -5
  80. package/dist/services/wallet-config.d.ts +6 -5
  81. package/dist/services/wallet-config.js +1 -1
  82. package/dist/signer/signer.cjs +122 -35
  83. package/dist/signer/signer.d.cts +4 -3
  84. package/dist/signer/signer.d.ts +4 -3
  85. package/dist/signer/signer.js +8 -4
  86. package/dist/{signer-C1t40Wus.d.cts → signer-BhLS7SYR.d.cts} +35 -14
  87. package/dist/{signer-DFGw9RRp.d.ts → signer-CylxIujU.d.ts} +35 -14
  88. package/dist/{spark-DXYE9gMM.d.ts → spark-DjR1b3TC.d.cts} +13 -21
  89. package/dist/{spark-DXYE9gMM.d.cts → spark-DjR1b3TC.d.ts} +13 -21
  90. package/dist/types/index.cjs +130 -227
  91. package/dist/types/index.d.cts +6 -5
  92. package/dist/types/index.d.ts +6 -5
  93. package/dist/types/index.js +3 -3
  94. package/dist/utils/index.cjs +1169 -3
  95. package/dist/utils/index.d.cts +66 -6
  96. package/dist/utils/index.d.ts +66 -6
  97. package/dist/utils/index.js +35 -14
  98. package/package.json +6 -2
  99. package/src/address/address.ts +41 -6
  100. package/src/graphql/client.ts +15 -0
  101. package/src/graphql/objects/Transfer.ts +7 -0
  102. package/src/graphql/queries/Transfer.ts +10 -0
  103. package/src/proto/spark.ts +215 -337
  104. package/src/proto/spark_token.ts +1407 -0
  105. package/src/services/config.ts +4 -0
  106. package/src/services/connection.ts +37 -1
  107. package/src/services/deposit.ts +23 -5
  108. package/src/services/token-transactions.ts +426 -75
  109. package/src/services/transfer.ts +182 -11
  110. package/src/services/tree-creation.ts +29 -14
  111. package/src/services/wallet-config.ts +2 -0
  112. package/src/signer/signer.ts +190 -48
  113. package/src/spark-wallet/spark-wallet.ts +510 -6
  114. package/src/tests/integration/transfer.test.ts +186 -214
  115. package/src/tests/integration/tree-creation.test.ts +5 -1
  116. package/src/tests/signer.test.ts +34 -0
  117. package/src/tests/transaction.test.ts +12 -0
  118. package/src/tests/xchain-address.test.ts +28 -0
  119. package/src/utils/index.ts +2 -0
  120. package/src/utils/mempool.ts +26 -1
  121. package/src/utils/network.ts +15 -0
  122. package/src/utils/transaction.ts +51 -3
  123. package/src/utils/unilateral-exit.ts +729 -0
  124. package/src/utils/xchain-address.ts +36 -0
  125. package/dist/chunk-E5SL7XTO.js +0 -301
@@ -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({ allowUnknownOutputs: true });
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 <= 0) {
1350
- throw new ValidationError("timelock interval is less than or equal to 0", {
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,