@buildonspark/spark-sdk 0.1.41 → 0.1.43

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 (156) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/android/src/main/jniLibs/arm64-v8a/libuniffi_spark_frost.so +0 -0
  3. package/android/src/main/jniLibs/armeabi-v7a/libuniffi_spark_frost.so +0 -0
  4. package/android/src/main/jniLibs/x86/libuniffi_spark_frost.so +0 -0
  5. package/android/src/main/jniLibs/x86_64/libuniffi_spark_frost.so +0 -0
  6. package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.cts +10 -0
  7. package/dist/LightningSendFeeEstimateInput-BgOhEAI-.d.ts +10 -0
  8. package/dist/{RequestLightningSendInput-mXUWn_cp.d.ts → RequestLightningSendInput-D7fZdT4A.d.ts} +35 -16
  9. package/dist/{RequestLightningSendInput-DXcLoiCe.d.cts → RequestLightningSendInput-Na1mHdWg.d.cts} +35 -16
  10. package/dist/address/index.cjs +38 -7
  11. package/dist/address/index.d.cts +2 -2
  12. package/dist/address/index.d.ts +2 -2
  13. package/dist/address/index.js +3 -3
  14. package/dist/{chunk-ATEHMLKP.js → chunk-6AFUC5M2.js} +1 -1
  15. package/dist/{chunk-ZXDE2XMU.js → chunk-BUTZWYBW.js} +9 -6
  16. package/dist/{chunk-7EFSUADA.js → chunk-DOA6QXYQ.js} +1 -0
  17. package/dist/{chunk-J5W5Q2ZP.js → chunk-DQYKQJRZ.js} +291 -7
  18. package/dist/{chunk-TWF35O6M.js → chunk-GSI4OLXZ.js} +32 -1
  19. package/dist/{chunk-2ZXXLPG2.js → chunk-GYQR4B4P.js} +5 -4
  20. package/dist/{chunk-ROKY5KS4.js → chunk-HRQRRDSS.js} +53 -15
  21. package/dist/{chunk-YEZDPUFY.js → chunk-IRW5TWMH.js} +8 -8
  22. package/dist/{chunk-7VMYMQLF.js → chunk-NSJF5F5O.js} +1 -1
  23. package/dist/{chunk-TM4TOEOX.js → chunk-O4RYNJNB.js} +3 -3
  24. package/dist/{chunk-MGPRLH6Q.js → chunk-QNNSEJ4P.js} +1 -1
  25. package/dist/{chunk-UKT6OFLO.js → chunk-TIUBYNN5.js} +13 -7
  26. package/dist/{chunk-6YVPOQ2A.js → chunk-TOSP3INR.js} +235 -143
  27. package/dist/chunk-VFJQNBFX.js +21 -0
  28. package/dist/{chunk-KKSU7OZO.js → chunk-WWOTVNPP.js} +195 -67
  29. package/dist/{chunk-HK6LPV6Z.js → chunk-Z5HIAYFT.js} +1 -1
  30. package/dist/graphql/objects/index.cjs +229 -135
  31. package/dist/graphql/objects/index.d.cts +54 -9
  32. package/dist/graphql/objects/index.d.ts +54 -9
  33. package/dist/graphql/objects/index.js +3 -3
  34. package/dist/{index-OSDtPMmC.d.ts → index-7RYRH5wc.d.ts} +10 -8
  35. package/dist/{index-CFh4uWzi.d.cts → index-BJOc8Ur-.d.cts} +10 -8
  36. package/dist/index.cjs +790 -315
  37. package/dist/index.d.cts +8 -7
  38. package/dist/index.d.ts +8 -7
  39. package/dist/index.js +26 -26
  40. package/dist/index.node.cjs +790 -315
  41. package/dist/index.node.d.cts +9 -8
  42. package/dist/index.node.d.ts +9 -8
  43. package/dist/index.node.js +26 -26
  44. package/dist/native/index.cjs +812 -332
  45. package/dist/native/index.d.cts +53 -18
  46. package/dist/native/index.d.ts +53 -18
  47. package/dist/native/index.js +659 -181
  48. package/dist/{network-BiwBmoOg.d.cts → network-D5lKssVl.d.cts} +1 -1
  49. package/dist/{network-BF2GYPye.d.ts → network-xkBSpaTn.d.ts} +1 -1
  50. package/dist/proto/lrc20.d.cts +1 -1
  51. package/dist/proto/lrc20.d.ts +1 -1
  52. package/dist/proto/spark.d.cts +1 -1
  53. package/dist/proto/spark.d.ts +1 -1
  54. package/dist/proto/spark_token.d.cts +1 -1
  55. package/dist/proto/spark_token.d.ts +1 -1
  56. package/dist/{sdk-types-CfhdFnsA.d.cts → sdk-types-B-q9py_P.d.cts} +1 -1
  57. package/dist/{sdk-types-MnQrHolg.d.ts → sdk-types-BPoPgzda.d.ts} +1 -1
  58. package/dist/services/config.cjs +118 -69
  59. package/dist/services/config.d.cts +6 -4
  60. package/dist/services/config.d.ts +6 -4
  61. package/dist/services/config.js +9 -9
  62. package/dist/services/connection.cjs +95 -15
  63. package/dist/services/connection.d.cts +6 -4
  64. package/dist/services/connection.d.ts +6 -4
  65. package/dist/services/connection.js +3 -3
  66. package/dist/services/index.cjs +487 -117
  67. package/dist/services/index.d.cts +5 -4
  68. package/dist/services/index.d.ts +5 -4
  69. package/dist/services/index.js +19 -19
  70. package/dist/services/lrc-connection.cjs +50 -7
  71. package/dist/services/lrc-connection.d.cts +5 -4
  72. package/dist/services/lrc-connection.d.ts +5 -4
  73. package/dist/services/lrc-connection.js +3 -3
  74. package/dist/services/token-transactions.cjs +351 -36
  75. package/dist/services/token-transactions.d.cts +5 -4
  76. package/dist/services/token-transactions.d.ts +5 -4
  77. package/dist/services/token-transactions.js +6 -6
  78. package/dist/services/wallet-config.cjs +1 -0
  79. package/dist/services/wallet-config.d.cts +6 -4
  80. package/dist/services/wallet-config.d.ts +6 -4
  81. package/dist/services/wallet-config.js +1 -1
  82. package/dist/signer/signer.cjs +117 -64
  83. package/dist/signer/signer.d.cts +4 -3
  84. package/dist/signer/signer.d.ts +4 -3
  85. package/dist/signer/signer.js +15 -7
  86. package/dist/{signer-CylxIujU.d.ts → signer-IO3oMRNj.d.cts} +2 -1
  87. package/dist/{signer-BhLS7SYR.d.cts → signer-wqesWifN.d.ts} +2 -1
  88. package/dist/{spark-DjR1b3TC.d.cts → spark-CDm4gqS6.d.cts} +1 -1
  89. package/dist/{spark-DjR1b3TC.d.ts → spark-CDm4gqS6.d.ts} +1 -1
  90. package/dist/types/index.cjs +282 -188
  91. package/dist/types/index.d.cts +7 -6
  92. package/dist/types/index.d.ts +7 -6
  93. package/dist/types/index.js +3 -3
  94. package/dist/utils/index.cjs +90 -58
  95. package/dist/utils/index.d.cts +6 -5
  96. package/dist/utils/index.d.ts +6 -5
  97. package/dist/utils/index.js +16 -16
  98. package/ios/spark_frostFFI.xcframework/ios-arm64/SparkFrost +0 -0
  99. package/ios/spark_frostFFI.xcframework/ios-arm64/spark_frostFFI.framework/spark_frostFFI +0 -0
  100. package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/SparkFrost +0 -0
  101. package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/spark_frostFFI.framework/spark_frostFFI +0 -0
  102. package/ios/spark_frostFFI.xcframework/macos-arm64_x86_64/spark_frostFFI.framework/spark_frostFFI +0 -0
  103. package/package.json +4 -4
  104. package/src/constants.ts +21 -0
  105. package/src/errors/base.ts +43 -1
  106. package/src/graphql/client.ts +4 -0
  107. package/src/graphql/mutations/RequestLightningSend.ts +2 -0
  108. package/src/graphql/objects/ClaimStaticDepositInput.ts +1 -1
  109. package/src/graphql/objects/ClaimStaticDepositStatus.ts +4 -2
  110. package/src/graphql/objects/Connection.ts +7 -7
  111. package/src/graphql/objects/CoopExitFeeEstimate.ts +1 -1
  112. package/src/graphql/objects/CoopExitFeeQuote.ts +202 -0
  113. package/src/graphql/objects/CoopExitFeeQuoteInput.ts +41 -0
  114. package/src/graphql/objects/CoopExitFeeQuoteOutput.ts +45 -0
  115. package/src/graphql/objects/CoopExitRequest.ts +21 -0
  116. package/src/graphql/objects/CurrencyUnit.ts +26 -28
  117. package/src/graphql/objects/Entity.ts +84 -0
  118. package/src/graphql/objects/Invoice.ts +2 -2
  119. package/src/graphql/objects/Leaf.ts +1 -1
  120. package/src/graphql/objects/LeavesSwapFeeEstimateOutput.ts +1 -1
  121. package/src/graphql/objects/LeavesSwapRequest.ts +6 -0
  122. package/src/graphql/objects/LightningReceiveRequest.ts +11 -0
  123. package/src/graphql/objects/LightningSendFeeEstimateInput.ts +8 -0
  124. package/src/graphql/objects/LightningSendFeeEstimateOutput.ts +1 -1
  125. package/src/graphql/objects/LightningSendRequest.ts +3 -0
  126. package/src/graphql/objects/RequestCoopExitInput.ts +8 -0
  127. package/src/graphql/objects/RequestLeavesSwapInput.ts +5 -1
  128. package/src/graphql/objects/RequestLightningReceiveInput.ts +9 -2
  129. package/src/graphql/objects/RequestLightningSendInput.ts +8 -0
  130. package/src/graphql/objects/SparkCoopExitRequestStatus.ts +2 -0
  131. package/src/graphql/objects/SparkUserRequestType.ts +2 -0
  132. package/src/graphql/objects/SparkWalletUser.ts +20 -0
  133. package/src/graphql/objects/UserRequest.ts +32 -0
  134. package/src/graphql/objects/VerifyChallengeInput.ts +1 -1
  135. package/src/graphql/objects/index.ts +12 -3
  136. package/src/graphql/queries/LightningSendFeeEstimate.ts +2 -0
  137. package/src/logger.ts +3 -0
  138. package/src/native/index.ts +1 -0
  139. package/src/services/config.ts +4 -0
  140. package/src/services/connection.ts +68 -29
  141. package/src/services/coop-exit.ts +1 -1
  142. package/src/services/lightning.ts +25 -1
  143. package/src/services/lrc-connection.ts +3 -3
  144. package/src/services/token-transactions.ts +6 -2
  145. package/src/services/wallet-config.ts +2 -0
  146. package/src/signer/signer.ts +4 -1
  147. package/src/spark-wallet/spark-wallet.ts +51 -15
  148. package/src/spark-wallet/types.ts +1 -0
  149. package/src/tests/errors.test.ts +58 -0
  150. package/src/tests/integration/lightning.test.ts +184 -0
  151. package/src/tests/integration/ssp/static_deposit.test.ts +1 -2
  152. package/src/tests/tokens.test.ts +52 -3
  153. package/src/utils/token-hashing.ts +335 -1
  154. package/dist/LightningSendFeeEstimateInput-CJvPnCSB.d.cts +0 -5
  155. package/dist/LightningSendFeeEstimateInput-CJvPnCSB.d.ts +0 -5
  156. package/dist/chunk-HKAKEKCE.js +0 -8
@@ -4,6 +4,7 @@ import {
4
4
  } from "./chunk-C3WN3D4O.js";
5
5
 
6
6
  // src/errors/base.ts
7
+ import { bytesToHex } from "@noble/hashes/utils";
7
8
  var SparkSDKError = class extends Error {
8
9
  context;
9
10
  originalError;
@@ -35,12 +36,42 @@ var SparkSDKError = class extends Error {
35
36
  }
36
37
  };
37
38
  function getMessage(message, context = {}, originalError) {
38
- const contextStr = Object.entries(context).map(([key, value]) => `${key}: ${JSON.stringify(value)}`).join(", ");
39
+ const contextStr = Object.entries(context).map(([key, value]) => `${key}: ${safeStringify(value)}`).join(", ");
39
40
  const originalErrorStr = originalError ? `
40
41
  Original Error: ${originalError.message}` : "";
41
42
  return `SparkSDKError: ${message}${contextStr ? `
42
43
  Context: ${contextStr}` : ""}${originalErrorStr}`;
43
44
  }
45
+ function safeStringify(value) {
46
+ const replacer = (_, v) => {
47
+ if (typeof v === "bigint") {
48
+ return v.toString();
49
+ }
50
+ if (v instanceof Uint8Array) {
51
+ return formatUint8Array(v);
52
+ }
53
+ return v;
54
+ };
55
+ if (typeof value === "bigint") {
56
+ return `"${value.toString()}"`;
57
+ }
58
+ if (value instanceof Uint8Array) {
59
+ return `"${formatUint8Array(value)}"`;
60
+ }
61
+ try {
62
+ const result = JSON.stringify(value, replacer);
63
+ return result === void 0 ? String(value) : result;
64
+ } catch {
65
+ try {
66
+ return String(value);
67
+ } catch {
68
+ return "[Unserializable]";
69
+ }
70
+ }
71
+ }
72
+ function formatUint8Array(arr) {
73
+ return `Uint8Array(0x${bytesToHex(arr)})`;
74
+ }
44
75
 
45
76
  // src/errors/types.ts
46
77
  var NetworkError = class extends SparkSDKError {
@@ -80,7 +111,7 @@ var NotImplementedError = class extends SparkSDKError {
80
111
  };
81
112
 
82
113
  // src/signer/signer.react-native.ts
83
- import { bytesToHex as bytesToHex3, hexToBytes as hexToBytes2 } from "@noble/hashes/utils";
114
+ import { bytesToHex as bytesToHex4, hexToBytes as hexToBytes2 } from "@noble/hashes/utils";
84
115
 
85
116
  // src/spark_bindings/native/index.ts
86
117
  import { NativeModules } from "react-native";
@@ -206,10 +237,13 @@ var NativeSparkFrost = class {
206
237
  return toUint8Array(result);
207
238
  }
208
239
  };
240
+ async function createDummyTx(address2, amountSats) {
241
+ return NativeSparkFrost.createDummyTx(address2, amountSats);
242
+ }
209
243
 
210
244
  // src/signer/signer.ts
211
245
  import {
212
- bytesToHex as bytesToHex2,
246
+ bytesToHex as bytesToHex3,
213
247
  bytesToNumberBE as bytesToNumberBE2,
214
248
  equalBytes as equalBytes2,
215
249
  hexToBytes
@@ -221,8 +255,20 @@ import { wordlist } from "@scure/bip39/wordlists/english";
221
255
  import * as ecies from "eciesjs";
222
256
 
223
257
  // src/constants.ts
258
+ import { isNode } from "@lightsparkdev/core";
224
259
  var isReactNative = typeof navigator !== "undefined" && navigator.product === "ReactNative";
225
260
  var isBun = globalThis.Bun !== void 0;
261
+ var packageVersion = true ? "0.1.43" : "unknown";
262
+ var baseEnvStr = "unknown";
263
+ if (isNode) {
264
+ baseEnvStr = `node/${process.version}`;
265
+ } else if (isReactNative) {
266
+ baseEnvStr = "react-native";
267
+ } else {
268
+ const userAgent = typeof navigator !== "undefined" && navigator.userAgent || "unknown-user-agent";
269
+ baseEnvStr = `browser/${userAgent}`;
270
+ }
271
+ var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
226
272
 
227
273
  // src/utils/adaptor-signature.ts
228
274
  import { mod } from "@noble/curves/abstract/modular";
@@ -444,7 +490,7 @@ function lastKeyWithTarget(target, keys) {
444
490
  }
445
491
 
446
492
  // src/utils/secret-sharing.ts
447
- import { bytesToHex, equalBytes } from "@noble/curves/abstract/utils";
493
+ import { bytesToHex as bytesToHex2, equalBytes } from "@noble/curves/abstract/utils";
448
494
  import { secp256k1 as secp256k13 } from "@noble/curves/secp256k1";
449
495
 
450
496
  // src/utils/crypto.ts
@@ -462,7 +508,7 @@ function getRandomBigInt(max) {
462
508
  const mask = (1n << BigInt(max.toString(2).length)) - 1n;
463
509
  while (true) {
464
510
  const randBytes = crypto.getRandomValues(new Uint8Array(byteLength + 1));
465
- const randValue = BigInt("0x" + bytesToHex(randBytes)) & mask;
511
+ const randValue = BigInt("0x" + bytesToHex2(randBytes)) & mask;
466
512
  if (randValue < maxBigInt) {
467
513
  return randValue;
468
514
  }
@@ -747,6 +793,8 @@ import {
747
793
  } from "@buildonspark/lrc20-sdk";
748
794
  import { sha256 } from "@noble/hashes/sha2";
749
795
  import { taprootTweakPrivKey } from "@scure/btc-signer/utils";
796
+ import { Receipt as Receipt2, PARITY as PARITY2, fromPrivateKey as fromPrivateKey2 } from "@buildonspark/lrc20-sdk";
797
+ import { MultisigReceiptInput } from "@buildonspark/lrc20-sdk/lrc/types";
750
798
  var sparkFrostModule = void 0;
751
799
  var getSparkFrostModule = async () => {
752
800
  if (isReactNative) {
@@ -845,13 +893,13 @@ var DefaultSparkSigner = class {
845
893
  const privateKey = this.deriveSigningKey(hash);
846
894
  const publicKey = secp256k15.getPublicKey(privateKey);
847
895
  this.publicKeyToPrivateKeyMap.set(
848
- bytesToHex2(publicKey),
849
- bytesToHex2(privateKey)
896
+ bytesToHex3(publicKey),
897
+ bytesToHex3(privateKey)
850
898
  );
851
899
  }
852
900
  }
853
901
  async getSchnorrPublicKey(publicKey) {
854
- const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex2(publicKey));
902
+ const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex3(publicKey));
855
903
  if (!privateKey) {
856
904
  throw new ValidationError("Private key is not set", {
857
905
  field: "privateKey"
@@ -860,7 +908,7 @@ var DefaultSparkSigner = class {
860
908
  return schnorr2.getPublicKey(hexToBytes(privateKey));
861
909
  }
862
910
  async signSchnorr(message, publicKey) {
863
- const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex2(publicKey));
911
+ const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex3(publicKey));
864
912
  if (!privateKey) {
865
913
  throw new ValidationError("Private key is not set", {
866
914
  field: "privateKey"
@@ -908,8 +956,8 @@ var DefaultSparkSigner = class {
908
956
  );
909
957
  this.staticDepositKeyMap.set(idx, staticDepositKey);
910
958
  this.publicKeyToPrivateKeyMap.set(
911
- bytesToHex2(staticDepositKey.publicKey),
912
- bytesToHex2(staticDepositKey.privateKey)
959
+ bytesToHex3(staticDepositKey.publicKey),
960
+ bytesToHex3(staticDepositKey.privateKey)
913
961
  );
914
962
  return staticDepositKey.publicKey;
915
963
  }
@@ -974,17 +1022,17 @@ var DefaultSparkSigner = class {
974
1022
  });
975
1023
  }
976
1024
  const publicKey = secp256k15.getPublicKey(newPrivateKey);
977
- const pubKeyHex = bytesToHex2(publicKey);
978
- const privKeyHex = bytesToHex2(newPrivateKey);
1025
+ const pubKeyHex = bytesToHex3(publicKey);
1026
+ const privKeyHex = bytesToHex3(newPrivateKey);
979
1027
  this.publicKeyToPrivateKeyMap.set(pubKeyHex, privKeyHex);
980
1028
  return publicKey;
981
1029
  }
982
1030
  async removePublicKey(publicKey) {
983
- this.publicKeyToPrivateKeyMap.delete(bytesToHex2(publicKey));
1031
+ this.publicKeyToPrivateKeyMap.delete(bytesToHex3(publicKey));
984
1032
  }
985
1033
  async subtractPrivateKeysGivenPublicKeys(first, second) {
986
- const firstPubKeyHex = bytesToHex2(first);
987
- const secondPubKeyHex = bytesToHex2(second);
1034
+ const firstPubKeyHex = bytesToHex3(first);
1035
+ const secondPubKeyHex = bytesToHex3(second);
988
1036
  const firstPrivateKeyHex = this.publicKeyToPrivateKeyMap.get(firstPubKeyHex);
989
1037
  const secondPrivateKeyHex = this.publicKeyToPrivateKeyMap.get(secondPubKeyHex);
990
1038
  if (!firstPrivateKeyHex || !secondPrivateKeyHex) {
@@ -997,8 +1045,8 @@ var DefaultSparkSigner = class {
997
1045
  secondPrivateKey
998
1046
  );
999
1047
  const resultPubKey = secp256k15.getPublicKey(resultPrivKey);
1000
- const resultPrivKeyHex = bytesToHex2(resultPrivKey);
1001
- const resultPubKeyHex = bytesToHex2(resultPubKey);
1048
+ const resultPrivKeyHex = bytesToHex3(resultPrivKey);
1049
+ const resultPubKeyHex = bytesToHex3(resultPubKey);
1002
1050
  this.publicKeyToPrivateKeyMap.set(resultPubKeyHex, resultPrivKeyHex);
1003
1051
  return resultPubKey;
1004
1052
  }
@@ -1010,7 +1058,7 @@ var DefaultSparkSigner = class {
1010
1058
  isSecretPubkey = false
1011
1059
  }) {
1012
1060
  if (isSecretPubkey) {
1013
- const pubKeyHex = bytesToHex2(secret);
1061
+ const pubKeyHex = bytesToHex3(secret);
1014
1062
  const privateKey = this.publicKeyToPrivateKeyMap.get(pubKeyHex);
1015
1063
  if (!privateKey) {
1016
1064
  throw new Error("Private key is not set");
@@ -1035,7 +1083,7 @@ var DefaultSparkSigner = class {
1035
1083
  field: "SparkFrost"
1036
1084
  });
1037
1085
  }
1038
- const privateAsPubKeyHex = bytesToHex2(privateAsPubKey);
1086
+ const privateAsPubKeyHex = bytesToHex3(privateAsPubKey);
1039
1087
  const signingPrivateKey = this.publicKeyToPrivateKeyMap.get(privateAsPubKeyHex);
1040
1088
  if (!signingPrivateKey) {
1041
1089
  throw new ValidationError("Private key not found for public key", {
@@ -1108,25 +1156,25 @@ var DefaultSparkSigner = class {
1108
1156
  this.signingKey = signingKey.hdKey;
1109
1157
  this.staticDepositKey = staticDepositKey.hdKey;
1110
1158
  this.publicKeyToPrivateKeyMap.set(
1111
- bytesToHex2(identityKey.publicKey),
1112
- bytesToHex2(identityKey.privateKey)
1159
+ bytesToHex3(identityKey.publicKey),
1160
+ bytesToHex3(identityKey.privateKey)
1113
1161
  );
1114
1162
  this.publicKeyToPrivateKeyMap.set(
1115
- bytesToHex2(depositKey.publicKey),
1116
- bytesToHex2(depositKey.privateKey)
1163
+ bytesToHex3(depositKey.publicKey),
1164
+ bytesToHex3(depositKey.privateKey)
1117
1165
  );
1118
1166
  this.publicKeyToPrivateKeyMap.set(
1119
- bytesToHex2(staticDepositKey.publicKey),
1120
- bytesToHex2(staticDepositKey.privateKey)
1167
+ bytesToHex3(staticDepositKey.publicKey),
1168
+ bytesToHex3(staticDepositKey.privateKey)
1121
1169
  );
1122
- return bytesToHex2(identityKey.publicKey);
1170
+ return bytesToHex3(identityKey.publicKey);
1123
1171
  }
1124
1172
  async signMessageWithPublicKey(message, publicKey, compact) {
1125
- const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex2(publicKey));
1173
+ const privateKey = this.publicKeyToPrivateKeyMap.get(bytesToHex3(publicKey));
1126
1174
  if (!privateKey) {
1127
1175
  throw new ValidationError("Private key not found for public key", {
1128
1176
  field: "privateKey",
1129
- value: bytesToHex2(publicKey)
1177
+ value: bytesToHex3(publicKey)
1130
1178
  });
1131
1179
  }
1132
1180
  const signature = secp256k15.sign(message, hexToBytes(privateKey));
@@ -1148,7 +1196,7 @@ var DefaultSparkSigner = class {
1148
1196
  return signature.toDERRawBytes();
1149
1197
  }
1150
1198
  async encryptLeafPrivateKeyEcies(receiverPublicKey, publicKey) {
1151
- const publicKeyHex = bytesToHex2(publicKey);
1199
+ const publicKeyHex = bytesToHex3(publicKey);
1152
1200
  const privateKey = this.publicKeyToPrivateKeyMap.get(publicKeyHex);
1153
1201
  if (!privateKey) {
1154
1202
  throw new Error("Private key is not set");
@@ -1162,12 +1210,12 @@ var DefaultSparkSigner = class {
1162
1210
  });
1163
1211
  }
1164
1212
  const receiverEciesPrivKey = ecies.PrivateKey.fromHex(
1165
- bytesToHex2(this.identityKey.privateKey)
1213
+ bytesToHex3(this.identityKey.privateKey)
1166
1214
  );
1167
1215
  const privateKey = ecies.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
1168
1216
  const publicKey = secp256k15.getPublicKey(privateKey);
1169
- const publicKeyHex = bytesToHex2(publicKey);
1170
- const privateKeyHex = bytesToHex2(privateKey);
1217
+ const publicKeyHex = bytesToHex3(publicKey);
1218
+ const privateKeyHex = bytesToHex3(privateKey);
1171
1219
  this.publicKeyToPrivateKeyMap.set(publicKeyHex, privateKeyHex);
1172
1220
  return publicKey;
1173
1221
  }
@@ -1184,8 +1232,8 @@ var DefaultSparkSigner = class {
1184
1232
  const adaptor = generateAdaptorFromSignature(signature);
1185
1233
  const adaptorPublicKey = secp256k15.getPublicKey(adaptor.adaptorPrivateKey);
1186
1234
  this.publicKeyToPrivateKeyMap.set(
1187
- bytesToHex2(adaptorPublicKey),
1188
- bytesToHex2(adaptor.adaptorPrivateKey)
1235
+ bytesToHex3(adaptorPublicKey),
1236
+ bytesToHex3(adaptor.adaptorPrivateKey)
1189
1237
  );
1190
1238
  return {
1191
1239
  adaptorSignature: signature,
@@ -1242,13 +1290,13 @@ var DefaultSparkSigner = class {
1242
1290
  privateKey = this.depositKey?.privateKey;
1243
1291
  } else {
1244
1292
  privateKey = hexToBytes(
1245
- this.publicKeyToPrivateKeyMap.get(bytesToHex2(publicKey)) ?? ""
1293
+ this.publicKeyToPrivateKeyMap.get(bytesToHex3(publicKey)) ?? ""
1246
1294
  );
1247
1295
  }
1248
1296
  if (!privateKey) {
1249
1297
  throw new ValidationError("Private key not found for public key", {
1250
1298
  field: "privateKey",
1251
- value: bytesToHex2(publicKey)
1299
+ value: bytesToHex3(publicKey)
1252
1300
  });
1253
1301
  }
1254
1302
  tx.signIdx(privateKey, index);
@@ -1266,7 +1314,7 @@ var ReactNativeSparkSigner = class extends DefaultSparkSigner {
1266
1314
  statechainCommitments,
1267
1315
  adaptorPubKey
1268
1316
  }) {
1269
- const privateAsPubKeyHex = bytesToHex3(privateAsPubKey);
1317
+ const privateAsPubKeyHex = bytesToHex4(privateAsPubKey);
1270
1318
  const signingPrivateKey = this.publicKeyToPrivateKeyMap.get(privateAsPubKeyHex);
1271
1319
  if (!signingPrivateKey) {
1272
1320
  throw new ValidationError("Private key not found for public key", {
@@ -1319,9 +1367,9 @@ var ReactNativeSparkSigner = class extends DefaultSparkSigner {
1319
1367
  };
1320
1368
 
1321
1369
  // src/spark-wallet/spark-wallet.ts
1322
- import { isNode as isNode4, mapCurrencyAmount } from "@lightsparkdev/core";
1370
+ import { isNode as isNode5, mapCurrencyAmount } from "@lightsparkdev/core";
1323
1371
  import {
1324
- bytesToHex as bytesToHex12,
1372
+ bytesToHex as bytesToHex13,
1325
1373
  bytesToNumberBE as bytesToNumberBE8,
1326
1374
  equalBytes as equalBytes5,
1327
1375
  hexToBytes as hexToBytes13,
@@ -1336,7 +1384,7 @@ import { uuidv7 as uuidv75, uuidv7obj } from "uuidv7";
1336
1384
 
1337
1385
  // src/graphql/client.ts
1338
1386
  import {
1339
- bytesToHex as bytesToHex4,
1387
+ bytesToHex as bytesToHex5,
1340
1388
  DefaultCrypto,
1341
1389
  NodeKeyCache,
1342
1390
  Requester
@@ -1436,10 +1484,21 @@ var CurrencyAmountToJson = (obj) => {
1436
1484
  };
1437
1485
  };
1438
1486
 
1487
+ // src/graphql/objects/ExitSpeed.ts
1488
+ var ExitSpeed = /* @__PURE__ */ ((ExitSpeed2) => {
1489
+ ExitSpeed2["FUTURE_VALUE"] = "FUTURE_VALUE";
1490
+ ExitSpeed2["FAST"] = "FAST";
1491
+ ExitSpeed2["MEDIUM"] = "MEDIUM";
1492
+ ExitSpeed2["SLOW"] = "SLOW";
1493
+ return ExitSpeed2;
1494
+ })(ExitSpeed || {});
1495
+ var ExitSpeed_default = ExitSpeed;
1496
+
1439
1497
  // src/graphql/objects/SparkCoopExitRequestStatus.ts
1440
1498
  var SparkCoopExitRequestStatus = /* @__PURE__ */ ((SparkCoopExitRequestStatus2) => {
1441
1499
  SparkCoopExitRequestStatus2["FUTURE_VALUE"] = "FUTURE_VALUE";
1442
1500
  SparkCoopExitRequestStatus2["INITIATED"] = "INITIATED";
1501
+ SparkCoopExitRequestStatus2["INBOUND_TRANSFER_CHECKED"] = "INBOUND_TRANSFER_CHECKED";
1443
1502
  SparkCoopExitRequestStatus2["TX_SIGNED"] = "TX_SIGNED";
1444
1503
  SparkCoopExitRequestStatus2["TX_BROADCASTED"] = "TX_BROADCASTED";
1445
1504
  SparkCoopExitRequestStatus2["WAITING_ON_TX_CONFIRMATIONS"] = "WAITING_ON_TX_CONFIRMATIONS";
@@ -1615,6 +1674,8 @@ var CoopExitRequestFromJson = (obj) => {
1615
1674
  rawCoopExitTransaction: obj["coop_exit_request_raw_coop_exit_transaction"],
1616
1675
  coopExitTxid: obj["coop_exit_request_coop_exit_txid"],
1617
1676
  typename: "CoopExitRequest",
1677
+ feeQuoteId: obj["coop_exit_request_fee_quote"]?.id ?? void 0,
1678
+ exitSpeed: !!obj["coop_exit_request_exit_speed"] ? ExitSpeed_default[obj["coop_exit_request_exit_speed"]] ?? ExitSpeed_default.FUTURE_VALUE : null,
1618
1679
  transfer: !!obj["coop_exit_request_transfer"] ? TransferFromJson(obj["coop_exit_request_transfer"]) : void 0
1619
1680
  };
1620
1681
  };
@@ -1641,6 +1702,10 @@ fragment CoopExitRequestFragment on CoopExitRequest {
1641
1702
  currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded
1642
1703
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
1643
1704
  }
1705
+ coop_exit_request_fee_quote: fee_quote {
1706
+ id
1707
+ }
1708
+ coop_exit_request_exit_speed: exit_speed
1644
1709
  coop_exit_request_status: status
1645
1710
  coop_exit_request_expires_at: expires_at
1646
1711
  coop_exit_request_raw_connector_transaction: raw_connector_transaction
@@ -1657,6 +1722,9 @@ fragment CoopExitRequestFragment on CoopExitRequest {
1657
1722
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
1658
1723
  }
1659
1724
  transfer_spark_id: spark_id
1725
+ transfer_user_request: user_request {
1726
+ id
1727
+ }
1660
1728
  }
1661
1729
  }`;
1662
1730
 
@@ -1775,6 +1843,9 @@ fragment LeavesSwapRequestFragment on LeavesSwapRequest {
1775
1843
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
1776
1844
  }
1777
1845
  transfer_spark_id: spark_id
1846
+ transfer_user_request: user_request {
1847
+ id
1848
+ }
1778
1849
  }
1779
1850
  leaves_swap_request_outbound_transfer: outbound_transfer {
1780
1851
  __typename
@@ -1787,6 +1858,9 @@ fragment LeavesSwapRequestFragment on LeavesSwapRequest {
1787
1858
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
1788
1859
  }
1789
1860
  transfer_spark_id: spark_id
1861
+ transfer_user_request: user_request {
1862
+ id
1863
+ }
1790
1864
  }
1791
1865
  leaves_swap_request_expires_at: expires_at
1792
1866
  leaves_swap_request_swap_leaves: swap_leaves {
@@ -1909,7 +1983,8 @@ var LightningReceiveRequestFromJson = (obj) => {
1909
1983
  status: LightningReceiveRequestStatus_default[obj["lightning_receive_request_status"]] ?? LightningReceiveRequestStatus_default.FUTURE_VALUE,
1910
1984
  typename: "LightningReceiveRequest",
1911
1985
  transfer: !!obj["lightning_receive_request_transfer"] ? TransferFromJson(obj["lightning_receive_request_transfer"]) : void 0,
1912
- paymentPreimage: obj["lightning_receive_request_payment_preimage"]
1986
+ paymentPreimage: obj["lightning_receive_request_payment_preimage"],
1987
+ receiverIdentityPublicKey: obj["lightning_receive_request_receiver_identity_public_key"]
1913
1988
  };
1914
1989
  };
1915
1990
  var FRAGMENT6 = `
@@ -1948,8 +2023,12 @@ fragment LightningReceiveRequestFragment on LightningReceiveRequest {
1948
2023
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
1949
2024
  }
1950
2025
  transfer_spark_id: spark_id
2026
+ transfer_user_request: user_request {
2027
+ id
2028
+ }
1951
2029
  }
1952
2030
  lightning_receive_request_payment_preimage: payment_preimage
2031
+ lightning_receive_request_receiver_identity_public_key: receiver_identity_public_key
1953
2032
  }`;
1954
2033
 
1955
2034
  // src/graphql/mutations/RequestLightningReceive.ts
@@ -2046,6 +2125,9 @@ fragment LightningSendRequestFragment on LightningSendRequest {
2046
2125
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2047
2126
  }
2048
2127
  transfer_spark_id: spark_id
2128
+ transfer_user_request: user_request {
2129
+ id
2130
+ }
2049
2131
  }
2050
2132
  lightning_send_request_payment_preimage: payment_preimage
2051
2133
  }`;
@@ -2055,10 +2137,12 @@ var RequestLightningSend = `
2055
2137
  mutation RequestLightningSend(
2056
2138
  $encoded_invoice: String!
2057
2139
  $idempotency_key: String!
2140
+ $amount_sats: Long
2058
2141
  ) {
2059
2142
  request_lightning_send(input: {
2060
2143
  encoded_invoice: $encoded_invoice
2061
2144
  idempotency_key: $idempotency_key
2145
+ amount_sats: $amount_sats
2062
2146
  }) {
2063
2147
  request {
2064
2148
  ...LightningSendRequestFragment
@@ -2332,10 +2416,12 @@ var LeavesSwapFeeEstimate = `
2332
2416
  var LightningSendFeeEstimate = `
2333
2417
  query LightningSendFeeEstimate(
2334
2418
  $encoded_invoice: String!
2419
+ $amount_sats: Long
2335
2420
  ) {
2336
2421
  lightning_send_fee_estimate(
2337
2422
  input: {
2338
2423
  encoded_invoice: $encoded_invoice
2424
+ amount_sats: $amount_sats
2339
2425
  }
2340
2426
  ) {
2341
2427
  ...LightningSendFeeEstimateOutputFragment
@@ -2409,6 +2495,10 @@ fragment UserRequestFragment on UserRequest {
2409
2495
  currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded
2410
2496
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2411
2497
  }
2498
+ coop_exit_request_fee_quote: fee_quote {
2499
+ id
2500
+ }
2501
+ coop_exit_request_exit_speed: exit_speed
2412
2502
  coop_exit_request_status: status
2413
2503
  coop_exit_request_expires_at: expires_at
2414
2504
  coop_exit_request_raw_connector_transaction: raw_connector_transaction
@@ -2425,6 +2515,9 @@ fragment UserRequestFragment on UserRequest {
2425
2515
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2426
2516
  }
2427
2517
  transfer_spark_id: spark_id
2518
+ transfer_user_request: user_request {
2519
+ id
2520
+ }
2428
2521
  }
2429
2522
  }
2430
2523
  ... on LeavesSwapRequest {
@@ -2469,6 +2562,9 @@ fragment UserRequestFragment on UserRequest {
2469
2562
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2470
2563
  }
2471
2564
  transfer_spark_id: spark_id
2565
+ transfer_user_request: user_request {
2566
+ id
2567
+ }
2472
2568
  }
2473
2569
  leaves_swap_request_outbound_transfer: outbound_transfer {
2474
2570
  __typename
@@ -2481,6 +2577,9 @@ fragment UserRequestFragment on UserRequest {
2481
2577
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2482
2578
  }
2483
2579
  transfer_spark_id: spark_id
2580
+ transfer_user_request: user_request {
2581
+ id
2582
+ }
2484
2583
  }
2485
2584
  leaves_swap_request_expires_at: expires_at
2486
2585
  leaves_swap_request_swap_leaves: swap_leaves {
@@ -2525,8 +2624,12 @@ fragment UserRequestFragment on UserRequest {
2525
2624
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2526
2625
  }
2527
2626
  transfer_spark_id: spark_id
2627
+ transfer_user_request: user_request {
2628
+ id
2629
+ }
2528
2630
  }
2529
2631
  lightning_receive_request_payment_preimage: payment_preimage
2632
+ lightning_receive_request_receiver_identity_public_key: receiver_identity_public_key
2530
2633
  }
2531
2634
  ... on LightningSendRequest {
2532
2635
  __typename
@@ -2556,6 +2659,9 @@ fragment UserRequestFragment on UserRequest {
2556
2659
  currency_amount_preferred_currency_value_approx: preferred_currency_value_approx
2557
2660
  }
2558
2661
  transfer_spark_id: spark_id
2662
+ transfer_user_request: user_request {
2663
+ id
2664
+ }
2559
2665
  }
2560
2666
  lightning_send_request_payment_preimage: payment_preimage
2561
2667
  }
@@ -2636,11 +2742,12 @@ var SspClient = class {
2636
2742
  }
2637
2743
  });
2638
2744
  }
2639
- async getLightningSendFeeEstimate(encodedInvoice) {
2745
+ async getLightningSendFeeEstimate(encodedInvoice, amountSats) {
2640
2746
  return await this.executeRawQuery({
2641
2747
  queryPayload: LightningSendFeeEstimate,
2642
2748
  variables: {
2643
- encoded_invoice: encodedInvoice
2749
+ encoded_invoice: encodedInvoice,
2750
+ amount_sats: amountSats
2644
2751
  },
2645
2752
  constructObject: (response) => {
2646
2753
  return LightningSendFeeEstimateOutputFromJson(
@@ -2736,13 +2843,15 @@ var SspClient = class {
2736
2843
  }
2737
2844
  async requestLightningSend({
2738
2845
  encodedInvoice,
2739
- idempotencyKey
2846
+ idempotencyKey,
2847
+ amountSats
2740
2848
  }) {
2741
2849
  return await this.executeRawQuery({
2742
2850
  queryPayload: RequestLightningSend,
2743
2851
  variables: {
2744
2852
  encoded_invoice: encodedInvoice,
2745
- idempotency_key: idempotencyKey
2853
+ idempotency_key: idempotencyKey,
2854
+ amount_sats: amountSats
2746
2855
  },
2747
2856
  constructObject: (response) => {
2748
2857
  return LightningSendRequestFromJson(
@@ -2910,7 +3019,7 @@ var SspClient = class {
2910
3019
  {
2911
3020
  queryPayload: GetChallenge,
2912
3021
  variables: {
2913
- public_key: bytesToHex4(await this.signer.getIdentityPublicKey())
3022
+ public_key: bytesToHex5(await this.signer.getIdentityPublicKey())
2914
3023
  },
2915
3024
  constructObject: (response) => {
2916
3025
  return GetChallengeOutputFromJson(response.get_challenge);
@@ -2926,7 +3035,7 @@ var SspClient = class {
2926
3035
  variables: {
2927
3036
  protected_challenge: protectedChallenge,
2928
3037
  signature,
2929
- identity_public_key: bytesToHex4(
3038
+ identity_public_key: bytesToHex5(
2930
3039
  await this.signer.getIdentityPublicKey()
2931
3040
  )
2932
3041
  },
@@ -2998,18 +3107,11 @@ var SparkAuthProvider = class {
2998
3107
  // src/graphql/objects/ClaimStaticDeposit.ts
2999
3108
  import { isObject as isObject6 } from "@lightsparkdev/core";
3000
3109
 
3001
- // src/graphql/objects/ExitSpeed.ts
3002
- var ExitSpeed = /* @__PURE__ */ ((ExitSpeed2) => {
3003
- ExitSpeed2["FUTURE_VALUE"] = "FUTURE_VALUE";
3004
- ExitSpeed2["FAST"] = "FAST";
3005
- ExitSpeed2["MEDIUM"] = "MEDIUM";
3006
- ExitSpeed2["SLOW"] = "SLOW";
3007
- return ExitSpeed2;
3008
- })(ExitSpeed || {});
3009
- var ExitSpeed_default = ExitSpeed;
3110
+ // src/graphql/objects/CoopExitFeeQuote.ts
3111
+ import { isObject as isObject7 } from "@lightsparkdev/core";
3010
3112
 
3011
3113
  // src/graphql/objects/SparkWalletUser.ts
3012
- import { isObject as isObject7 } from "@lightsparkdev/core";
3114
+ import { isObject as isObject8 } from "@lightsparkdev/core";
3013
3115
 
3014
3116
  // src/proto/spark.ts
3015
3117
  import { BinaryReader as BinaryReader4, BinaryWriter as BinaryWriter4 } from "@bufbuild/protobuf/wire";
@@ -3907,7 +4009,7 @@ var DepositAddressProof = {
3907
4009
  },
3908
4010
  fromJSON(object) {
3909
4011
  return {
3910
- addressSignatures: isObject8(object.addressSignatures) ? Object.entries(object.addressSignatures).reduce((acc, [key, value]) => {
4012
+ addressSignatures: isObject9(object.addressSignatures) ? Object.entries(object.addressSignatures).reduce((acc, [key, value]) => {
3911
4013
  acc[key] = bytesFromBase642(value);
3912
4014
  return acc;
3913
4015
  }, {}) : {},
@@ -4689,18 +4791,18 @@ var SigningResult = {
4689
4791
  },
4690
4792
  fromJSON(object) {
4691
4793
  return {
4692
- publicKeys: isObject8(object.publicKeys) ? Object.entries(object.publicKeys).reduce((acc, [key, value]) => {
4794
+ publicKeys: isObject9(object.publicKeys) ? Object.entries(object.publicKeys).reduce((acc, [key, value]) => {
4693
4795
  acc[key] = bytesFromBase642(value);
4694
4796
  return acc;
4695
4797
  }, {}) : {},
4696
- signingNonceCommitments: isObject8(object.signingNonceCommitments) ? Object.entries(object.signingNonceCommitments).reduce(
4798
+ signingNonceCommitments: isObject9(object.signingNonceCommitments) ? Object.entries(object.signingNonceCommitments).reduce(
4697
4799
  (acc, [key, value]) => {
4698
4800
  acc[key] = SigningCommitment.fromJSON(value);
4699
4801
  return acc;
4700
4802
  },
4701
4803
  {}
4702
4804
  ) : {},
4703
- signatureShares: isObject8(object.signatureShares) ? Object.entries(object.signatureShares).reduce((acc, [key, value]) => {
4805
+ signatureShares: isObject9(object.signatureShares) ? Object.entries(object.signatureShares).reduce((acc, [key, value]) => {
4704
4806
  acc[key] = bytesFromBase642(value);
4705
4807
  return acc;
4706
4808
  }, {}) : {},
@@ -8728,7 +8830,7 @@ var TransferPackage = {
8728
8830
  fromJSON(object) {
8729
8831
  return {
8730
8832
  leavesToSend: globalThis.Array.isArray(object?.leavesToSend) ? object.leavesToSend.map((e) => UserSignedTxSigningJob.fromJSON(e)) : [],
8731
- keyTweakPackage: isObject8(object.keyTweakPackage) ? Object.entries(object.keyTweakPackage).reduce((acc, [key, value]) => {
8833
+ keyTweakPackage: isObject9(object.keyTweakPackage) ? Object.entries(object.keyTweakPackage).reduce((acc, [key, value]) => {
8732
8834
  acc[key] = bytesFromBase642(value);
8733
8835
  return acc;
8734
8836
  }, {}) : {},
@@ -8990,7 +9092,7 @@ var SendLeafKeyTweak = {
8990
9092
  return {
8991
9093
  leafId: isSet3(object.leafId) ? globalThis.String(object.leafId) : "",
8992
9094
  secretShareTweak: isSet3(object.secretShareTweak) ? SecretShare.fromJSON(object.secretShareTweak) : void 0,
8993
- pubkeySharesTweak: isObject8(object.pubkeySharesTweak) ? Object.entries(object.pubkeySharesTweak).reduce((acc, [key, value]) => {
9095
+ pubkeySharesTweak: isObject9(object.pubkeySharesTweak) ? Object.entries(object.pubkeySharesTweak).reduce((acc, [key, value]) => {
8994
9096
  acc[key] = bytesFromBase642(value);
8995
9097
  return acc;
8996
9098
  }, {}) : {},
@@ -9963,7 +10065,7 @@ var ClaimLeafKeyTweak = {
9963
10065
  return {
9964
10066
  leafId: isSet3(object.leafId) ? globalThis.String(object.leafId) : "",
9965
10067
  secretShareTweak: isSet3(object.secretShareTweak) ? SecretShare.fromJSON(object.secretShareTweak) : void 0,
9966
- pubkeySharesTweak: isObject8(object.pubkeySharesTweak) ? Object.entries(object.pubkeySharesTweak).reduce((acc, [key, value]) => {
10068
+ pubkeySharesTweak: isObject9(object.pubkeySharesTweak) ? Object.entries(object.pubkeySharesTweak).reduce((acc, [key, value]) => {
9967
10069
  acc[key] = bytesFromBase642(value);
9968
10070
  return acc;
9969
10071
  }, {}) : {}
@@ -10639,7 +10741,7 @@ var RequestedSigningCommitments = {
10639
10741
  },
10640
10742
  fromJSON(object) {
10641
10743
  return {
10642
- signingNonceCommitments: isObject8(object.signingNonceCommitments) ? Object.entries(object.signingNonceCommitments).reduce(
10744
+ signingNonceCommitments: isObject9(object.signingNonceCommitments) ? Object.entries(object.signingNonceCommitments).reduce(
10643
10745
  (acc, [key, value]) => {
10644
10746
  acc[key] = SigningCommitment.fromJSON(value);
10645
10747
  return acc;
@@ -10886,7 +10988,7 @@ var SigningCommitments = {
10886
10988
  },
10887
10989
  fromJSON(object) {
10888
10990
  return {
10889
- signingCommitments: isObject8(object.signingCommitments) ? Object.entries(object.signingCommitments).reduce(
10991
+ signingCommitments: isObject9(object.signingCommitments) ? Object.entries(object.signingCommitments).reduce(
10890
10992
  (acc, [key, value]) => {
10891
10993
  acc[key] = SigningCommitment.fromJSON(value);
10892
10994
  return acc;
@@ -12987,7 +13089,7 @@ var GetSigningOperatorListResponse = {
12987
13089
  },
12988
13090
  fromJSON(object) {
12989
13091
  return {
12990
- signingOperators: isObject8(object.signingOperators) ? Object.entries(object.signingOperators).reduce(
13092
+ signingOperators: isObject9(object.signingOperators) ? Object.entries(object.signingOperators).reduce(
12991
13093
  (acc, [key, value]) => {
12992
13094
  acc[key] = SigningOperatorInfo.fromJSON(value);
12993
13095
  return acc;
@@ -13654,7 +13756,7 @@ var QueryNodesResponse = {
13654
13756
  },
13655
13757
  fromJSON(object) {
13656
13758
  return {
13657
- nodes: isObject8(object.nodes) ? Object.entries(object.nodes).reduce((acc, [key, value]) => {
13759
+ nodes: isObject9(object.nodes) ? Object.entries(object.nodes).reduce((acc, [key, value]) => {
13658
13760
  acc[key] = TreeNode.fromJSON(value);
13659
13761
  return acc;
13660
13762
  }, {}) : {},
@@ -14370,7 +14472,7 @@ var QueryBalanceResponse = {
14370
14472
  fromJSON(object) {
14371
14473
  return {
14372
14474
  balance: isSet3(object.balance) ? globalThis.Number(object.balance) : 0,
14373
- nodeBalances: isObject8(object.nodeBalances) ? Object.entries(object.nodeBalances).reduce((acc, [key, value]) => {
14475
+ nodeBalances: isObject9(object.nodeBalances) ? Object.entries(object.nodeBalances).reduce((acc, [key, value]) => {
14374
14476
  acc[key] = Number(value);
14375
14477
  return acc;
14376
14478
  }, {}) : {}
@@ -15380,7 +15482,7 @@ var QueryNodesDistributionResponse = {
15380
15482
  },
15381
15483
  fromJSON(object) {
15382
15484
  return {
15383
- nodeDistribution: isObject8(object.nodeDistribution) ? Object.entries(object.nodeDistribution).reduce((acc, [key, value]) => {
15485
+ nodeDistribution: isObject9(object.nodeDistribution) ? Object.entries(object.nodeDistribution).reduce((acc, [key, value]) => {
15384
15486
  acc[globalThis.Number(key)] = Number(value);
15385
15487
  return acc;
15386
15488
  }, {}) : {}
@@ -15629,7 +15731,7 @@ var QueryNodesByValueResponse = {
15629
15731
  },
15630
15732
  fromJSON(object) {
15631
15733
  return {
15632
- nodes: isObject8(object.nodes) ? Object.entries(object.nodes).reduce((acc, [key, value]) => {
15734
+ nodes: isObject9(object.nodes) ? Object.entries(object.nodes).reduce((acc, [key, value]) => {
15633
15735
  acc[key] = TreeNode.fromJSON(value);
15634
15736
  return acc;
15635
15737
  }, {}) : {},
@@ -16157,7 +16259,7 @@ function longToNumber2(int64) {
16157
16259
  }
16158
16260
  return num;
16159
16261
  }
16160
- function isObject8(value) {
16262
+ function isObject9(value) {
16161
16263
  return typeof value === "object" && value !== null;
16162
16264
  }
16163
16265
  function isSet3(value) {
@@ -16236,10 +16338,10 @@ function getNetworkFromString(network) {
16236
16338
  }
16237
16339
 
16238
16340
  // src/tests/isHermeticTest.ts
16239
- import { isNode } from "@lightsparkdev/core";
16341
+ import { isNode as isNode2 } from "@lightsparkdev/core";
16240
16342
  import fs from "fs";
16241
16343
  function isHermeticTest() {
16242
- if (isNode) {
16344
+ if (isNode2) {
16243
16345
  return (fs?.existsSync?.("/tmp/spark_hermetic") ?? false) || process.env.HERMETIC_TEST === "true";
16244
16346
  }
16245
16347
  return typeof process !== "undefined" && process.env?.HERMETIC_TEST === "true" || false;
@@ -16367,6 +16469,7 @@ var BASE_CONFIG = {
16367
16469
  signingOperators: getLocalSigningOperators(),
16368
16470
  tokenSignatures: "SCHNORR",
16369
16471
  tokenTransactionVersion: "V0",
16472
+ tokenValidityDurationSeconds: 180,
16370
16473
  electrsUrl: getElectrsUrl("LOCAL"),
16371
16474
  expectedWithdrawBondSats: 1e4,
16372
16475
  expectedWithdrawRelativeBlockLocktime: 1e3,
@@ -16577,6 +16680,9 @@ var WalletConfigService = class {
16577
16680
  getTokenTransactionVersion() {
16578
16681
  return this.config.tokenTransactionVersion;
16579
16682
  }
16683
+ getTokenValidityDurationSeconds() {
16684
+ return this.config.tokenValidityDurationSeconds;
16685
+ }
16580
16686
  getElectrsUrl() {
16581
16687
  return this.config.electrsUrl;
16582
16688
  }
@@ -16586,7 +16692,7 @@ var WalletConfigService = class {
16586
16692
  };
16587
16693
 
16588
16694
  // src/services/connection.ts
16589
- import { isNode as isNode2 } from "@lightsparkdev/core";
16695
+ import { isNode as isNode3 } from "@lightsparkdev/core";
16590
16696
  import { sha256 as sha2563 } from "@noble/hashes/sha2";
16591
16697
  import { retryMiddleware } from "nice-grpc-client-middleware-retry";
16592
16698
  import { Metadata } from "nice-grpc-common";
@@ -18432,7 +18538,7 @@ var ConnectionManager = class {
18432
18538
  async createMockClient(address2) {
18433
18539
  const channel = await this.createChannelWithTLS(address2);
18434
18540
  const isNodeChannel = "close" in channel;
18435
- if (isNode2 && isNodeChannel && !isBun) {
18541
+ if (isNode3 && isNodeChannel && !isBun) {
18436
18542
  const grpcModule = await import("nice-grpc");
18437
18543
  const { createClient } = "default" in grpcModule ? grpcModule.default : grpcModule;
18438
18544
  const client = createClient(MockServiceDefinition, channel);
@@ -18449,7 +18555,7 @@ var ConnectionManager = class {
18449
18555
  }
18450
18556
  async createChannelWithTLS(address2, certPath) {
18451
18557
  try {
18452
- if (isNode2 && !isBun) {
18558
+ if (isNode3 && !isBun) {
18453
18559
  const grpcModule = await import("nice-grpc");
18454
18560
  const { ChannelCredentials, createChannel } = "default" in grpcModule ? grpcModule.default : grpcModule;
18455
18561
  if (certPath) {
@@ -18590,14 +18696,38 @@ var ConnectionManager = class {
18590
18696
  }
18591
18697
  async createSparkAuthnGrpcConnection(address2, certPath) {
18592
18698
  const channel = await this.createChannelWithTLS(address2, certPath);
18699
+ const authnMiddleware = this.createAuthnMiddleware();
18593
18700
  return this.createGrpcClient(
18594
18701
  SparkAuthnServiceDefinition,
18595
18702
  channel,
18596
- false
18703
+ false,
18704
+ authnMiddleware
18597
18705
  );
18598
18706
  }
18707
+ createAuthnMiddleware() {
18708
+ if (isNode3) {
18709
+ return async function* (call, options) {
18710
+ const metadata = Metadata(options.metadata).set(
18711
+ "X-Client-Env",
18712
+ clientEnv
18713
+ );
18714
+ return yield* call.next(call.request, {
18715
+ ...options,
18716
+ metadata
18717
+ });
18718
+ }.bind(this);
18719
+ } else {
18720
+ return async function* (call, options) {
18721
+ const metadata = Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("X-Client-Env", clientEnv).set("Content-Type", "application/grpc-web+proto");
18722
+ return yield* call.next(call.request, {
18723
+ ...options,
18724
+ metadata
18725
+ });
18726
+ }.bind(this);
18727
+ }
18728
+ }
18599
18729
  createMiddleware(address2, authToken) {
18600
- if (isNode2) {
18730
+ if (isNode3) {
18601
18731
  return this.createNodeMiddleware(address2, authToken);
18602
18732
  } else {
18603
18733
  return this.createBrowserMiddleware(address2, authToken);
@@ -18605,21 +18735,29 @@ var ConnectionManager = class {
18605
18735
  }
18606
18736
  createNodeMiddleware(address2, initialAuthToken) {
18607
18737
  return async function* (call, options) {
18738
+ const metadata = Metadata(options.metadata).set(
18739
+ "X-Client-Env",
18740
+ clientEnv
18741
+ );
18608
18742
  try {
18609
18743
  return yield* call.next(call.request, {
18610
18744
  ...options,
18611
- metadata: Metadata(options.metadata).set(
18745
+ metadata: metadata.set(
18612
18746
  "Authorization",
18613
18747
  `Bearer ${this.clients.get(address2)?.authToken || initialAuthToken}`
18614
- ).set("User-Agent", "spark-js-sdk")
18748
+ )
18615
18749
  });
18616
18750
  } catch (error) {
18617
18751
  if (error.message?.includes("token has expired")) {
18618
18752
  const newAuthToken = await this.authenticate(address2);
18619
- this.clients.get(address2).authToken = newAuthToken;
18753
+ const clientData = this.clients.get(address2);
18754
+ if (!clientData) {
18755
+ throw new Error(`No client found for address: ${address2}`);
18756
+ }
18757
+ clientData.authToken = newAuthToken;
18620
18758
  return yield* call.next(call.request, {
18621
18759
  ...options,
18622
- metadata: Metadata(options.metadata).set("Authorization", `Bearer ${newAuthToken}`).set("User-Agent", "spark-js-sdk")
18760
+ metadata: metadata.set("Authorization", `Bearer ${newAuthToken}`)
18623
18761
  });
18624
18762
  }
18625
18763
  throw error;
@@ -18628,21 +18766,26 @@ var ConnectionManager = class {
18628
18766
  }
18629
18767
  createBrowserMiddleware(address2, initialAuthToken) {
18630
18768
  return async function* (call, options) {
18769
+ const metadata = Metadata(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("X-Client-Env", clientEnv).set("Content-Type", "application/grpc-web+proto");
18631
18770
  try {
18632
18771
  return yield* call.next(call.request, {
18633
18772
  ...options,
18634
- metadata: Metadata(options.metadata).set(
18773
+ metadata: metadata.set(
18635
18774
  "Authorization",
18636
18775
  `Bearer ${this.clients.get(address2)?.authToken || initialAuthToken}`
18637
- ).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("User-Agent", "spark-js-sdk")
18776
+ )
18638
18777
  });
18639
18778
  } catch (error) {
18640
18779
  if (error.message?.includes("token has expired")) {
18641
18780
  const newAuthToken = await this.authenticate(address2);
18642
- this.clients.get(address2).authToken = newAuthToken;
18781
+ const clientData = this.clients.get(address2);
18782
+ if (!clientData) {
18783
+ throw new Error(`No client found for address: ${address2}`);
18784
+ }
18785
+ clientData.authToken = newAuthToken;
18643
18786
  return yield* call.next(call.request, {
18644
18787
  ...options,
18645
- metadata: Metadata(options.metadata).set("Authorization", `Bearer ${newAuthToken}`).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("User-Agent", "spark-js-sdk")
18788
+ metadata: metadata.set("Authorization", `Bearer ${newAuthToken}`)
18646
18789
  });
18647
18790
  }
18648
18791
  throw error;
@@ -18657,7 +18800,7 @@ var ConnectionManager = class {
18657
18800
  };
18658
18801
  let options = {};
18659
18802
  const isNodeChannel = "close" in channel;
18660
- if (isNode2 && isNodeChannel && !isBun) {
18803
+ if (isNode3 && isNodeChannel && !isBun) {
18661
18804
  const grpcModule = await import("nice-grpc");
18662
18805
  const { openTelemetryClientMiddleware } = await import("nice-grpc-opentelemetry");
18663
18806
  const { createClientFactory } = "default" in grpcModule ? grpcModule.default : grpcModule;
@@ -18706,7 +18849,7 @@ import { uuidv7 as uuidv72 } from "uuidv7";
18706
18849
 
18707
18850
  // src/utils/bitcoin.ts
18708
18851
  import {
18709
- bytesToHex as bytesToHex5,
18852
+ bytesToHex as bytesToHex6,
18710
18853
  bytesToNumberBE as bytesToNumberBE3,
18711
18854
  hexToBytes as hexToBytes3
18712
18855
  } from "@noble/curves/abstract/utils";
@@ -18775,7 +18918,7 @@ function getP2TRAddressFromPkScript(pkScript, network) {
18775
18918
  if (pkScript.length !== 34 || pkScript[0] !== 81 || pkScript[1] !== 32) {
18776
18919
  throw new ValidationError("Invalid pkscript", {
18777
18920
  field: "pkScript",
18778
- value: bytesToHex5(pkScript),
18921
+ value: bytesToHex6(pkScript),
18779
18922
  expected: "34 bytes starting with 0x51 0x20"
18780
18923
  });
18781
18924
  }
@@ -18847,10 +18990,10 @@ function getSigHashFromTx(tx, inputIndex, prevOutput) {
18847
18990
  );
18848
18991
  }
18849
18992
  function getTxId(tx) {
18850
- return bytesToHex5(sha2564(sha2564(tx.toBytes(true))).reverse());
18993
+ return bytesToHex6(sha2564(sha2564(tx.toBytes(true))).reverse());
18851
18994
  }
18852
18995
  function getTxIdNoReverse(tx) {
18853
- return bytesToHex5(sha2564(sha2564(tx.toBytes(true))));
18996
+ return bytesToHex6(sha2564(sha2564(tx.toBytes(true))));
18854
18997
  }
18855
18998
 
18856
18999
  // src/utils/transaction.ts
@@ -18937,7 +19080,7 @@ function getEphemeralAnchorOutput() {
18937
19080
 
18938
19081
  // src/services/transfer.ts
18939
19082
  import {
18940
- bytesToHex as bytesToHex6,
19083
+ bytesToHex as bytesToHex7,
18941
19084
  equalBytes as equalBytes3,
18942
19085
  hexToBytes as hexToBytes5,
18943
19086
  numberToBytesBE as numberToBytesBE3
@@ -19237,7 +19380,7 @@ var BaseTransferService = class {
19237
19380
  }
19238
19381
  async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, refundSignatureMap) {
19239
19382
  const receiverEciesPubKey = ecies2.PublicKey.fromHex(
19240
- bytesToHex6(receiverIdentityPubkey)
19383
+ bytesToHex7(receiverIdentityPubkey)
19241
19384
  );
19242
19385
  const leavesTweaksMap = /* @__PURE__ */ new Map();
19243
19386
  for (const leaf of leaves) {
@@ -20210,7 +20353,7 @@ var CoopExitService = class extends BaseTransferService {
20210
20353
  connectorOutputs,
20211
20354
  receiverPubKey
20212
20355
  );
20213
- const transferTweak = await this.sendTransferTweakKey(
20356
+ const transferTweak = await this.deliverTransferPackage(
20214
20357
  transfer,
20215
20358
  leaves,
20216
20359
  signaturesMap
@@ -20973,7 +21116,8 @@ var LightningService = class {
20973
21116
  paymentHash,
20974
21117
  invoiceString,
20975
21118
  isInboundPayment,
20976
- feeSats = 0
21119
+ feeSats = 0,
21120
+ amountSatsToSend
20977
21121
  }) {
20978
21122
  const sparkClient = await this.connectionManager.createSparkClient(
20979
21123
  this.config.getCoordinatorAddress()
@@ -21010,7 +21154,25 @@ var LightningService = class {
21010
21154
  } catch (error) {
21011
21155
  console.error("Error decoding invoice", error);
21012
21156
  }
21013
- amountSats = amountMsats / 1e3;
21157
+ const isZeroAmountInvoice = !amountMsats;
21158
+ if (isZeroAmountInvoice && amountSatsToSend === void 0) {
21159
+ throw new ValidationError(
21160
+ "Invalid amount. User must specify amountSatsToSend for 0 amount lightning invoice",
21161
+ {
21162
+ field: "amountSatsToSend",
21163
+ value: amountSatsToSend,
21164
+ expected: "positive number"
21165
+ }
21166
+ );
21167
+ }
21168
+ amountSats = isZeroAmountInvoice ? amountSatsToSend : amountMsats / 1e3;
21169
+ if (isNaN(amountSats) || amountSats <= 0) {
21170
+ throw new ValidationError("Invalid amount", {
21171
+ field: "amountSats",
21172
+ value: amountSats,
21173
+ expected: "greater than 0"
21174
+ });
21175
+ }
21014
21176
  bolt11String = invoiceString;
21015
21177
  }
21016
21178
  const reason = isInboundPayment ? 1 /* REASON_RECEIVE */ : 0 /* REASON_SEND */;
@@ -21110,7 +21272,7 @@ var LightningService = class {
21110
21272
  };
21111
21273
 
21112
21274
  // src/services/lrc-connection.ts
21113
- import { isNode as isNode3 } from "@lightsparkdev/core";
21275
+ import { isNode as isNode4 } from "@lightsparkdev/core";
21114
21276
  import { retryMiddleware as retryMiddleware2 } from "nice-grpc-client-middleware-retry";
21115
21277
  import { Metadata as Metadata2 } from "nice-grpc-common";
21116
21278
 
@@ -24182,7 +24344,7 @@ var Lrc20ConnectionManager = class {
24182
24344
  }
24183
24345
  async createChannelWithTLS(address2, certPath) {
24184
24346
  try {
24185
- if (isNode3 && !isBun) {
24347
+ if (isNode4 && !isBun) {
24186
24348
  const grpcModule = await import("nice-grpc");
24187
24349
  const { ChannelCredentials, createChannel } = "default" in grpcModule ? grpcModule.default : grpcModule;
24188
24350
  if (certPath) {
@@ -24249,7 +24411,7 @@ var Lrc20ConnectionManager = class {
24249
24411
  return client;
24250
24412
  }
24251
24413
  createMiddleware() {
24252
- if (isNode3) {
24414
+ if (isNode4) {
24253
24415
  return this.createNodeMiddleware();
24254
24416
  } else {
24255
24417
  return this.createBrowserMiddleware();
@@ -24259,7 +24421,7 @@ var Lrc20ConnectionManager = class {
24259
24421
  return async function* (call, options) {
24260
24422
  return yield* call.next(call.request, {
24261
24423
  ...options,
24262
- metadata: Metadata2(options.metadata).set("User-Agent", "spark-js-sdk")
24424
+ metadata: Metadata2(options.metadata).set("X-Client-Env", clientEnv)
24263
24425
  });
24264
24426
  }.bind(this);
24265
24427
  }
@@ -24267,7 +24429,7 @@ var Lrc20ConnectionManager = class {
24267
24429
  return async function* (call, options) {
24268
24430
  return yield* call.next(call.request, {
24269
24431
  ...options,
24270
- metadata: Metadata2(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("User-Agent", "spark-js-sdk")
24432
+ metadata: Metadata2(options.metadata).set("X-Requested-With", "XMLHttpRequest").set("X-Grpc-Web", "1").set("Content-Type", "application/grpc-web+proto").set("X-Client-Env", clientEnv)
24271
24433
  });
24272
24434
  }.bind(this);
24273
24435
  }
@@ -24279,7 +24441,7 @@ var Lrc20ConnectionManager = class {
24279
24441
  };
24280
24442
  let options = {};
24281
24443
  const isNodeChannel = "close" in channel;
24282
- if (isNode3 && isNodeChannel && !isBun) {
24444
+ if (isNode4 && isNodeChannel && !isBun) {
24283
24445
  const grpcModule = await import("nice-grpc");
24284
24446
  const { openTelemetryClientMiddleware } = await import("nice-grpc-opentelemetry");
24285
24447
  const { createClientFactory } = "default" in grpcModule ? grpcModule.default : grpcModule;
@@ -24324,7 +24486,7 @@ var Lrc20ConnectionManager = class {
24324
24486
 
24325
24487
  // src/services/token-transactions.ts
24326
24488
  import {
24327
- bytesToHex as bytesToHex9,
24489
+ bytesToHex as bytesToHex10,
24328
24490
  bytesToNumberBE as bytesToNumberBE7,
24329
24491
  numberToBytesBE as numberToBytesBE5
24330
24492
  } from "@noble/curves/abstract/utils";
@@ -24333,6 +24495,19 @@ import { secp256k1 as secp256k113 } from "@noble/curves/secp256k1";
24333
24495
  // src/utils/token-hashing.ts
24334
24496
  import { sha256 as sha25611 } from "@noble/hashes/sha2";
24335
24497
  function hashTokenTransaction(tokenTransaction, partialHash = false) {
24498
+ switch (tokenTransaction.version) {
24499
+ case 0:
24500
+ return hashTokenTransactionV0(tokenTransaction, partialHash);
24501
+ case 1:
24502
+ return hashTokenTransactionV1(tokenTransaction, partialHash);
24503
+ default:
24504
+ throw new ValidationError("invalid token transaction version", {
24505
+ field: "tokenTransaction.version",
24506
+ value: tokenTransaction.version
24507
+ });
24508
+ }
24509
+ }
24510
+ function hashTokenTransactionV0(tokenTransaction, partialHash = false) {
24336
24511
  if (!tokenTransaction) {
24337
24512
  throw new ValidationError("token transaction cannot be nil", {
24338
24513
  field: "tokenTransaction"
@@ -24580,6 +24755,275 @@ function hashTokenTransaction(tokenTransaction, partialHash = false) {
24580
24755
  finalHashObj.update(concatenatedHashes);
24581
24756
  return finalHashObj.digest();
24582
24757
  }
24758
+ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
24759
+ if (!tokenTransaction) {
24760
+ throw new ValidationError("token transaction cannot be nil", {
24761
+ field: "tokenTransaction"
24762
+ });
24763
+ }
24764
+ let allHashes = [];
24765
+ const versionHashObj = sha25611.create();
24766
+ const versionBytes = new Uint8Array(4);
24767
+ new DataView(versionBytes.buffer).setUint32(
24768
+ 0,
24769
+ tokenTransaction.version,
24770
+ false
24771
+ // false for big-endian
24772
+ );
24773
+ versionHashObj.update(versionBytes);
24774
+ allHashes.push(versionHashObj.digest());
24775
+ if (tokenTransaction.tokenInputs?.$case === "transferInput") {
24776
+ if (!tokenTransaction.tokenInputs.transferInput.outputsToSpend) {
24777
+ throw new ValidationError("outputs to spend cannot be null", {
24778
+ field: "tokenInputs.transferInput.outputsToSpend"
24779
+ });
24780
+ }
24781
+ if (tokenTransaction.tokenInputs.transferInput.outputsToSpend.length === 0) {
24782
+ throw new ValidationError("outputs to spend cannot be empty", {
24783
+ field: "tokenInputs.transferInput.outputsToSpend"
24784
+ });
24785
+ }
24786
+ for (const [
24787
+ i,
24788
+ output
24789
+ ] of tokenTransaction.tokenInputs.transferInput.outputsToSpend.entries()) {
24790
+ if (!output) {
24791
+ throw new ValidationError(`output cannot be null at index ${i}`, {
24792
+ field: `tokenInputs.transferInput.outputsToSpend[${i}]`,
24793
+ index: i
24794
+ });
24795
+ }
24796
+ const hashObj2 = sha25611.create();
24797
+ if (output.prevTokenTransactionHash) {
24798
+ const prevHash = output.prevTokenTransactionHash;
24799
+ if (output.prevTokenTransactionHash.length !== 32) {
24800
+ throw new ValidationError(
24801
+ `invalid previous transaction hash length at index ${i}`,
24802
+ {
24803
+ field: `tokenInputs.transferInput.outputsToSpend[${i}].prevTokenTransactionHash`,
24804
+ value: prevHash,
24805
+ expectedLength: 32,
24806
+ actualLength: prevHash.length,
24807
+ index: i
24808
+ }
24809
+ );
24810
+ }
24811
+ hashObj2.update(output.prevTokenTransactionHash);
24812
+ }
24813
+ const voutBytes = new Uint8Array(4);
24814
+ new DataView(voutBytes.buffer).setUint32(
24815
+ 0,
24816
+ output.prevTokenTransactionVout,
24817
+ false
24818
+ );
24819
+ hashObj2.update(voutBytes);
24820
+ allHashes.push(hashObj2.digest());
24821
+ }
24822
+ }
24823
+ if (tokenTransaction.tokenInputs?.$case === "mintInput") {
24824
+ const hashObj2 = sha25611.create();
24825
+ if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
24826
+ const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
24827
+ if (issuerPubKey.length === 0) {
24828
+ throw new ValidationError("issuer public key cannot be empty", {
24829
+ field: "tokenInputs.mintInput.issuerPublicKey",
24830
+ value: issuerPubKey,
24831
+ expectedLength: 1,
24832
+ actualLength: 0
24833
+ });
24834
+ }
24835
+ hashObj2.update(issuerPubKey);
24836
+ if (tokenTransaction.tokenInputs.mintInput.issuerProvidedTimestamp != 0) {
24837
+ const timestampBytes = new Uint8Array(8);
24838
+ new DataView(timestampBytes.buffer).setBigUint64(
24839
+ 0,
24840
+ BigInt(
24841
+ tokenTransaction.tokenInputs.mintInput.issuerProvidedTimestamp
24842
+ ),
24843
+ true
24844
+ // true for little-endian to match Go implementation
24845
+ );
24846
+ hashObj2.update(timestampBytes);
24847
+ }
24848
+ allHashes.push(hashObj2.digest());
24849
+ }
24850
+ }
24851
+ if (!tokenTransaction.tokenOutputs) {
24852
+ throw new ValidationError("token outputs cannot be null", {
24853
+ field: "tokenOutputs"
24854
+ });
24855
+ }
24856
+ if (tokenTransaction.tokenOutputs.length === 0) {
24857
+ throw new ValidationError("token outputs cannot be empty", {
24858
+ field: "tokenOutputs"
24859
+ });
24860
+ }
24861
+ for (const [i, output] of tokenTransaction.tokenOutputs.entries()) {
24862
+ if (!output) {
24863
+ throw new ValidationError(`output cannot be null at index ${i}`, {
24864
+ field: `tokenOutputs[${i}]`,
24865
+ index: i
24866
+ });
24867
+ }
24868
+ const hashObj2 = sha25611.create();
24869
+ if (output.id && !partialHash) {
24870
+ if (output.id.length === 0) {
24871
+ throw new ValidationError(`output ID at index ${i} cannot be empty`, {
24872
+ field: `tokenOutputs[${i}].id`,
24873
+ index: i
24874
+ });
24875
+ }
24876
+ hashObj2.update(new TextEncoder().encode(output.id));
24877
+ }
24878
+ if (output.ownerPublicKey) {
24879
+ if (output.ownerPublicKey.length === 0) {
24880
+ throw new ValidationError(
24881
+ `owner public key at index ${i} cannot be empty`,
24882
+ {
24883
+ field: `tokenOutputs[${i}].ownerPublicKey`,
24884
+ index: i
24885
+ }
24886
+ );
24887
+ }
24888
+ hashObj2.update(output.ownerPublicKey);
24889
+ }
24890
+ if (!partialHash) {
24891
+ const revPubKey = output.revocationCommitment;
24892
+ if (revPubKey) {
24893
+ if (revPubKey.length === 0) {
24894
+ throw new ValidationError(
24895
+ `revocation commitment at index ${i} cannot be empty`,
24896
+ {
24897
+ field: `tokenOutputs[${i}].revocationCommitment`,
24898
+ index: i
24899
+ }
24900
+ );
24901
+ }
24902
+ hashObj2.update(revPubKey);
24903
+ }
24904
+ const bondBytes = new Uint8Array(8);
24905
+ new DataView(bondBytes.buffer).setBigUint64(
24906
+ 0,
24907
+ BigInt(output.withdrawBondSats),
24908
+ false
24909
+ );
24910
+ hashObj2.update(bondBytes);
24911
+ const locktimeBytes = new Uint8Array(8);
24912
+ new DataView(locktimeBytes.buffer).setBigUint64(
24913
+ 0,
24914
+ BigInt(output.withdrawRelativeBlockLocktime),
24915
+ false
24916
+ );
24917
+ hashObj2.update(locktimeBytes);
24918
+ }
24919
+ if (output.tokenPublicKey) {
24920
+ if (output.tokenPublicKey.length === 0) {
24921
+ throw new ValidationError(
24922
+ `token public key at index ${i} cannot be empty`,
24923
+ {
24924
+ field: `tokenOutputs[${i}].tokenPublicKey`,
24925
+ index: i
24926
+ }
24927
+ );
24928
+ }
24929
+ hashObj2.update(output.tokenPublicKey);
24930
+ }
24931
+ if (output.tokenAmount) {
24932
+ if (output.tokenAmount.length === 0) {
24933
+ throw new ValidationError(
24934
+ `token amount at index ${i} cannot be empty`,
24935
+ {
24936
+ field: `tokenOutputs[${i}].tokenAmount`,
24937
+ index: i
24938
+ }
24939
+ );
24940
+ }
24941
+ if (output.tokenAmount.length > 16) {
24942
+ throw new ValidationError(
24943
+ `token amount at index ${i} exceeds maximum length`,
24944
+ {
24945
+ field: `tokenOutputs[${i}].tokenAmount`,
24946
+ value: output.tokenAmount,
24947
+ expectedLength: 16,
24948
+ actualLength: output.tokenAmount.length,
24949
+ index: i
24950
+ }
24951
+ );
24952
+ }
24953
+ hashObj2.update(output.tokenAmount);
24954
+ }
24955
+ allHashes.push(hashObj2.digest());
24956
+ }
24957
+ if (!tokenTransaction.sparkOperatorIdentityPublicKeys) {
24958
+ throw new ValidationError(
24959
+ "spark operator identity public keys cannot be null",
24960
+ {}
24961
+ );
24962
+ }
24963
+ const sortedPubKeys = [
24964
+ ...tokenTransaction.sparkOperatorIdentityPublicKeys || []
24965
+ ].sort((a, b) => {
24966
+ for (let i = 0; i < a.length && i < b.length; i++) {
24967
+ if (a[i] !== b[i]) return a[i] - b[i];
24968
+ }
24969
+ return a.length - b.length;
24970
+ });
24971
+ for (const [i, pubKey] of sortedPubKeys.entries()) {
24972
+ if (!pubKey) {
24973
+ throw new ValidationError(
24974
+ `operator public key at index ${i} cannot be null`,
24975
+ {
24976
+ field: `sparkOperatorIdentityPublicKeys[${i}]`,
24977
+ index: i
24978
+ }
24979
+ );
24980
+ }
24981
+ if (pubKey.length === 0) {
24982
+ throw new ValidationError(
24983
+ `operator public key at index ${i} cannot be empty`,
24984
+ {
24985
+ field: `sparkOperatorIdentityPublicKeys[${i}]`,
24986
+ index: i
24987
+ }
24988
+ );
24989
+ }
24990
+ const hashObj2 = sha25611.create();
24991
+ hashObj2.update(pubKey);
24992
+ allHashes.push(hashObj2.digest());
24993
+ }
24994
+ const hashObj = sha25611.create();
24995
+ let networkBytes = new Uint8Array(4);
24996
+ new DataView(networkBytes.buffer).setUint32(
24997
+ 0,
24998
+ tokenTransaction.network.valueOf(),
24999
+ false
25000
+ // false for big-endian
25001
+ );
25002
+ hashObj.update(networkBytes);
25003
+ allHashes.push(hashObj.digest());
25004
+ const expiryHashObj = sha25611.create();
25005
+ const validityDurationBytes = new Uint8Array(8);
25006
+ const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
25007
+ new DataView(validityDurationBytes.buffer).setBigUint64(
25008
+ 0,
25009
+ BigInt(expiryUnixTime),
25010
+ false
25011
+ // false for big-endian
25012
+ );
25013
+ expiryHashObj.update(validityDurationBytes);
25014
+ allHashes.push(expiryHashObj.digest());
25015
+ const finalHashObj = sha25611.create();
25016
+ const concatenatedHashes = new Uint8Array(
25017
+ allHashes.reduce((sum, hash) => sum + hash.length, 0)
25018
+ );
25019
+ let offset = 0;
25020
+ for (const hash of allHashes) {
25021
+ concatenatedHashes.set(hash, offset);
25022
+ offset += hash.length;
25023
+ }
25024
+ finalHashObj.update(concatenatedHashes);
25025
+ return finalHashObj.digest();
25026
+ }
24583
25027
  function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
24584
25028
  if (!payload) {
24585
25029
  throw new ValidationError(
@@ -24630,7 +25074,7 @@ function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
24630
25074
  }
24631
25075
 
24632
25076
  // src/utils/token-transactions.ts
24633
- import { bytesToHex as bytesToHex7, bytesToNumberBE as bytesToNumberBE5 } from "@noble/curves/abstract/utils";
25077
+ import { bytesToHex as bytesToHex8, bytesToNumberBE as bytesToNumberBE5 } from "@noble/curves/abstract/utils";
24634
25078
  function calculateAvailableTokenAmount(outputLeaves) {
24635
25079
  return outputLeaves.reduce(
24636
25080
  (sum, output) => sum + BigInt(bytesToNumberBE5(output.output.tokenAmount)),
@@ -24638,7 +25082,7 @@ function calculateAvailableTokenAmount(outputLeaves) {
24638
25082
  );
24639
25083
  }
24640
25084
  function checkIfSelectedOutputsAreAvailable(selectedOutputs, tokenOutputs, tokenPublicKey) {
24641
- const tokenPubKeyHex = bytesToHex7(tokenPublicKey);
25085
+ const tokenPubKeyHex = bytesToHex8(tokenPublicKey);
24642
25086
  const tokenOutputsAvailable = tokenOutputs.get(tokenPubKeyHex);
24643
25087
  if (!tokenOutputsAvailable) {
24644
25088
  return false;
@@ -24927,7 +25371,7 @@ import { hexToBytes as hexToBytes9 } from "@noble/hashes/utils";
24927
25371
 
24928
25372
  // src/address/address.ts
24929
25373
  import { secp256k1 as secp256k111 } from "@noble/curves/secp256k1";
24930
- import { bytesToHex as bytesToHex8, hexToBytes as hexToBytes8 } from "@noble/hashes/utils";
25374
+ import { bytesToHex as bytesToHex9, hexToBytes as hexToBytes8 } from "@noble/hashes/utils";
24931
25375
  import { bech32m } from "@scure/base";
24932
25376
  import { UUID } from "uuidv7";
24933
25377
  import { bytesToNumberBE as bytesToNumberBE6 } from "@noble/curves/abstract/utils";
@@ -24978,7 +25422,7 @@ function decodeSparkAddress(address2, network) {
24978
25422
  });
24979
25423
  }
24980
25424
  const payload = SparkAddress.decode(bech32m.fromWords(decoded.words));
24981
- const publicKey = bytesToHex8(payload.identityPublicKey);
25425
+ const publicKey = bytesToHex9(payload.identityPublicKey);
24982
25426
  isValidPublicKey(publicKey);
24983
25427
  const paymentIntentFields = payload.paymentIntentFields;
24984
25428
  return {
@@ -24986,7 +25430,7 @@ function decodeSparkAddress(address2, network) {
24986
25430
  network,
24987
25431
  paymentIntentFields: paymentIntentFields && {
24988
25432
  id: UUID.ofInner(paymentIntentFields.id).toString(),
24989
- assetIdentifier: paymentIntentFields.assetIdentifier ? bytesToHex8(paymentIntentFields.assetIdentifier) : void 0,
25433
+ assetIdentifier: paymentIntentFields.assetIdentifier ? bytesToHex9(paymentIntentFields.assetIdentifier) : void 0,
24990
25434
  assetAmount: bytesToNumberBE6(paymentIntentFields.assetAmount),
24991
25435
  memo: paymentIntentFields.memo
24992
25436
  }
@@ -25312,7 +25756,7 @@ var TokenTransactionService = class {
25312
25756
  {
25313
25757
  field: "revocationCommitment",
25314
25758
  value: derivedRevocationCommitment,
25315
- expected: bytesToHex9(outputsToSpendCommitments[outputIndex]),
25759
+ expected: bytesToHex10(outputsToSpendCommitments[outputIndex]),
25316
25760
  outputIndex
25317
25761
  }
25318
25762
  )
@@ -25338,7 +25782,7 @@ var TokenTransactionService = class {
25338
25782
  threshold
25339
25783
  );
25340
25784
  }
25341
- return bytesToHex9(finalTokenTransactionHash);
25785
+ return bytesToHex10(finalTokenTransactionHash);
25342
25786
  }
25343
25787
  async broadcastTokenTransactionV1(tokenTransaction, signingOperators, outputsToSpendSigningPublicKeys, outputsToSpendCommitments) {
25344
25788
  const { finalTokenTransaction, finalTokenTransactionHash, threshold } = await this.startTokenTransaction(
@@ -25352,13 +25796,13 @@ var TokenTransactionService = class {
25352
25796
  finalTokenTransactionHash,
25353
25797
  signingOperators
25354
25798
  );
25355
- return bytesToHex9(finalTokenTransactionHash);
25799
+ return bytesToHex10(finalTokenTransactionHash);
25356
25800
  }
25357
25801
  async startTokenTransactionV0(tokenTransaction, signingOperators, outputsToSpendSigningPublicKeys, outputsToSpendCommitments) {
25358
25802
  const sparkClient = await this.connectionManager.createSparkClient(
25359
25803
  this.config.getCoordinatorAddress()
25360
25804
  );
25361
- const partialTokenTransactionHash = hashTokenTransaction(
25805
+ const partialTokenTransactionHash = hashTokenTransactionV0(
25362
25806
  tokenTransaction,
25363
25807
  true
25364
25808
  );
@@ -25439,7 +25883,7 @@ var TokenTransactionService = class {
25439
25883
  this.config.getThreshold()
25440
25884
  );
25441
25885
  const finalTokenTransaction = startResponse.finalTokenTransaction;
25442
- const finalTokenTransactionHash = hashTokenTransaction(
25886
+ const finalTokenTransactionHash = hashTokenTransactionV0(
25443
25887
  finalTokenTransaction,
25444
25888
  false
25445
25889
  );
@@ -25507,7 +25951,9 @@ var TokenTransactionService = class {
25507
25951
  const startResponse = await sparkClient.start_transaction(
25508
25952
  {
25509
25953
  identityPublicKey: await this.config.signer.getIdentityPublicKey(),
25510
- partialTokenTransaction: tokenTransaction
25954
+ partialTokenTransaction: tokenTransaction,
25955
+ validityDurationSeconds: await this.config.getTokenValidityDurationSeconds(),
25956
+ partialTokenTransactionOwnerSignatures: ownerSignaturesWithIndex
25511
25957
  },
25512
25958
  {
25513
25959
  retry: true,
@@ -25706,7 +26152,7 @@ var TokenTransactionService = class {
25706
26152
  []
25707
26153
  );
25708
26154
  unsortedTokenOutputs.forEach((output) => {
25709
- const tokenKey = bytesToHex9(output.output.tokenPublicKey);
26155
+ const tokenKey = bytesToHex10(output.output.tokenPublicKey);
25710
26156
  const index = output.previousTransactionVout;
25711
26157
  tokenOutputs.set(tokenKey, [
25712
26158
  { ...output, previousTransactionVout: index }
@@ -25763,7 +26209,7 @@ var TokenTransactionService = class {
25763
26209
  // Helper function for deciding if the signer public key is the identity public key
25764
26210
  async signMessageWithKey(message, publicKey) {
25765
26211
  const tokenSignatures = this.config.getTokenSignatures();
25766
- if (bytesToHex9(publicKey) === bytesToHex9(await this.config.signer.getIdentityPublicKey())) {
26212
+ if (bytesToHex10(publicKey) === bytesToHex10(await this.config.signer.getIdentityPublicKey())) {
25767
26213
  if (tokenSignatures === "SCHNORR") {
25768
26214
  return await this.config.signer.signSchnorrWithIdentityKey(message);
25769
26215
  } else {
@@ -26425,7 +26871,7 @@ var SigningService = class {
26425
26871
  };
26426
26872
 
26427
26873
  // src/tests/utils/test-faucet.ts
26428
- import { bytesToHex as bytesToHex10, hexToBytes as hexToBytes12 } from "@noble/curves/abstract/utils";
26874
+ import { bytesToHex as bytesToHex11, hexToBytes as hexToBytes12 } from "@noble/curves/abstract/utils";
26429
26875
  import { schnorr as schnorr5, secp256k1 as secp256k114 } from "@noble/curves/secp256k1";
26430
26876
  import * as btc4 from "@scure/btc-signer";
26431
26877
  import { Address as Address5, OutScript as OutScript4, SigHash as SigHash2, Transaction as Transaction8 } from "@scure/btc-signer";
@@ -26558,7 +27004,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
26558
27004
  },
26559
27005
  STATIC_MINING_KEY
26560
27006
  );
26561
- await this.broadcastTx(bytesToHex10(signedSplitTx.extract()));
27007
+ await this.broadcastTx(bytesToHex11(signedSplitTx.extract()));
26562
27008
  const splitTxId = signedSplitTx.id;
26563
27009
  for (let i = 0; i < numCoinsToCreate; i++) {
26564
27010
  this.coins.push({
@@ -26592,7 +27038,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
26592
27038
  coinToSend.txout,
26593
27039
  coinToSend.key
26594
27040
  );
26595
- await this.broadcastTx(bytesToHex10(signedTx.extract()));
27041
+ await this.broadcastTx(bytesToHex11(signedTx.extract()));
26596
27042
  }
26597
27043
  async signFaucetCoin(unsignedTx, fundingTxOut, key) {
26598
27044
  const pubKey = secp256k114.getPublicKey(key);
@@ -26711,7 +27157,7 @@ var BitcoinFaucet = class _BitcoinFaucet {
26711
27157
  });
26712
27158
  }
26713
27159
  const signedTx = await this.signFaucetCoin(tx, coin.txout, coin.key);
26714
- const txHex = bytesToHex10(signedTx.extract());
27160
+ const txHex = bytesToHex11(signedTx.extract());
26715
27161
  await this.broadcastTx(txHex);
26716
27162
  const randomKey = secp256k114.utils.randomPrivateKey();
26717
27163
  const randomPubKey = secp256k114.getPublicKey(randomKey);
@@ -26728,18 +27174,18 @@ var BitcoinFaucet = class _BitcoinFaucet {
26728
27174
  };
26729
27175
 
26730
27176
  // src/types/sdk-types.ts
26731
- import { bytesToHex as bytesToHex11 } from "@noble/curves/abstract/utils";
27177
+ import { bytesToHex as bytesToHex12 } from "@noble/curves/abstract/utils";
26732
27178
  function mapTreeNodeToWalletLeaf(proto) {
26733
27179
  return {
26734
27180
  id: proto.id,
26735
27181
  treeId: proto.treeId,
26736
27182
  value: proto.value,
26737
27183
  parentNodeId: proto.parentNodeId,
26738
- nodeTx: bytesToHex11(proto.nodeTx),
26739
- refundTx: bytesToHex11(proto.refundTx),
27184
+ nodeTx: bytesToHex12(proto.nodeTx),
27185
+ refundTx: bytesToHex12(proto.refundTx),
26740
27186
  vout: proto.vout,
26741
- verifyingPublicKey: bytesToHex11(proto.verifyingPublicKey),
26742
- ownerIdentityPublicKey: bytesToHex11(proto.ownerIdentityPublicKey),
27187
+ verifyingPublicKey: bytesToHex12(proto.verifyingPublicKey),
27188
+ ownerIdentityPublicKey: bytesToHex12(proto.ownerIdentityPublicKey),
26743
27189
  signingKeyshare: proto.signingKeyshare,
26744
27190
  status: proto.status,
26745
27191
  network: Network[proto.network]
@@ -26748,14 +27194,14 @@ function mapTreeNodeToWalletLeaf(proto) {
26748
27194
  function mapTransferLeafToWalletTransferLeaf(proto) {
26749
27195
  return {
26750
27196
  leaf: proto.leaf ? mapTreeNodeToWalletLeaf(proto.leaf) : void 0,
26751
- secretCipher: bytesToHex11(proto.secretCipher),
26752
- signature: bytesToHex11(proto.signature),
26753
- intermediateRefundTx: bytesToHex11(proto.intermediateRefundTx)
27197
+ secretCipher: bytesToHex12(proto.secretCipher),
27198
+ signature: bytesToHex12(proto.signature),
27199
+ intermediateRefundTx: bytesToHex12(proto.intermediateRefundTx)
26754
27200
  };
26755
27201
  }
26756
27202
  function mapTransferToWalletTransfer(proto, identityPublicKey) {
26757
- const receiverIdentityPublicKey = bytesToHex11(proto.receiverIdentityPublicKey);
26758
- const senderIdentityPublicKey = bytesToHex11(proto.senderIdentityPublicKey);
27203
+ const receiverIdentityPublicKey = bytesToHex12(proto.receiverIdentityPublicKey);
27204
+ const senderIdentityPublicKey = bytesToHex12(proto.senderIdentityPublicKey);
26759
27205
  return {
26760
27206
  id: proto.id,
26761
27207
  senderIdentityPublicKey,
@@ -26952,7 +27398,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
26952
27398
  setTimeout(maybeUnref, 100);
26953
27399
  }
26954
27400
  };
26955
- if (isNode4) {
27401
+ if (isNode5) {
26956
27402
  maybeUnref();
26957
27403
  }
26958
27404
  const claimedTransfersIds = await this.claimTransfers();
@@ -27187,7 +27633,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27187
27633
  * @returns {Promise<string>} The identity public key as a hex string.
27188
27634
  */
27189
27635
  async getIdentityPublicKey() {
27190
- return bytesToHex12(await this.config.signer.getIdentityPublicKey());
27636
+ return bytesToHex13(await this.config.signer.getIdentityPublicKey());
27191
27637
  }
27192
27638
  /**
27193
27639
  * Gets the Spark address of the wallet.
@@ -27197,7 +27643,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27197
27643
  async getSparkAddress() {
27198
27644
  if (!this.sparkAddress) {
27199
27645
  this.sparkAddress = encodeSparkAddress({
27200
- identityPublicKey: bytesToHex12(
27646
+ identityPublicKey: bytesToHex13(
27201
27647
  await this.config.signer.getIdentityPublicKey()
27202
27648
  ),
27203
27649
  network: this.config.getNetworkType()
@@ -27234,7 +27680,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27234
27680
  isValidPublicKey(assetIdentifier);
27235
27681
  }
27236
27682
  const paymentRequest = encodeSparkAddress({
27237
- identityPublicKey: bytesToHex12(
27683
+ identityPublicKey: bytesToHex13(
27238
27684
  await this.config.signer.getIdentityPublicKey()
27239
27685
  ),
27240
27686
  network: this.config.getNetworkType(),
@@ -27409,10 +27855,10 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27409
27855
  const userLeaves = [];
27410
27856
  userLeaves.push({
27411
27857
  leaf_id: transfer.leaves[0].leaf.id,
27412
- raw_unsigned_refund_transaction: bytesToHex12(
27858
+ raw_unsigned_refund_transaction: bytesToHex13(
27413
27859
  transfer.leaves[0].intermediateRefundTx
27414
27860
  ),
27415
- adaptor_added_signature: bytesToHex12(adaptorSignature)
27861
+ adaptor_added_signature: bytesToHex13(adaptorSignature)
27416
27862
  });
27417
27863
  for (let i = 1; i < transfer.leaves.length; i++) {
27418
27864
  const leaf = transfer.leaves[i];
@@ -27429,14 +27875,14 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27429
27875
  );
27430
27876
  userLeaves.push({
27431
27877
  leaf_id: leaf.leaf.id,
27432
- raw_unsigned_refund_transaction: bytesToHex12(
27878
+ raw_unsigned_refund_transaction: bytesToHex13(
27433
27879
  leaf.intermediateRefundTx
27434
27880
  ),
27435
- adaptor_added_signature: bytesToHex12(signature)
27881
+ adaptor_added_signature: bytesToHex13(signature)
27436
27882
  });
27437
27883
  }
27438
27884
  const sspClient = this.getSspClient();
27439
- const adaptorPubkey = bytesToHex12(
27885
+ const adaptorPubkey = bytesToHex13(
27440
27886
  secp256k115.getPublicKey(adaptorPrivateKey)
27441
27887
  );
27442
27888
  let request = null;
@@ -27496,7 +27942,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27496
27942
  signatureMap
27497
27943
  );
27498
27944
  const completeResponse = await sspClient.completeLeaveSwap({
27499
- adaptorSecretKey: bytesToHex12(adaptorPrivateKey),
27945
+ adaptorSecretKey: bytesToHex13(adaptorPrivateKey),
27500
27946
  userOutboundTransferExternalId: transfer.id,
27501
27947
  leavesSwapRequestId: request.id
27502
27948
  });
@@ -27522,7 +27968,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27522
27968
  limit,
27523
27969
  offset
27524
27970
  );
27525
- const identityPublicKey = bytesToHex12(
27971
+ const identityPublicKey = bytesToHex13(
27526
27972
  await this.config.signer.getIdentityPublicKey()
27527
27973
  );
27528
27974
  return {
@@ -27546,7 +27992,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27546
27992
  publicKeys: Array.from(tokenBalances.keys()).map(hexToBytes13)
27547
27993
  });
27548
27994
  return tokenInfo.tokenPubkeyInfos.map((info) => ({
27549
- tokenPublicKey: bytesToHex12(info.announcement.publicKey.publicKey),
27995
+ tokenPublicKey: bytesToHex13(info.announcement.publicKey.publicKey),
27550
27996
  tokenName: info.announcement.name,
27551
27997
  tokenSymbol: info.announcement.symbol,
27552
27998
  tokenDecimals: Number(bytesToNumberBE8(info.announcement.decimal)),
@@ -27583,7 +28029,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27583
28029
  });
27584
28030
  const result = /* @__PURE__ */ new Map();
27585
28031
  for (const info of tokenInfo.tokenPubkeyInfos) {
27586
- const tokenPublicKey = bytesToHex12(
28032
+ const tokenPublicKey = bytesToHex13(
27587
28033
  info.announcement.publicKey.publicKey
27588
28034
  );
27589
28035
  const leaves = this.tokenOutputs.get(tokenPublicKey);
@@ -27728,7 +28174,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27728
28174
  if (network === BitcoinNetwork_default.FUTURE_VALUE) {
27729
28175
  network = BitcoinNetwork_default.REGTEST;
27730
28176
  }
27731
- const depositSecretKey = bytesToHex12(
28177
+ const depositSecretKey = bytesToHex13(
27732
28178
  await this.config.signer.getStaticDepositSecretKey(0)
27733
28179
  );
27734
28180
  const message = await this.getStaticDepositSigningPayload(
@@ -27741,7 +28187,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27741
28187
  );
27742
28188
  const hashBuffer = sha25613(message);
27743
28189
  const signatureBytes = await this.config.signer.signMessageWithIdentityKey(hashBuffer);
27744
- const signature = bytesToHex12(signatureBytes);
28190
+ const signature = bytesToHex13(signatureBytes);
27745
28191
  const response = await this.sspClient.claimStaticDeposit({
27746
28192
  transactionId,
27747
28193
  outputIndex,
@@ -27826,7 +28272,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
27826
28272
  networkJSON.toLowerCase(),
27827
28273
  2 /* Refund */,
27828
28274
  creditAmountSats,
27829
- bytesToHex12(spendTxSighash)
28275
+ bytesToHex13(spendTxSighash)
27830
28276
  );
27831
28277
  const hashBuffer = sha25613(message);
27832
28278
  const swapResponseUserSignature = await this.config.signer.signMessageWithIdentityKey(hashBuffer);
@@ -28298,7 +28744,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28298
28744
  }
28299
28745
  return mapTransferToWalletTransfer(
28300
28746
  transfer,
28301
- bytesToHex12(await this.config.signer.getIdentityPublicKey())
28747
+ bytesToHex13(await this.config.signer.getIdentityPublicKey())
28302
28748
  );
28303
28749
  });
28304
28750
  }
@@ -28622,7 +29068,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28622
29068
  const invoice2 = await sspClient.requestLightningReceive({
28623
29069
  amountSats: amountSats2,
28624
29070
  network: bitcoinNetwork,
28625
- paymentHash: bytesToHex12(paymentHash),
29071
+ paymentHash: bytesToHex13(paymentHash),
28626
29072
  expirySecs: expirySeconds,
28627
29073
  memo: memo2,
28628
29074
  includeSparkAddress,
@@ -28677,12 +29123,14 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28677
29123
  * @param {Object} params - Parameters for paying the invoice
28678
29124
  * @param {string} params.invoice - The BOLT11-encoded Lightning invoice to pay
28679
29125
  * @param {boolean} [params.preferSpark] - Whether to prefer a spark transfer over lightning for the payment
29126
+ * @param {number} [params.amountSatsToSend] - The amount in sats to send. This is only valid for 0 amount lightning invoices.
28680
29127
  * @returns {Promise<LightningSendRequest>} The Lightning payment request details
28681
29128
  */
28682
29129
  async payLightningInvoice({
28683
29130
  invoice,
28684
29131
  maxFeeSats,
28685
- preferSpark = false
29132
+ preferSpark = false,
29133
+ amountSatsToSend
28686
29134
  }) {
28687
29135
  const invoiceNetwork = getNetworkFromInvoice(invoice);
28688
29136
  const walletNetwork = this.config.getNetwork();
@@ -28697,7 +29145,36 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28697
29145
  );
28698
29146
  }
28699
29147
  const decodedInvoice = decodeInvoice(invoice);
28700
- const amountSats = decodedInvoice.amountMSats !== null ? Number(decodedInvoice.amountMSats / 1000n) : 0;
29148
+ const amountMSats = decodedInvoice.amountMSats;
29149
+ const isZeroAmountInvoice = !amountMSats;
29150
+ if (!isZeroAmountInvoice && amountSatsToSend !== void 0) {
29151
+ throw new ValidationError(
29152
+ "Invalid amount. User can only specify amountSatsToSend for 0 amount lightning invoice",
29153
+ {
29154
+ field: "amountMSats",
29155
+ value: Number(amountMSats),
29156
+ expected: "0"
29157
+ }
29158
+ );
29159
+ }
29160
+ if (isZeroAmountInvoice && amountSatsToSend === void 0) {
29161
+ throw new ValidationError(
29162
+ "Invalid amount. User must specify amountSatsToSend for 0 amount lightning invoice",
29163
+ {
29164
+ field: "amountMSats",
29165
+ value: Number(amountMSats),
29166
+ expected: "0"
29167
+ }
29168
+ );
29169
+ }
29170
+ const amountSats = isZeroAmountInvoice ? amountSatsToSend : Number(amountMSats / 1000n);
29171
+ if (isNaN(amountSats) || amountSats <= 0) {
29172
+ throw new ValidationError("Invalid amount", {
29173
+ field: "amountSats",
29174
+ value: amountSats,
29175
+ expected: "greater than 0"
29176
+ });
29177
+ }
28701
29178
  const sparkFallbackAddress = decodedInvoice.fallbackAddress;
28702
29179
  const paymentHash = decodedInvoice.paymentHash;
28703
29180
  if (preferSpark) {
@@ -28719,15 +29196,9 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28719
29196
  }
28720
29197
  return await this.withLeaves(async () => {
28721
29198
  const sspClient = this.getSspClient();
28722
- if (isNaN(amountSats) || amountSats <= 0) {
28723
- throw new ValidationError("Invalid amount", {
28724
- field: "amountSats",
28725
- value: amountSats,
28726
- expected: "positive number"
28727
- });
28728
- }
28729
29199
  const feeEstimate = await this.getLightningSendFeeEstimate({
28730
- encodedInvoice: invoice
29200
+ encodedInvoice: invoice,
29201
+ amountSats: isZeroAmountInvoice ? amountSatsToSend : void 0
28731
29202
  });
28732
29203
  if (maxFeeSats < feeEstimate) {
28733
29204
  throw new ValidationError("maxFeeSats does not cover fee estimate", {
@@ -28765,19 +29236,21 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28765
29236
  paymentHash: hexToBytes13(paymentHash),
28766
29237
  isInboundPayment: false,
28767
29238
  invoiceString: invoice,
28768
- feeSats: feeEstimate
29239
+ feeSats: feeEstimate,
29240
+ amountSatsToSend
28769
29241
  });
28770
29242
  if (!swapResponse.transfer) {
28771
29243
  throw new Error("Failed to swap nodes for preimage");
28772
29244
  }
28773
- const transfer = await this.transferService.sendTransferTweakKey(
29245
+ await this.transferService.deliverTransferPackage(
28774
29246
  swapResponse.transfer,
28775
29247
  leavesToSend,
28776
29248
  /* @__PURE__ */ new Map()
28777
29249
  );
28778
29250
  const sspResponse = await sspClient.requestLightningSend({
28779
29251
  encodedInvoice: invoice,
28780
- idempotencyKey: paymentHash
29252
+ idempotencyKey: paymentHash,
29253
+ amountSats: isZeroAmountInvoice ? amountSatsToSend : void 0
28781
29254
  });
28782
29255
  if (!sspResponse) {
28783
29256
  throw new Error("Failed to contact SSP");
@@ -28794,10 +29267,14 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
28794
29267
  * @returns {Promise<number>} Fee estimate for sending Lightning payments
28795
29268
  */
28796
29269
  async getLightningSendFeeEstimate({
28797
- encodedInvoice
29270
+ encodedInvoice,
29271
+ amountSats
28798
29272
  }) {
28799
29273
  const sspClient = this.getSspClient();
28800
- const feeEstimate = await sspClient.getLightningSendFeeEstimate(encodedInvoice);
29274
+ const feeEstimate = await sspClient.getLightningSendFeeEstimate(
29275
+ encodedInvoice,
29276
+ amountSats
29277
+ );
28801
29278
  if (!feeEstimate) {
28802
29279
  throw new Error("Failed to get lightning send fee estimate");
28803
29280
  }
@@ -29050,7 +29527,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
29050
29527
  );
29051
29528
  const groupedOutputs = /* @__PURE__ */ new Map();
29052
29529
  filteredTokenOutputs.forEach((output) => {
29053
- const tokenKey = bytesToHex12(output.output.tokenPublicKey);
29530
+ const tokenKey = bytesToHex13(output.output.tokenPublicKey);
29054
29531
  const index = output.previousTransactionVout;
29055
29532
  if (!groupedOutputs.has(tokenKey)) {
29056
29533
  groupedOutputs.set(tokenKey, []);
@@ -29180,7 +29657,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
29180
29657
  hash,
29181
29658
  compact
29182
29659
  );
29183
- return bytesToHex12(signature);
29660
+ return bytesToHex13(signature);
29184
29661
  }
29185
29662
  /**
29186
29663
  * Validates a message with the identity key.
@@ -29238,7 +29715,7 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
29238
29715
  publicKey,
29239
29716
  this.config.getNetwork()
29240
29717
  );
29241
- if (bytesToHex12(script) === bytesToHex12(identityScript)) {
29718
+ if (bytesToHex13(script) === bytesToHex13(identityScript)) {
29242
29719
  try {
29243
29720
  this.config.signer.signTransactionIndex(tx, i, publicKey);
29244
29721
  inputsSigned++;
@@ -29282,13 +29759,13 @@ var SparkWallet = class _SparkWallet extends EventEmitter {
29282
29759
  depositPubKey,
29283
29760
  this.config.getNetwork()
29284
29761
  );
29285
- if (bytesToHex12(script) === bytesToHex12(identityScript)) {
29762
+ if (bytesToHex13(script) === bytesToHex13(identityScript)) {
29286
29763
  return {
29287
29764
  publicKey: identityPubKey,
29288
29765
  keyType: "identity"
29289
29766
  };
29290
29767
  }
29291
- if (bytesToHex12(script) === bytesToHex12(depositScript)) {
29768
+ if (bytesToHex13(script) === bytesToHex13(depositScript)) {
29292
29769
  return {
29293
29770
  publicKey: depositPubKey,
29294
29771
  keyType: "deposit"
@@ -29673,7 +30150,7 @@ async function isTxBroadcast(txid, baseUrl, network) {
29673
30150
  }
29674
30151
 
29675
30152
  // src/utils/unilateral-exit.ts
29676
- import { bytesToHex as bytesToHex13, hexToBytes as hexToBytes14 } from "@noble/curves/abstract/utils";
30153
+ import { bytesToHex as bytesToHex14, hexToBytes as hexToBytes14 } from "@noble/curves/abstract/utils";
29677
30154
  import { ripemd160 } from "@noble/hashes/legacy";
29678
30155
  import { sha256 as sha25614 } from "@noble/hashes/sha2";
29679
30156
  import * as btc5 from "@scure/btc-signer";
@@ -29744,10 +30221,10 @@ async function constructUnilateralExitTxs(nodeHexStrings, sparkClient, network)
29744
30221
  }
29745
30222
  }
29746
30223
  for (const chainNode of chain) {
29747
- const nodeTx = bytesToHex13(chainNode.nodeTx);
30224
+ const nodeTx = bytesToHex14(chainNode.nodeTx);
29748
30225
  transactions.push(nodeTx);
29749
30226
  if (chainNode.id === node.id) {
29750
- const refundTx = bytesToHex13(chainNode.refundTx);
30227
+ const refundTx = bytesToHex14(chainNode.refundTx);
29751
30228
  transactions.push(refundTx);
29752
30229
  }
29753
30230
  }
@@ -29853,7 +30330,7 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
29853
30330
  }
29854
30331
  }
29855
30332
  for (const chainNode of chain) {
29856
- let nodeTxHex = bytesToHex13(chainNode.nodeTx);
30333
+ let nodeTxHex = bytesToHex14(chainNode.nodeTx);
29857
30334
  try {
29858
30335
  const txObj = getTxFromRawTxHex(nodeTxHex);
29859
30336
  const txid = getTxId(txObj);
@@ -29870,7 +30347,7 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
29870
30347
  for (let i = txObj.outputsLength - 1; i >= 0; i--) {
29871
30348
  const output = txObj.getOutput(i);
29872
30349
  if (output?.amount === 0n && output.script) {
29873
- anchorOutputScriptHex = bytesToHex13(output.script);
30350
+ anchorOutputScriptHex = bytesToHex14(output.script);
29874
30351
  break;
29875
30352
  }
29876
30353
  }
@@ -29895,7 +30372,7 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
29895
30372
  var feeBumpOut = feeBumpTx.outputsLength === 1 ? feeBumpTx.getOutput(0) : null;
29896
30373
  var feeBumpOutPubKey = null;
29897
30374
  for (const usedUtxo of usedUtxos) {
29898
- if (feeBumpOut && bytesToHex13(feeBumpOut.script) == usedUtxo.script) {
30375
+ if (feeBumpOut && bytesToHex14(feeBumpOut.script) == usedUtxo.script) {
29899
30376
  feeBumpOutPubKey = usedUtxo.publicKey;
29900
30377
  }
29901
30378
  const index = availableUtxos.findIndex(
@@ -29910,20 +30387,20 @@ async function constructUnilateralExitFeeBumpPackages(nodeHexStrings, utxos, fee
29910
30387
  txid: getTxId(feeBumpTx),
29911
30388
  vout: 0,
29912
30389
  value: feeBumpOut.amount,
29913
- script: bytesToHex13(feeBumpOut.script),
30390
+ script: bytesToHex14(feeBumpOut.script),
29914
30391
  publicKey: feeBumpOutPubKey
29915
30392
  });
29916
30393
  const finalNodeTx = correctedParentTx || nodeTxHex;
29917
30394
  txPackages.push({ tx: finalNodeTx, feeBumpPsbt: nodeFeeBumpPsbt });
29918
30395
  if (chainNode.id === node.id) {
29919
- let refundTxHex = bytesToHex13(chainNode.refundTx);
30396
+ let refundTxHex = bytesToHex14(chainNode.refundTx);
29920
30397
  try {
29921
30398
  const txObj = getTxFromRawTxHex(refundTxHex);
29922
30399
  let anchorOutputScriptHex;
29923
30400
  for (let i = txObj.outputsLength - 1; i >= 0; i--) {
29924
30401
  const output = txObj.getOutput(i);
29925
30402
  if (output?.amount === 0n && output.script) {
29926
- anchorOutputScriptHex = bytesToHex13(output.script);
30403
+ anchorOutputScriptHex = bytesToHex14(output.script);
29927
30404
  break;
29928
30405
  }
29929
30406
  }
@@ -30040,7 +30517,7 @@ function constructFeeBumpTx(txHex, utxos, feeRate, previousFeeBumpTx) {
30040
30517
  const pubKeyHash = hash160(hexToBytes14(fundingUtxo.publicKey));
30041
30518
  const scriptToUse = new Uint8Array([0, 20, ...pubKeyHash]);
30042
30519
  const providedScript = hexToBytes14(fundingUtxo.script);
30043
- if (bytesToHex13(scriptToUse) !== bytesToHex13(providedScript)) {
30520
+ if (bytesToHex14(scriptToUse) !== bytesToHex14(providedScript)) {
30044
30521
  throw new Error(
30045
30522
  `\u274C Derived script doesn't match provided script for UTXO ${i + 1}.`
30046
30523
  );
@@ -30105,7 +30582,7 @@ function constructFeeBumpTx(txHex, utxos, feeRate, previousFeeBumpTx) {
30105
30582
  }
30106
30583
  let psbtHex;
30107
30584
  try {
30108
- psbtHex = bytesToHex13(builder.toPSBT());
30585
+ psbtHex = bytesToHex14(builder.toPSBT());
30109
30586
  } catch (error) {
30110
30587
  throw new Error(`Failed to extract transaction: ${error}`);
30111
30588
  }
@@ -30176,6 +30653,7 @@ export {
30176
30653
  constructFeeBumpTx,
30177
30654
  constructUnilateralExitFeeBumpPackages,
30178
30655
  constructUnilateralExitTxs,
30656
+ createDummyTx,
30179
30657
  createRefundTx,
30180
30658
  createSigningCommitment,
30181
30659
  createSigningNonce,