@buildonspark/spark-sdk 0.3.6 → 0.3.7

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 (70) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/bare/index.cjs +9240 -9125
  3. package/dist/bare/index.d.cts +14 -11
  4. package/dist/bare/index.d.ts +14 -11
  5. package/dist/bare/index.js +3917 -3802
  6. package/dist/{chunk-XPHYQ2L6.js → chunk-KDEVNW7C.js} +4895 -4779
  7. package/dist/{chunk-LIZFXQWK.js → chunk-P4HYYSMU.js} +1 -1
  8. package/dist/{chunk-EHKP3Y65.js → chunk-SRPKOCG4.js} +1 -2
  9. package/dist/{chunk-FJ7LTA2O.js → chunk-UYTT3C6H.js} +1 -1
  10. package/dist/{client-AHn11NHe.d.cts → client-Bcb7TUIp.d.cts} +11 -9
  11. package/dist/{client-GOlkXliC.d.ts → client-D9T58OY8.d.ts} +11 -9
  12. package/dist/debug.cjs +1852 -1738
  13. package/dist/debug.d.cts +4 -4
  14. package/dist/debug.d.ts +4 -4
  15. package/dist/debug.js +2 -2
  16. package/dist/graphql/objects/index.d.cts +2 -2
  17. package/dist/graphql/objects/index.d.ts +2 -2
  18. package/dist/index.cjs +174 -58
  19. package/dist/index.d.cts +5 -5
  20. package/dist/index.d.ts +5 -5
  21. package/dist/index.js +3 -3
  22. package/dist/index.node.cjs +174 -57
  23. package/dist/index.node.d.cts +5 -5
  24. package/dist/index.node.d.ts +5 -5
  25. package/dist/index.node.js +2 -2
  26. package/dist/{logging-D7ukPwRA.d.ts → logging-JIaZZIbR.d.ts} +2 -2
  27. package/dist/{logging-CW3kwBaM.d.cts → logging-zkr4UlOi.d.cts} +2 -2
  28. package/dist/native/{index.cjs → index.react-native.cjs} +182 -62
  29. package/dist/native/{index.d.cts → index.react-native.d.cts} +19 -15
  30. package/dist/native/{index.d.ts → index.react-native.d.ts} +19 -15
  31. package/dist/native/{index.js → index.react-native.js} +179 -60
  32. package/dist/{spark-wallet-NxG55m7K.d.cts → spark-wallet-BuFrUWeE.d.cts} +4 -3
  33. package/dist/{spark-wallet-jwNvWvpK.d.ts → spark-wallet-CE5PYiIb.d.ts} +4 -3
  34. package/dist/{spark-wallet.browser-Cg4fB-Nm.d.ts → spark-wallet.browser-BwYkkOBU.d.ts} +1 -1
  35. package/dist/{spark-wallet.browser-Db7Y95Kt.d.cts → spark-wallet.browser-DC3jdQPW.d.cts} +1 -1
  36. package/dist/{spark-wallet.node-DB3ZqtJG.d.ts → spark-wallet.node-C9d2W-Nb.d.ts} +1 -1
  37. package/dist/{spark-wallet.node-HEG2ahNd.d.cts → spark-wallet.node-CR_zNxmy.d.cts} +1 -1
  38. package/dist/tests/test-utils.cjs +168 -51
  39. package/dist/tests/test-utils.d.cts +4 -4
  40. package/dist/tests/test-utils.d.ts +4 -4
  41. package/dist/tests/test-utils.js +4 -4
  42. package/dist/{token-transactions-B2-BO7Oz.d.ts → token-transactions-BZoJuvuE.d.ts} +1 -1
  43. package/dist/{token-transactions-BAN68xwg.d.cts → token-transactions-I_OFIoNH.d.cts} +1 -1
  44. package/dist/types/index.d.cts +1 -1
  45. package/dist/types/index.d.ts +1 -1
  46. package/package.json +14 -4
  47. package/src/graphql/client.ts +6 -9
  48. package/src/graphql/mutations/CompleteCoopExit.ts +1 -1
  49. package/src/graphql/mutations/RequestCoopExit.ts +3 -1
  50. package/src/graphql/mutations/RequestLightningSend.ts +3 -1
  51. package/src/graphql/objects/CompleteCoopExitInput.ts +22 -33
  52. package/src/graphql/objects/RequestCoopExitInput.ts +39 -45
  53. package/src/graphql/objects/RequestLightningSendInput.ts +31 -39
  54. package/src/index.react-native.ts +21 -0
  55. package/src/services/config.ts +2 -2
  56. package/src/services/connection/connection.ts +10 -0
  57. package/src/services/coop-exit.ts +5 -1
  58. package/src/services/token-transactions.ts +8 -8
  59. package/src/spark-wallet/spark-wallet.browser.ts +0 -1
  60. package/src/spark-wallet/spark-wallet.react-native.ts +5 -3
  61. package/src/spark-wallet/spark-wallet.ts +56 -9
  62. package/src/tests/integration/coop-exit.test.ts +2 -0
  63. package/src/tests/integration/lightning.test.ts +5 -1
  64. package/src/tests/integration/ssp/coop-exit-validation.test.ts +5 -6
  65. package/src/tests/integration/ssp/static_deposit.test.ts +45 -35
  66. package/src/tests/optimize.test.ts +45 -0
  67. package/src/tests/token-outputs.test.ts +60 -1
  68. package/src/tests/utils/test-faucet.ts +12 -8
  69. package/src/utils/optimize.ts +226 -0
  70. package/src/native/index.ts +0 -21
package/dist/debug.cjs CHANGED
@@ -1044,12 +1044,12 @@ var init_spark_bindings = __esm({
1044
1044
  });
1045
1045
 
1046
1046
  // src/utils/logging.ts
1047
- var import_core11, LOGGER_NAMES, SparkSdkLogger;
1047
+ var import_core12, LOGGER_NAMES, SparkSdkLogger;
1048
1048
  var init_logging = __esm({
1049
1049
  "src/utils/logging.ts"() {
1050
1050
  "use strict";
1051
1051
  init_buffer();
1052
- import_core11 = require("@lightsparkdev/core");
1052
+ import_core12 = require("@lightsparkdev/core");
1053
1053
  LOGGER_NAMES = {
1054
1054
  wasm: "wasm"
1055
1055
  };
@@ -1057,7 +1057,7 @@ var init_logging = __esm({
1057
1057
  static loggers = /* @__PURE__ */ new Map();
1058
1058
  static get(name) {
1059
1059
  if (!this.loggers.has(name)) {
1060
- this.loggers.set(name, new import_core11.Logger(name));
1060
+ this.loggers.set(name, new import_core12.Logger(name));
1061
1061
  }
1062
1062
  return this.loggers.get(name);
1063
1063
  }
@@ -1111,30 +1111,30 @@ function signFrost({
1111
1111
  adaptorPubKey
1112
1112
  }) {
1113
1113
  const logMsg = JSON.stringify({
1114
- message: (0, import_utils4.bytesToHex)(message),
1114
+ message: (0, import_utils17.bytesToHex)(message),
1115
1115
  keyPackage: {
1116
- secretKey: (0, import_utils4.bytesToHex)(keyPackage.secretKey),
1117
- publicKey: (0, import_utils4.bytesToHex)(keyPackage.publicKey),
1118
- verifyingKey: (0, import_utils4.bytesToHex)(keyPackage.verifyingKey)
1116
+ secretKey: (0, import_utils17.bytesToHex)(keyPackage.secretKey),
1117
+ publicKey: (0, import_utils17.bytesToHex)(keyPackage.publicKey),
1118
+ verifyingKey: (0, import_utils17.bytesToHex)(keyPackage.verifyingKey)
1119
1119
  },
1120
1120
  nonce: {
1121
- hiding: (0, import_utils4.bytesToHex)(nonce.hiding),
1122
- binding: (0, import_utils4.bytesToHex)(nonce.binding)
1121
+ hiding: (0, import_utils17.bytesToHex)(nonce.hiding),
1122
+ binding: (0, import_utils17.bytesToHex)(nonce.binding)
1123
1123
  },
1124
1124
  selfCommitment: {
1125
- hiding: (0, import_utils4.bytesToHex)(selfCommitment.hiding),
1126
- binding: (0, import_utils4.bytesToHex)(selfCommitment.binding)
1125
+ hiding: (0, import_utils17.bytesToHex)(selfCommitment.hiding),
1126
+ binding: (0, import_utils17.bytesToHex)(selfCommitment.binding)
1127
1127
  },
1128
1128
  statechainCommitments: Object.fromEntries(
1129
1129
  Object.entries(statechainCommitments ?? {}).map(([k, v]) => [
1130
1130
  k,
1131
1131
  {
1132
- hiding: (0, import_utils4.bytesToHex)(v.hiding),
1133
- binding: (0, import_utils4.bytesToHex)(v.binding)
1132
+ hiding: (0, import_utils17.bytesToHex)(v.hiding),
1133
+ binding: (0, import_utils17.bytesToHex)(v.binding)
1134
1134
  }
1135
1135
  ])
1136
1136
  ),
1137
- adaptorPubKey: adaptorPubKey ? (0, import_utils4.bytesToHex)(adaptorPubKey) : void 0
1137
+ adaptorPubKey: adaptorPubKey ? (0, import_utils17.bytesToHex)(adaptorPubKey) : void 0
1138
1138
  });
1139
1139
  SparkSdkLogger.get(LOGGER_NAMES.wasm).trace("signFrost", logMsg);
1140
1140
  const result = wasm_sign_frost(
@@ -1147,7 +1147,7 @@ function signFrost({
1147
1147
  );
1148
1148
  SparkSdkLogger.get(LOGGER_NAMES.wasm).trace(
1149
1149
  "signFrost result",
1150
- (0, import_utils4.bytesToHex)(result)
1150
+ (0, import_utils17.bytesToHex)(result)
1151
1151
  );
1152
1152
  return result;
1153
1153
  }
@@ -1163,36 +1163,36 @@ function aggregateFrost({
1163
1163
  adaptorPubKey
1164
1164
  }) {
1165
1165
  const logMsg = JSON.stringify({
1166
- message: (0, import_utils4.bytesToHex)(message),
1166
+ message: (0, import_utils17.bytesToHex)(message),
1167
1167
  statechainCommitments: Object.fromEntries(
1168
1168
  Object.entries(statechainCommitments ?? {}).map(([k, v]) => [
1169
1169
  k,
1170
1170
  {
1171
- hiding: (0, import_utils4.bytesToHex)(v.hiding),
1172
- binding: (0, import_utils4.bytesToHex)(v.binding)
1171
+ hiding: (0, import_utils17.bytesToHex)(v.hiding),
1172
+ binding: (0, import_utils17.bytesToHex)(v.binding)
1173
1173
  }
1174
1174
  ])
1175
1175
  ),
1176
1176
  selfCommitment: {
1177
- hiding: (0, import_utils4.bytesToHex)(selfCommitment.hiding),
1178
- binding: (0, import_utils4.bytesToHex)(selfCommitment.binding)
1177
+ hiding: (0, import_utils17.bytesToHex)(selfCommitment.hiding),
1178
+ binding: (0, import_utils17.bytesToHex)(selfCommitment.binding)
1179
1179
  },
1180
1180
  statechainSignatures: Object.fromEntries(
1181
1181
  Object.entries(statechainSignatures ?? {}).map(([k, v]) => [
1182
1182
  k,
1183
- (0, import_utils4.bytesToHex)(v)
1183
+ (0, import_utils17.bytesToHex)(v)
1184
1184
  ])
1185
1185
  ),
1186
- selfSignature: (0, import_utils4.bytesToHex)(selfSignature),
1186
+ selfSignature: (0, import_utils17.bytesToHex)(selfSignature),
1187
1187
  statechainPublicKeys: Object.fromEntries(
1188
1188
  Object.entries(statechainPublicKeys ?? {}).map(([k, v]) => [
1189
1189
  k,
1190
- (0, import_utils4.bytesToHex)(v)
1190
+ (0, import_utils17.bytesToHex)(v)
1191
1191
  ])
1192
1192
  ),
1193
- selfPublicKey: (0, import_utils4.bytesToHex)(selfPublicKey),
1194
- verifyingKey: (0, import_utils4.bytesToHex)(verifyingKey),
1195
- adaptorPubKey: adaptorPubKey ? (0, import_utils4.bytesToHex)(adaptorPubKey) : void 0
1193
+ selfPublicKey: (0, import_utils17.bytesToHex)(selfPublicKey),
1194
+ verifyingKey: (0, import_utils17.bytesToHex)(verifyingKey),
1195
+ adaptorPubKey: adaptorPubKey ? (0, import_utils17.bytesToHex)(adaptorPubKey) : void 0
1196
1196
  });
1197
1197
  SparkSdkLogger.get(LOGGER_NAMES.wasm).trace("aggregateFrost", logMsg);
1198
1198
  const result = wasm_aggregate_frost(
@@ -1208,7 +1208,7 @@ function aggregateFrost({
1208
1208
  );
1209
1209
  SparkSdkLogger.get(LOGGER_NAMES.wasm).trace(
1210
1210
  "aggregateFrost result",
1211
- (0, import_utils4.bytesToHex)(result)
1211
+ (0, import_utils17.bytesToHex)(result)
1212
1212
  );
1213
1213
  return result;
1214
1214
  }
@@ -1230,12 +1230,12 @@ function decryptEcies({
1230
1230
  }) {
1231
1231
  return decrypt_ecies(encryptedMsg, privateKey);
1232
1232
  }
1233
- var import_utils4;
1233
+ var import_utils17;
1234
1234
  var init_wasm = __esm({
1235
1235
  "src/spark_bindings/wasm/index.ts"() {
1236
1236
  "use strict";
1237
1237
  init_buffer();
1238
- import_utils4 = require("@noble/curves/utils");
1238
+ import_utils17 = require("@noble/curves/utils");
1239
1239
  init_spark_bindings();
1240
1240
  init_logging();
1241
1241
  }
@@ -1382,6 +1382,28 @@ var import_sha2 = require("@noble/hashes/sha2");
1382
1382
  // src/errors/index.ts
1383
1383
  init_buffer();
1384
1384
 
1385
+ // src/utils/fetch.ts
1386
+ init_buffer();
1387
+ var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch.bind(globalThis) : null;
1388
+ var Headers = globalThis.Headers ?? null;
1389
+ var getFetch = () => {
1390
+ if (!fetchImpl) {
1391
+ throw new Error(
1392
+ "Fetch implementation is not set. Please set it using setFetch()."
1393
+ );
1394
+ }
1395
+ if (!Headers) {
1396
+ throw new Error(
1397
+ "Headers implementation is not set. Please set it using setFetch()."
1398
+ );
1399
+ }
1400
+ const val = {
1401
+ fetch: fetchImpl,
1402
+ Headers
1403
+ };
1404
+ return val;
1405
+ };
1406
+
1385
1407
  // src/graphql/mutations/ClaimStaticDeposit.ts
1386
1408
  init_buffer();
1387
1409
 
@@ -1747,7 +1769,7 @@ fragment CoopExitRequestFragment on CoopExitRequest {
1747
1769
  var CompleteCoopExit = `
1748
1770
  mutation CompleteCoopExit(
1749
1771
  $user_outbound_transfer_external_id: UUID!
1750
- $coop_exit_request_id: ID!
1772
+ $coop_exit_request_id: ID
1751
1773
  ) {
1752
1774
  complete_coop_exit(input: {
1753
1775
  user_outbound_transfer_external_id: $user_outbound_transfer_external_id
@@ -1962,11 +1984,12 @@ var RequestCoopExit = `
1962
1984
  mutation RequestCoopExit(
1963
1985
  $leaf_external_ids: [UUID!]!
1964
1986
  $withdrawal_address: String!
1965
- $idempotency_key: String!
1987
+ $idempotency_key: String
1966
1988
  $exit_speed: ExitSpeed!
1967
1989
  $withdraw_all: Boolean
1968
1990
  $fee_leaf_external_ids: [UUID!]
1969
1991
  $fee_quote_id: ID
1992
+ $user_outbound_transfer_external_id: UUID
1970
1993
  ) {
1971
1994
  request_coop_exit(
1972
1995
  input: {
@@ -1977,6 +2000,7 @@ var RequestCoopExit = `
1977
2000
  withdraw_all: $withdraw_all
1978
2001
  fee_leaf_external_ids: $fee_leaf_external_ids
1979
2002
  fee_quote_id: $fee_quote_id
2003
+ user_outbound_transfer_external_id: $user_outbound_transfer_external_id
1980
2004
  }
1981
2005
  ) {
1982
2006
  request {
@@ -2195,13 +2219,15 @@ fragment LightningSendRequestFragment on LightningSendRequest {
2195
2219
  var RequestLightningSend = `
2196
2220
  mutation RequestLightningSend(
2197
2221
  $encoded_invoice: String!
2198
- $idempotency_key: String!
2222
+ $idempotency_key: String
2199
2223
  $amount_sats: Long
2224
+ $user_outbound_transfer_external_id: UUID
2200
2225
  ) {
2201
2226
  request_lightning_send(input: {
2202
2227
  encoded_invoice: $encoded_invoice
2203
2228
  idempotency_key: $idempotency_key
2204
2229
  amount_sats: $amount_sats
2230
+ user_outbound_transfer_external_id: $user_outbound_transfer_external_id
2205
2231
  }) {
2206
2232
  request {
2207
2233
  ...LightningSendRequestFragment
@@ -2934,28 +2960,6 @@ var UserRequest2 = `
2934
2960
  ${FRAGMENT14}
2935
2961
  `;
2936
2962
 
2937
- // src/utils/fetch.ts
2938
- init_buffer();
2939
- var fetchImpl = typeof window !== "undefined" && window.fetch ? window.fetch.bind(window) : globalThis.fetch ? globalThis.fetch.bind(globalThis) : null;
2940
- var Headers = globalThis.Headers ?? null;
2941
- var getFetch = () => {
2942
- if (!fetchImpl) {
2943
- throw new Error(
2944
- "Fetch implementation is not set. Please set it using setFetch()."
2945
- );
2946
- }
2947
- if (!Headers) {
2948
- throw new Error(
2949
- "Headers implementation is not set. Please set it using setFetch()."
2950
- );
2951
- }
2952
- const val = {
2953
- fetch: fetchImpl,
2954
- Headers
2955
- };
2956
- return val;
2957
- };
2958
-
2959
2963
  // src/graphql/client.ts
2960
2964
  var SspClient = class {
2961
2965
  requester;
@@ -3058,14 +3062,12 @@ var SspClient = class {
3058
3062
  throw new Error("Not implemented");
3059
3063
  }
3060
3064
  async completeCoopExit({
3061
- userOutboundTransferExternalId,
3062
- coopExitRequestId
3065
+ userOutboundTransferExternalId
3063
3066
  }) {
3064
3067
  return await this.executeRawQuery({
3065
3068
  queryPayload: CompleteCoopExit,
3066
3069
  variables: {
3067
- user_outbound_transfer_external_id: userOutboundTransferExternalId,
3068
- coop_exit_request_id: coopExitRequestId
3070
+ user_outbound_transfer_external_id: userOutboundTransferExternalId
3069
3071
  },
3070
3072
  constructObject: (response) => {
3071
3073
  return CoopExitRequestFromJson(response.complete_coop_exit.request);
@@ -3075,29 +3077,28 @@ var SspClient = class {
3075
3077
  async requestCoopExit({
3076
3078
  leafExternalIds,
3077
3079
  withdrawalAddress,
3078
- idempotencyKey,
3079
3080
  exitSpeed,
3080
3081
  feeLeafExternalIds,
3081
3082
  feeQuoteId,
3082
- withdrawAll
3083
+ withdrawAll,
3084
+ userOutboundTransferExternalId
3083
3085
  }) {
3084
3086
  return await this.executeRawQuery({
3085
3087
  queryPayload: RequestCoopExit,
3086
3088
  variables: {
3087
3089
  leaf_external_ids: leafExternalIds,
3088
3090
  withdrawal_address: withdrawalAddress,
3089
- idempotency_key: idempotencyKey,
3090
3091
  exit_speed: exitSpeed,
3091
3092
  fee_leaf_external_ids: feeLeafExternalIds,
3092
3093
  fee_quote_id: feeQuoteId,
3093
- withdraw_all: withdrawAll
3094
+ withdraw_all: withdrawAll,
3095
+ user_outbound_transfer_external_id: userOutboundTransferExternalId
3094
3096
  },
3095
3097
  constructObject: (response) => {
3096
3098
  return CoopExitRequestFromJson(response.request_coop_exit.request);
3097
3099
  }
3098
3100
  });
3099
3101
  }
3100
- // TODO: Lets name this better
3101
3102
  async requestLightningReceive({
3102
3103
  amountSats,
3103
3104
  network,
@@ -3129,15 +3130,15 @@ var SspClient = class {
3129
3130
  }
3130
3131
  async requestLightningSend({
3131
3132
  encodedInvoice,
3132
- idempotencyKey,
3133
- amountSats
3133
+ amountSats,
3134
+ userOutboundTransferExternalId
3134
3135
  }) {
3135
3136
  return await this.executeRawQuery({
3136
3137
  queryPayload: RequestLightningSend,
3137
3138
  variables: {
3138
3139
  encoded_invoice: encodedInvoice,
3139
- idempotency_key: idempotencyKey,
3140
- amount_sats: amountSats
3140
+ amount_sats: amountSats,
3141
+ user_outbound_transfer_external_id: userOutboundTransferExternalId
3141
3142
  },
3142
3143
  constructObject: (response) => {
3143
3144
  return LightningSendRequestFromJson(
@@ -19085,1247 +19086,426 @@ function isSet3(value) {
19085
19086
  // src/services/config.ts
19086
19087
  init_buffer();
19087
19088
 
19088
- // src/signer/signer.ts
19089
- init_buffer();
19090
- var import_secp256k14 = require("@bitcoinerlab/secp256k1");
19091
- var import_secp256k15 = require("@noble/curves/secp256k1");
19092
- var import_utils5 = require("@noble/curves/utils");
19093
- var import_sha22 = require("@noble/hashes/sha2");
19094
- var import_bip32 = require("@scure/bip32");
19095
- var import_bip39 = require("@scure/bip39");
19096
- var import_english = require("@scure/bip39/wordlists/english");
19097
- var import_utils6 = require("@scure/btc-signer/utils");
19098
- var ecies = __toESM(require("eciesjs"), 1);
19099
-
19100
- // src/constants.ts
19101
- init_buffer();
19102
- var import_core10 = require("@lightsparkdev/core");
19103
- var isReactNative = "navigator" in globalThis && navigator.product === "ReactNative";
19104
- var isBun = "Bun" in globalThis;
19105
- var isWebExtension = (
19106
- /* globalThis.chrome actually exists in extension contexts for all browsers for legacy reasons: */
19107
- "chrome" in globalThis && globalThis.chrome.runtime?.id
19108
- );
19109
- var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
19110
- var packageVersion = true ? "0.3.6" : "unknown";
19111
- var baseEnvStr = "unknown";
19112
- if (isBun) {
19113
- const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
19114
- baseEnvStr = `bun/${bunVersion}`;
19115
- } else if (import_core10.isNode) {
19116
- baseEnvStr = `node/${globalThis.process.version}`;
19117
- } else if (isReactNative) {
19118
- baseEnvStr = "react-native";
19119
- } else if (import_core10.isBare) {
19120
- const bareVersion = Bare.version;
19121
- baseEnvStr = `bare/${bareVersion}`;
19122
- } else if (isWebExtension) {
19123
- const protocol = "location" in globalThis ? globalThis.location.protocol : "";
19124
- const extScriptType = "window" in globalThis ? "content-script" : "background-script";
19125
- baseEnvStr = `web-extension/${protocol.replace(":", "")}/${extScriptType}/${userAgent}`;
19126
- } else {
19127
- baseEnvStr = `browser/${userAgent}`;
19128
- }
19129
- var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
19130
-
19131
- // src/utils/keys.ts
19089
+ // src/utils/network.ts
19132
19090
  init_buffer();
19133
- var import_secp256k1 = require("@noble/curves/secp256k1");
19134
- var import_utils2 = require("@noble/curves/utils");
19135
- function addPublicKeys(a, b) {
19136
- if (a.length !== 33 || b.length !== 33) {
19137
- throw new ValidationError("Public keys must be 33 bytes", {
19138
- field: "publicKeys",
19139
- value: `a: ${a.length}, b: ${b.length}`,
19140
- expected: 33
19141
- });
19142
- }
19143
- const pubkeyA = import_secp256k1.secp256k1.Point.fromHex(a);
19144
- const pubkeyB = import_secp256k1.secp256k1.Point.fromHex(b);
19145
- return pubkeyA.add(pubkeyB).toBytes(true);
19146
- }
19147
- function applyAdditiveTweakToPublicKey(pubkey, tweak) {
19148
- if (pubkey.length !== 33) {
19149
- throw new ValidationError("Public key must be 33 bytes", {
19150
- field: "pubkey",
19151
- value: pubkey.length,
19152
- expected: 33
19153
- });
19154
- }
19155
- if (tweak.length !== 32) {
19156
- throw new ValidationError("Tweak must be 32 bytes", {
19157
- field: "tweak",
19158
- value: tweak.length,
19159
- expected: 32
19160
- });
19161
- }
19162
- const pubkeyPoint = import_secp256k1.secp256k1.Point.fromHex(pubkey);
19163
- const privTweek = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(tweak);
19164
- const pubTweek = import_secp256k1.secp256k1.getPublicKey(privTweek, true);
19165
- const tweekPoint = import_secp256k1.secp256k1.Point.fromHex(pubTweek);
19166
- return pubkeyPoint.add(tweekPoint).toBytes(true);
19167
- }
19168
- function subtractPublicKeys(a, b) {
19169
- if (a.length !== 33 || b.length !== 33) {
19170
- throw new ValidationError("Public keys must be 33 bytes", {
19171
- field: "publicKeys",
19172
- value: `a: ${a.length}, b: ${b.length}`,
19173
- expected: 33
19174
- });
19175
- }
19176
- const pubkeyA = import_secp256k1.secp256k1.Point.fromHex(a);
19177
- const pubkeyB = import_secp256k1.secp256k1.Point.fromHex(b);
19178
- return pubkeyA.subtract(pubkeyB).toBytes(true);
19179
- }
19180
- function addPrivateKeys(a, b) {
19181
- if (a.length !== 32 || b.length !== 32) {
19182
- throw new ValidationError("Private keys must be 32 bytes", {
19183
- field: "privateKeys",
19184
- value: `a: ${a.length}, b: ${b.length}`,
19185
- expected: 32
19186
- });
19187
- }
19188
- const privA = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(a);
19189
- const privB = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(b);
19190
- const sum = (privA + privB) % import_secp256k1.secp256k1.CURVE.n;
19191
- return (0, import_utils2.numberToBytesBE)(sum, 32);
19192
- }
19193
- function subtractPrivateKeys(a, b) {
19194
- if (a.length !== 32 || b.length !== 32) {
19195
- throw new ValidationError("Private keys must be 32 bytes", {
19196
- field: "privateKeys",
19197
- value: `a: ${a.length}, b: ${b.length}`,
19198
- expected: 32
19199
- });
19091
+ var btc = __toESM(require("@scure/btc-signer"), 1);
19092
+ var import_base2 = require("@scure/base");
19093
+ var Network2 = /* @__PURE__ */ ((Network5) => {
19094
+ Network5[Network5["MAINNET"] = 0] = "MAINNET";
19095
+ Network5[Network5["TESTNET"] = 1] = "TESTNET";
19096
+ Network5[Network5["SIGNET"] = 2] = "SIGNET";
19097
+ Network5[Network5["REGTEST"] = 3] = "REGTEST";
19098
+ Network5[Network5["LOCAL"] = 4] = "LOCAL";
19099
+ return Network5;
19100
+ })(Network2 || {});
19101
+ var NetworkToProto = {
19102
+ [0 /* MAINNET */]: 1 /* MAINNET */,
19103
+ [1 /* TESTNET */]: 3 /* TESTNET */,
19104
+ [2 /* SIGNET */]: 4 /* SIGNET */,
19105
+ [3 /* REGTEST */]: 2 /* REGTEST */,
19106
+ [4 /* LOCAL */]: 2 /* REGTEST */
19107
+ };
19108
+ var protoToNetwork = (protoNetwork) => {
19109
+ switch (protoNetwork) {
19110
+ case 1 /* MAINNET */:
19111
+ return 0 /* MAINNET */;
19112
+ case 3 /* TESTNET */:
19113
+ return 1 /* TESTNET */;
19114
+ case 4 /* SIGNET */:
19115
+ return 2 /* SIGNET */;
19116
+ case 2 /* REGTEST */:
19117
+ return 3 /* REGTEST */;
19118
+ default:
19119
+ return void 0;
19200
19120
  }
19201
- const privA = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(a);
19202
- const privB = import_secp256k1.secp256k1.utils.normPrivateKeyToScalar(b);
19203
- const sum = (import_secp256k1.secp256k1.CURVE.n - privB + privA) % import_secp256k1.secp256k1.CURVE.n;
19204
- return (0, import_utils2.numberToBytesBE)(sum, 32);
19205
- }
19206
- function sumOfPrivateKeys(keys) {
19207
- return keys.reduce((sum, key) => {
19208
- if (key.length !== 32) {
19209
- throw new ValidationError("Private keys must be 32 bytes", {
19210
- field: "privateKey",
19211
- value: key.length,
19212
- expected: 32
19213
- });
19121
+ };
19122
+ var NetworkConfig = {
19123
+ [0 /* MAINNET */]: btc.NETWORK,
19124
+ [1 /* TESTNET */]: btc.TEST_NETWORK,
19125
+ [2 /* SIGNET */]: btc.TEST_NETWORK,
19126
+ [3 /* REGTEST */]: { ...btc.TEST_NETWORK, bech32: "bcrt" },
19127
+ [4 /* LOCAL */]: { ...btc.TEST_NETWORK, bech32: "bcrt" }
19128
+ };
19129
+ var getNetwork = (network) => NetworkConfig[network];
19130
+ function getNetworkFromAddress(address) {
19131
+ try {
19132
+ const bechAddress = address;
19133
+ const decoded = (() => {
19134
+ try {
19135
+ return import_base2.bech32.decode(bechAddress);
19136
+ } catch (_) {
19137
+ return import_base2.bech32m.decode(bechAddress);
19138
+ }
19139
+ })();
19140
+ if (decoded.prefix === "bc") {
19141
+ return "MAINNET" /* MAINNET */;
19142
+ } else if (decoded.prefix === "bcrt") {
19143
+ return "REGTEST" /* REGTEST */;
19214
19144
  }
19215
- return addPrivateKeys(sum, key);
19216
- });
19217
- }
19218
- function lastKeyWithTarget(target, keys) {
19219
- if (target.length !== 32) {
19220
- throw new ValidationError("Target must be 32 bytes", {
19221
- field: "target",
19222
- value: target.length,
19223
- expected: 32
19224
- });
19145
+ } catch (err) {
19146
+ throw new ValidationError(
19147
+ "Invalid Bitcoin address",
19148
+ {
19149
+ field: "address",
19150
+ value: address,
19151
+ expected: "Valid Bech32 address with prefix 'bc' or 'bcrt'"
19152
+ },
19153
+ err instanceof Error ? err : void 0
19154
+ );
19225
19155
  }
19226
- const sum = sumOfPrivateKeys(keys);
19227
- return subtractPrivateKeys(target, sum);
19156
+ return null;
19157
+ }
19158
+ function getNetworkFromString(network) {
19159
+ const net = (network ?? "REGTEST").toUpperCase();
19160
+ if (net === "MAINNET") return 0 /* MAINNET */;
19161
+ if (net === "TESTNET") return 1 /* TESTNET */;
19162
+ if (net === "SIGNET") return 2 /* SIGNET */;
19163
+ if (net === "LOCAL") return 4 /* LOCAL */;
19164
+ return 3 /* REGTEST */;
19228
19165
  }
19229
19166
 
19230
- // src/utils/secret-sharing.ts
19167
+ // src/services/wallet-config.ts
19231
19168
  init_buffer();
19232
- var import_secp256k12 = require("@noble/curves/secp256k1");
19233
- var import_utils3 = require("@noble/curves/utils");
19234
19169
 
19235
- // src/utils/crypto.ts
19170
+ // src/tests/isHermeticTest.ts
19236
19171
  init_buffer();
19237
- var cryptoImpl = globalThis.crypto ?? null;
19238
- var getCrypto = () => {
19239
- if (!cryptoImpl) {
19240
- throw new Error(
19241
- "Crypto implementation is not set. Please set it using setCrypto()."
19242
- );
19172
+ var isHermeticTest = Boolean(
19173
+ typeof process !== "undefined" && process?.env?.HERMETIC_TEST === "true"
19174
+ );
19175
+
19176
+ // src/services/wallet-config.ts
19177
+ var SSP_IDENTITY_PUBLIC_KEYS = {
19178
+ LOCAL: "028c094a432d46a0ac95349d792c2e3730bd60c29188db716f56a99e39b95338b4",
19179
+ REGTEST: {
19180
+ PROD: "022bf283544b16c0622daecb79422007d167eca6ce9f0c98c0c49833b1f7170bfe"
19181
+ },
19182
+ MAINNET: {
19183
+ PROD: "023e33e2920326f64ea31058d44777442d97d7d5cbfcf54e3060bc1695e5261c93"
19243
19184
  }
19244
- return cryptoImpl;
19245
19185
  };
19246
-
19247
- // src/utils/secret-sharing.ts
19248
- function getRandomBigInt(max) {
19249
- const byteLength = max.toString(2).length + 7 >> 3;
19250
- const maxBigInt = max;
19251
- const mask = (1n << BigInt(max.toString(2).length)) - 1n;
19252
- while (true) {
19253
- const crypto = getCrypto();
19254
- const randBytes = crypto.getRandomValues(new Uint8Array(byteLength + 1));
19255
- const randValue = BigInt("0x" + (0, import_utils3.bytesToHex)(randBytes)) & mask;
19256
- if (randValue < maxBigInt) {
19257
- return randValue;
19186
+ var URL_CONFIG = {
19187
+ LOCAL: {
19188
+ SSP: "http://127.0.0.1:5000",
19189
+ ELECTRS: "http://127.0.0.1:30000"
19190
+ },
19191
+ REGTEST: {
19192
+ PROD: {
19193
+ SSP: "https://api.lightspark.com",
19194
+ ELECTRS: "https://regtest-mempool.us-west-2.sparkinfra.net/api"
19195
+ }
19196
+ },
19197
+ MAINNET: {
19198
+ PROD: {
19199
+ SSP: "https://api.lightspark.com",
19200
+ ELECTRS: "https://mempool.space/api"
19258
19201
  }
19259
19202
  }
19260
- }
19261
- function modInverse(a, m) {
19262
- a = (a % m + m) % m;
19263
- let [old_r, r] = [a, m];
19264
- let [old_s, s2] = [1n, 0n];
19265
- let [old_t, t] = [0n, 1n];
19266
- while (r !== 0n) {
19267
- const quotient = old_r / r;
19268
- [old_r, r] = [r, old_r - quotient * r];
19269
- [old_s, s2] = [s2, old_s - quotient * s2];
19270
- [old_t, t] = [t, old_t - quotient * t];
19203
+ };
19204
+ var ELECTRS_CREDENTIALS = {
19205
+ username: "spark-sdk",
19206
+ password: "mCMk1JqlBNtetUNy"
19207
+ };
19208
+ function getElectrsUrl(network) {
19209
+ switch (network) {
19210
+ case "LOCAL":
19211
+ return isHermeticTest ? "http://mempool.minikube.local/api" : URL_CONFIG.LOCAL.ELECTRS;
19212
+ case "REGTEST":
19213
+ return URL_CONFIG.REGTEST.PROD.ELECTRS;
19214
+ case "MAINNET":
19215
+ return URL_CONFIG.MAINNET.PROD.ELECTRS;
19216
+ default:
19217
+ return URL_CONFIG.LOCAL.ELECTRS;
19271
19218
  }
19272
- if (old_r !== 1n) {
19273
- throw new ValidationError("Modular inverse does not exist", {
19274
- field: "modInverse",
19275
- value: `a: ${a}, m: ${m}`,
19276
- expected: "a and m must be coprime"
19277
- });
19219
+ }
19220
+ function getSspIdentityPublicKey(network) {
19221
+ switch (network) {
19222
+ case "LOCAL":
19223
+ return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
19224
+ case "REGTEST":
19225
+ return SSP_IDENTITY_PUBLIC_KEYS.REGTEST.PROD;
19226
+ case "MAINNET":
19227
+ return SSP_IDENTITY_PUBLIC_KEYS.MAINNET.PROD;
19228
+ default:
19229
+ return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
19278
19230
  }
19279
- return (old_s % m + m) % m;
19280
19231
  }
19281
- function evaluatePolynomial(polynomial, x) {
19282
- let result = 0n;
19283
- for (let i = 0; i < polynomial.coefficients.length; i++) {
19284
- const coeff = polynomial.coefficients[i];
19285
- if (!coeff) {
19286
- throw new ValidationError("Coefficient is undefined", {
19287
- field: "coefficient",
19288
- value: "undefined",
19289
- expected: "A valid bigint coefficient"
19290
- });
19291
- }
19292
- const xPow = x ** BigInt(i) % polynomial.fieldModulus;
19293
- result = (result + xPow * coeff) % polynomial.fieldModulus;
19232
+ function getSspUrl(network) {
19233
+ switch (network) {
19234
+ case "LOCAL":
19235
+ return isHermeticTest ? "http://app.minikube.local" : URL_CONFIG.LOCAL.SSP;
19236
+ case "REGTEST":
19237
+ return URL_CONFIG.REGTEST.PROD.SSP;
19238
+ case "MAINNET":
19239
+ return URL_CONFIG.MAINNET.PROD.SSP;
19240
+ default:
19241
+ return URL_CONFIG.LOCAL.SSP;
19294
19242
  }
19295
- return result;
19296
19243
  }
19297
- function fieldDiv(numerator, denominator, fieldModulus) {
19298
- if (denominator === 0n) {
19299
- throw new ValidationError("Division by zero", {
19300
- field: "denominator",
19301
- value: "0",
19302
- expected: "Non-zero value"
19303
- });
19244
+ function getSspSchemaEndpoint(network) {
19245
+ switch (network) {
19246
+ case "LOCAL":
19247
+ return "graphql/spark/rc";
19304
19248
  }
19305
- const inverse = modInverse(denominator, fieldModulus);
19306
- return numerator * inverse % fieldModulus;
19249
+ return;
19307
19250
  }
19308
- function computerLagrangeCoefficients(index, points) {
19309
- let numerator = 1n;
19310
- let denominator = 1n;
19311
- let fieldModulus = points[0]?.fieldModulus;
19312
- if (!fieldModulus) {
19313
- throw new ValidationError("Field modulus is undefined", {
19314
- field: "fieldModulus",
19315
- value: "undefined",
19316
- expected: "A valid field modulus"
19317
- });
19251
+ var PROD_PUBKEYS = [
19252
+ "03dfbdff4b6332c220f8fa2ba8ed496c698ceada563fa01b67d9983bfc5c95e763",
19253
+ "03e625e9768651c9be268e287245cc33f96a68ce9141b0b4769205db027ee8ed77",
19254
+ "022eda13465a59205413086130a65dc0ed1b8f8e51937043161f8be0c369b1a410"
19255
+ ];
19256
+ function getLocalFrostSignerAddress() {
19257
+ return isHermeticTest ? "localhost:9999" : "unix:///tmp/frost_0.sock";
19258
+ }
19259
+ var BASE_CONFIG = {
19260
+ network: "LOCAL",
19261
+ coordinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
19262
+ frostSignerAddress: getLocalFrostSignerAddress(),
19263
+ threshold: 2,
19264
+ signingOperators: getLocalSigningOperators(),
19265
+ tokenSignatures: "SCHNORR",
19266
+ tokenValidityDurationSeconds: 180,
19267
+ electrsUrl: getElectrsUrl("LOCAL"),
19268
+ expectedWithdrawBondSats: 1e4,
19269
+ expectedWithdrawRelativeBlockLocktime: 1e3,
19270
+ sspClientOptions: {
19271
+ baseUrl: getSspUrl("LOCAL"),
19272
+ identityPublicKey: getSspIdentityPublicKey("LOCAL"),
19273
+ schemaEndpoint: getSspSchemaEndpoint("LOCAL")
19274
+ },
19275
+ signerWithPreExistingKeys: false,
19276
+ console: {
19277
+ otel: false
19318
19278
  }
19319
- for (const point of points) {
19320
- if (point.index === index) {
19321
- continue;
19322
- }
19323
- numerator = numerator * point.index;
19324
- const value = point.index - index;
19325
- denominator = denominator * value;
19279
+ };
19280
+ var LOCAL_WALLET_CONFIG = {
19281
+ ...BASE_CONFIG,
19282
+ threshold: 3
19283
+ };
19284
+ var LOCAL_WALLET_CONFIG_SCHNORR = {
19285
+ ...LOCAL_WALLET_CONFIG,
19286
+ threshold: 3
19287
+ // 3 for issuance tests.
19288
+ };
19289
+ var LOCAL_WALLET_CONFIG_ECDSA = {
19290
+ ...LOCAL_WALLET_CONFIG,
19291
+ tokenSignatures: "ECDSA",
19292
+ threshold: 3
19293
+ // 3 for issuance tests.
19294
+ };
19295
+ var REGTEST_WALLET_CONFIG = {
19296
+ ...BASE_CONFIG,
19297
+ network: "REGTEST",
19298
+ signingOperators: getSigningOperators(),
19299
+ electrsUrl: getElectrsUrl("REGTEST"),
19300
+ expectedWithdrawBondSats: 1e4,
19301
+ expectedWithdrawRelativeBlockLocktime: 1e3,
19302
+ sspClientOptions: {
19303
+ baseUrl: getSspUrl("REGTEST"),
19304
+ identityPublicKey: getSspIdentityPublicKey("REGTEST")
19326
19305
  }
19327
- return fieldDiv(numerator, denominator, fieldModulus);
19328
- }
19329
- function generatePolynomialForSecretSharing(fieldModulus, secret, degree) {
19330
- const coefficients = new Array(degree);
19331
- const proofs = new Array(degree);
19332
- coefficients[0] = secret;
19333
- proofs[0] = import_secp256k12.secp256k1.Point.fromPrivateKey(secret).toBytes(true);
19334
- for (let i = 1; i < degree; i++) {
19335
- const coefficient = getRandomBigInt(fieldModulus);
19336
- coefficients[i] = coefficient;
19337
- proofs[i] = import_secp256k12.secp256k1.Point.fromPrivateKey(coefficient).toBytes(true);
19306
+ };
19307
+ var MAINNET_WALLET_CONFIG = {
19308
+ ...BASE_CONFIG,
19309
+ network: "MAINNET",
19310
+ signingOperators: getSigningOperators(),
19311
+ electrsUrl: getElectrsUrl("MAINNET"),
19312
+ expectedWithdrawBondSats: 1e4,
19313
+ expectedWithdrawRelativeBlockLocktime: 1e3,
19314
+ sspClientOptions: {
19315
+ baseUrl: getSspUrl("MAINNET"),
19316
+ identityPublicKey: getSspIdentityPublicKey("MAINNET")
19338
19317
  }
19318
+ };
19319
+ var WalletConfig = {
19320
+ LOCAL: LOCAL_WALLET_CONFIG,
19321
+ LOCAL_SCHNORR: LOCAL_WALLET_CONFIG_SCHNORR,
19322
+ LOCAL_ECDSA: LOCAL_WALLET_CONFIG_ECDSA,
19323
+ REGTEST: REGTEST_WALLET_CONFIG,
19324
+ MAINNET: MAINNET_WALLET_CONFIG
19325
+ };
19326
+ function getSigningOperators() {
19339
19327
  return {
19340
- fieldModulus,
19341
- coefficients,
19342
- proofs
19328
+ "0000000000000000000000000000000000000000000000000000000000000001": {
19329
+ id: 0,
19330
+ identifier: "0000000000000000000000000000000000000000000000000000000000000001",
19331
+ address: "https://0.spark.lightspark.com",
19332
+ identityPublicKey: PROD_PUBKEYS[0]
19333
+ },
19334
+ "0000000000000000000000000000000000000000000000000000000000000002": {
19335
+ id: 1,
19336
+ identifier: "0000000000000000000000000000000000000000000000000000000000000002",
19337
+ address: "https://1.spark.lightspark.com",
19338
+ identityPublicKey: PROD_PUBKEYS[1]
19339
+ },
19340
+ "0000000000000000000000000000000000000000000000000000000000000003": {
19341
+ id: 2,
19342
+ identifier: "0000000000000000000000000000000000000000000000000000000000000003",
19343
+ address: "https://2.spark.flashnet.xyz",
19344
+ identityPublicKey: PROD_PUBKEYS[2]
19345
+ }
19343
19346
  };
19344
19347
  }
19345
- function splitSecret(fieldModulus, secret, threshold, numberOfShares) {
19346
- const polynomial = generatePolynomialForSecretSharing(
19347
- fieldModulus,
19348
- secret,
19349
- threshold
19348
+ function getLocalSigningOperators() {
19349
+ const addresses = Array.from(
19350
+ { length: 5 },
19351
+ (_, i) => isHermeticTest ? `https://${i}.spark.minikube.local` : `https://localhost:${i + 8535}`
19350
19352
  );
19351
- const shares = [];
19352
- for (let i = 1; i <= numberOfShares; i++) {
19353
- const share = evaluatePolynomial(polynomial, BigInt(i));
19354
- shares.push({
19355
- fieldModulus,
19356
- threshold,
19357
- index: BigInt(i),
19358
- share
19359
- });
19360
- }
19361
- return shares;
19362
- }
19363
- function splitSecretWithProofs(secret, fieldModulus, threshold, numberOfShares) {
19364
- const polynomial = generatePolynomialForSecretSharing(
19365
- fieldModulus,
19366
- secret,
19367
- threshold
19368
- );
19369
- const shares = [];
19370
- for (let i = 1; i <= numberOfShares; i++) {
19371
- const share = evaluatePolynomial(polynomial, BigInt(i));
19372
- shares.push({
19373
- fieldModulus,
19374
- threshold,
19375
- index: BigInt(i),
19376
- share,
19377
- proofs: polynomial.proofs
19378
- });
19379
- }
19380
- return shares;
19381
- }
19382
- function recoverSecret(shares) {
19383
- if (shares.length === 0) return 0n;
19384
- const threshold = shares[0]?.threshold;
19385
- const fieldModulus = shares[0]?.fieldModulus;
19386
- if (!threshold || !fieldModulus) {
19387
- throw new ValidationError("Shares are not valid", {
19388
- field: "shares",
19389
- value: "Missing threshold or fieldModulus",
19390
- expected: "Valid shares with threshold and fieldModulus"
19391
- });
19392
- }
19393
- if (shares.length < threshold) {
19394
- throw new ValidationError("Not enough shares to recover secret", {
19395
- field: "shares",
19396
- value: shares.length,
19397
- expected: `At least ${threshold} shares`
19398
- });
19399
- }
19400
- let result = 0n;
19401
- for (const share of shares) {
19402
- const coeff = computerLagrangeCoefficients(share.index, shares);
19403
- const item = share.share * coeff % fieldModulus;
19404
- result = (result + item) % fieldModulus;
19405
- }
19406
- return result;
19407
- }
19408
- function validateShare(share) {
19409
- const targetPubkey = import_secp256k12.secp256k1.Point.fromPrivateKey(share.share).toBytes(
19410
- true
19411
- );
19412
- let resultPubkey = share.proofs[0];
19413
- if (!resultPubkey) {
19414
- throw new ValidationError("Result pubkey is not valid", {
19415
- field: "resultPubkey",
19416
- value: "null",
19417
- expected: "Valid public key bytes"
19418
- });
19419
- }
19420
- for (let i = 1; i < share.proofs.length; i++) {
19421
- const pubkey = share.proofs[i];
19422
- if (!pubkey) {
19423
- throw new ValidationError("Pubkey is not valid", {
19424
- field: "pubkey",
19425
- value: "null",
19426
- expected: "Valid public key bytes"
19427
- });
19428
- }
19429
- const value = share.index ** BigInt(i) % share.fieldModulus;
19430
- const scaledPoint = import_secp256k12.secp256k1.Point.fromHex(pubkey).multiply(value);
19431
- resultPubkey = import_secp256k12.secp256k1.Point.fromHex(resultPubkey).add(scaledPoint).toBytes(true);
19432
- }
19433
- if (!(0, import_utils3.equalBytes)(resultPubkey, targetPubkey)) {
19434
- throw new ValidationError("Share is not valid", {
19435
- field: "share",
19436
- value: "Invalid proof",
19437
- expected: "Valid share with matching proofs"
19438
- });
19439
- }
19440
- }
19441
- function bigIntToPrivateKey(value) {
19442
- const hex = value.toString(16).padStart(64, "0");
19443
- const bytes2 = new Uint8Array(32);
19444
- for (let i = 0; i < 32; i++) {
19445
- bytes2[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
19446
- }
19447
- return bytes2;
19448
- }
19449
-
19450
- // src/utils/signing.ts
19451
- init_buffer();
19452
- var import_secp256k13 = require("@noble/curves/secp256k1");
19453
- function getRandomSigningNonce() {
19454
- const binding = import_secp256k13.secp256k1.utils.randomPrivateKey();
19455
- const hiding = import_secp256k13.secp256k1.utils.randomPrivateKey();
19456
- return createSigningNonce(binding, hiding);
19457
- }
19458
- function createSigningNonce(binding, hiding) {
19459
- if (binding.length !== 32 || hiding.length !== 32) {
19460
- throw new ValidationError("Invalid nonce length", {
19461
- field: "nonce",
19462
- value: `binding: ${binding.length}, hiding: ${hiding.length}`,
19463
- expected: "Both binding and hiding should be 32 bytes"
19464
- });
19465
- }
19466
- return {
19467
- binding,
19468
- hiding
19469
- };
19470
- }
19471
- function getSigningCommitmentFromNonce(nonce) {
19472
- const bindingPubKey = import_secp256k13.secp256k1.getPublicKey(nonce.binding, true);
19473
- const hidingPubKey = import_secp256k13.secp256k1.getPublicKey(nonce.hiding, true);
19474
- return {
19475
- binding: bindingPubKey,
19476
- hiding: hidingPubKey
19477
- };
19478
- }
19479
- function encodeSigningNonceToBytes(nonce) {
19480
- return new Uint8Array([...nonce.binding, ...nonce.hiding]);
19481
- }
19482
- function decodeBytesToSigningNonce(bytes2) {
19483
- if (bytes2.length !== 64) {
19484
- throw new ValidationError("Invalid nonce length", {
19485
- field: "bytes",
19486
- value: bytes2.length,
19487
- expected: "64 bytes (32 bytes for binding + 32 bytes for hiding)"
19488
- });
19489
- }
19490
- return {
19491
- binding: bytes2.slice(32, 64),
19492
- hiding: bytes2.slice(0, 32)
19493
- };
19494
- }
19495
- function createSigningCommitment(binding, hiding) {
19496
- if (binding.length !== 33 || hiding.length !== 33) {
19497
- throw new ValidationError("Invalid nonce commitment length", {
19498
- field: "commitment",
19499
- value: `binding: ${binding.length}, hiding: ${hiding.length}`,
19500
- expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
19501
- });
19502
- }
19503
- return {
19504
- binding,
19505
- hiding
19506
- };
19507
- }
19508
- function encodeSigningCommitmentToBytes(commitment) {
19509
- if (commitment.binding.length !== 33 || commitment.hiding.length !== 33) {
19510
- throw new ValidationError("Invalid nonce commitment length", {
19511
- field: "commitment",
19512
- value: `binding: ${commitment.binding.length}, hiding: ${commitment.hiding.length}`,
19513
- expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
19514
- });
19515
- }
19516
- return new Uint8Array([...commitment.binding, ...commitment.hiding]);
19517
- }
19518
- function decodeBytesToSigningCommitment(bytes2) {
19519
- if (bytes2.length !== 66) {
19520
- throw new ValidationError("Invalid nonce commitment length", {
19521
- field: "bytes",
19522
- value: bytes2.length,
19523
- expected: "66 bytes (33 bytes for binding + 33 bytes for hiding)"
19524
- });
19525
- }
19353
+ const pubkeys = [
19354
+ "0322ca18fc489ae25418a0e768273c2c61cabb823edfb14feb891e9bec62016510",
19355
+ "0341727a6c41b168f07eb50865ab8c397a53c7eef628ac1020956b705e43b6cb27",
19356
+ "0305ab8d485cc752394de4981f8a5ae004f2becfea6f432c9a59d5022d8764f0a6",
19357
+ "0352aef4d49439dedd798ac4aef1e7ebef95f569545b647a25338398c1247ffdea",
19358
+ "02c05c88cc8fc181b1ba30006df6a4b0597de6490e24514fbdd0266d2b9cd3d0ba"
19359
+ ];
19526
19360
  return {
19527
- binding: bytes2.slice(33, 66),
19528
- hiding: bytes2.slice(0, 33)
19361
+ "0000000000000000000000000000000000000000000000000000000000000001": {
19362
+ id: 0,
19363
+ identifier: "0000000000000000000000000000000000000000000000000000000000000001",
19364
+ address: addresses[0],
19365
+ identityPublicKey: pubkeys[0]
19366
+ },
19367
+ "0000000000000000000000000000000000000000000000000000000000000002": {
19368
+ id: 1,
19369
+ identifier: "0000000000000000000000000000000000000000000000000000000000000002",
19370
+ address: addresses[1],
19371
+ identityPublicKey: pubkeys[1]
19372
+ },
19373
+ "0000000000000000000000000000000000000000000000000000000000000003": {
19374
+ id: 2,
19375
+ identifier: "0000000000000000000000000000000000000000000000000000000000000003",
19376
+ address: addresses[2],
19377
+ identityPublicKey: pubkeys[2]
19378
+ },
19379
+ "0000000000000000000000000000000000000000000000000000000000000004": {
19380
+ id: 3,
19381
+ identifier: "0000000000000000000000000000000000000000000000000000000000000004",
19382
+ address: addresses[3],
19383
+ identityPublicKey: pubkeys[3]
19384
+ },
19385
+ "0000000000000000000000000000000000000000000000000000000000000005": {
19386
+ id: 4,
19387
+ identifier: "0000000000000000000000000000000000000000000000000000000000000005",
19388
+ address: addresses[4],
19389
+ identityPublicKey: pubkeys[4]
19390
+ }
19529
19391
  };
19530
19392
  }
19531
19393
 
19532
- // src/signer/types.ts
19533
- init_buffer();
19534
-
19535
- // src/signer/signer.ts
19536
- var sparkFrostModule = void 0;
19537
- var getSparkFrostModule = async () => {
19538
- if (isReactNative) {
19539
- return void 0;
19540
- }
19541
- if (!sparkFrostModule) {
19542
- sparkFrostModule = await Promise.resolve().then(() => (init_wasm(), wasm_exports));
19394
+ // src/services/config.ts
19395
+ var WalletConfigService = class {
19396
+ config;
19397
+ signer;
19398
+ sspClientOptions;
19399
+ constructor(options = {}, signer) {
19400
+ const network = options?.network ?? "REGTEST";
19401
+ this.config = {
19402
+ ...this.getDefaultConfig(Network2[network]),
19403
+ ...options
19404
+ };
19405
+ this.signer = signer;
19406
+ this.sspClientOptions = this.config.sspClientOptions;
19543
19407
  }
19544
- return sparkFrostModule;
19545
- };
19546
- var HARDENED_OFFSET = 2147483648;
19547
- var DefaultSparkKeysGenerator = class {
19548
- async deriveKeysFromSeed(seed, accountNumber) {
19549
- const hdkey = import_bip32.HDKey.fromMasterSeed(seed);
19550
- if (!hdkey.privateKey || !hdkey.publicKey) {
19551
- throw new ValidationError("Failed to derive keys from seed", {
19552
- field: "hdkey",
19553
- value: seed
19554
- });
19408
+ getDefaultConfig(network) {
19409
+ switch (network) {
19410
+ case 0 /* MAINNET */:
19411
+ return WalletConfig.MAINNET;
19412
+ case 3 /* REGTEST */:
19413
+ return WalletConfig.REGTEST;
19414
+ default:
19415
+ return WalletConfig.LOCAL;
19555
19416
  }
19556
- const identityKey = hdkey.derive(`m/8797555'/${accountNumber}'/0'`);
19557
- const signingKey = hdkey.derive(`m/8797555'/${accountNumber}'/1'`);
19558
- const depositKey = hdkey.derive(`m/8797555'/${accountNumber}'/2'`);
19559
- const staticDepositKey = hdkey.derive(`m/8797555'/${accountNumber}'/3'`);
19560
- if (!identityKey.privateKey || !depositKey.privateKey || !signingKey.privateKey || !identityKey.publicKey || !depositKey.publicKey || !signingKey.publicKey || !staticDepositKey.privateKey || !staticDepositKey.publicKey) {
19561
- throw new ValidationError(
19562
- "Failed to derive all required keys from seed",
19417
+ }
19418
+ getCoordinatorAddress() {
19419
+ const coordinator = this.config.signingOperators[this.config.coordinatorIdentifier];
19420
+ if (!coordinator) {
19421
+ throw new ConfigurationError(
19422
+ "Coordinator not found in signing operators",
19563
19423
  {
19564
- field: "derivedKeys"
19424
+ configKey: "signingOperators"
19565
19425
  }
19566
19426
  );
19567
19427
  }
19568
- return {
19569
- identityKey: {
19570
- privateKey: identityKey.privateKey,
19571
- publicKey: identityKey.publicKey
19572
- },
19573
- signingHDKey: {
19574
- hdKey: signingKey,
19575
- privateKey: signingKey.privateKey,
19576
- publicKey: signingKey.publicKey
19577
- },
19578
- depositKey: {
19579
- privateKey: depositKey.privateKey,
19580
- publicKey: depositKey.publicKey
19581
- },
19582
- staticDepositHDKey: {
19583
- hdKey: staticDepositKey,
19584
- privateKey: staticDepositKey.privateKey,
19585
- publicKey: staticDepositKey.publicKey
19586
- }
19587
- };
19428
+ return coordinator.address;
19588
19429
  }
19589
- };
19590
- var DefaultSparkSigner = class {
19591
- identityKey = null;
19592
- signingKey = null;
19593
- depositKey = null;
19594
- staticDepositKey = null;
19595
- commitmentToNonceMap = /* @__PURE__ */ new Map();
19596
- keysGenerator;
19597
- constructor({
19598
- sparkKeysGenerator
19599
- } = {}) {
19600
- this.keysGenerator = sparkKeysGenerator ?? new DefaultSparkKeysGenerator();
19430
+ getSigningOperators() {
19431
+ return this.config.signingOperators;
19601
19432
  }
19602
- deriveSigningKey(hash) {
19603
- if (!this.signingKey) {
19604
- throw new ValidationError("Private key not initialized", {
19605
- field: "signingKey"
19606
- });
19607
- }
19608
- const view = new DataView(hash.buffer);
19609
- const amount = view.getUint32(0, false) % HARDENED_OFFSET + HARDENED_OFFSET;
19610
- const newPrivateKey = this.signingKey?.deriveChild(amount).privateKey;
19611
- if (!newPrivateKey) {
19612
- throw new ValidationError("Failed to recover signing key", {
19613
- field: "privateKey"
19614
- });
19615
- }
19616
- return newPrivateKey;
19433
+ getThreshold() {
19434
+ return this.config.threshold;
19617
19435
  }
19618
- async decryptEciesToPrivateKey(ciphertext) {
19619
- if (!this.identityKey?.privateKey) {
19620
- throw new ConfigurationError("Identity key not initialized", {
19621
- configKey: "identityKey"
19622
- });
19623
- }
19624
- const receiverEciesPrivKey = ecies.PrivateKey.fromHex(
19625
- (0, import_utils5.bytesToHex)(this.identityKey.privateKey)
19626
- );
19627
- const privateKey = ecies.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
19628
- return privateKey;
19436
+ getCoordinatorIdentifier() {
19437
+ return this.config.coordinatorIdentifier;
19629
19438
  }
19630
- async getSigningPrivateKeyFromDerivation(keyDerivation) {
19631
- switch (keyDerivation.type) {
19632
- case "leaf" /* LEAF */:
19633
- return this.deriveSigningKey((0, import_sha22.sha256)(keyDerivation.path));
19634
- case "deposit" /* DEPOSIT */:
19635
- return this.depositKey?.privateKey ?? new Uint8Array();
19636
- case "static_deposit" /* STATIC_DEPOSIT */:
19637
- return this.getStaticDepositSecretKey(keyDerivation.path);
19638
- case "ecies" /* ECIES */:
19639
- return this.decryptEciesToPrivateKey(keyDerivation.path);
19640
- case "random" /* RANDOM */:
19641
- return import_secp256k15.secp256k1.utils.randomPrivateKey();
19642
- }
19439
+ getExpectedWithdrawBondSats() {
19440
+ return this.config.expectedWithdrawBondSats;
19643
19441
  }
19644
- async signSchnorrWithIdentityKey(message) {
19645
- if (!this.identityKey?.privateKey) {
19646
- throw new ValidationError("Private key not set", {
19647
- field: "identityKey"
19648
- });
19649
- }
19650
- const signature = import_secp256k15.schnorr.sign(message, this.identityKey.privateKey);
19651
- return signature;
19442
+ getExpectedWithdrawRelativeBlockLocktime() {
19443
+ return this.config.expectedWithdrawRelativeBlockLocktime;
19652
19444
  }
19653
- async getIdentityPublicKey() {
19654
- if (!this.identityKey?.publicKey) {
19655
- throw new ValidationError("Private key is not set", {
19656
- field: "identityKey"
19657
- });
19445
+ getSspNetwork() {
19446
+ if (this.config.network === "MAINNET") {
19447
+ return "MAINNET" /* MAINNET */;
19448
+ } else if (this.config.network === "REGTEST") {
19449
+ return "REGTEST" /* REGTEST */;
19450
+ } else if (this.config.network === "TESTNET") {
19451
+ return "TESTNET" /* TESTNET */;
19452
+ } else if (this.config.network === "SIGNET") {
19453
+ return "SIGNET" /* SIGNET */;
19658
19454
  }
19659
- return this.identityKey.publicKey;
19455
+ return "FUTURE_VALUE" /* FUTURE_VALUE */;
19660
19456
  }
19661
- async getDepositSigningKey() {
19662
- if (!this.depositKey?.publicKey) {
19663
- throw new ValidationError("Deposit key is not set", {
19664
- field: "depositKey"
19665
- });
19666
- }
19667
- return this.depositKey.publicKey;
19457
+ getNetwork() {
19458
+ return Network2[this.config.network];
19668
19459
  }
19669
- async getStaticDepositSigningKey(idx) {
19670
- const staticDepositKey = await this.getStaticDepositSecretKey(idx);
19671
- return import_secp256k15.secp256k1.getPublicKey(staticDepositKey);
19460
+ getNetworkType() {
19461
+ return this.config.network;
19672
19462
  }
19673
- async getStaticDepositSecretKey(idx) {
19674
- if (!this.staticDepositKey) {
19675
- throw new ValidationError("Static deposit key is not set", {
19676
- field: "staticDepositKey"
19677
- });
19678
- }
19679
- const staticDepositKey = this.staticDepositKey.deriveChild(
19680
- HARDENED_OFFSET + idx
19681
- );
19682
- if (!staticDepositKey?.privateKey) {
19683
- throw new ValidationError("Static deposit key is not set", {
19684
- field: "staticDepositKey"
19685
- });
19686
- }
19687
- return staticDepositKey.privateKey;
19463
+ getNetworkProto() {
19464
+ return NetworkToProto[Network2[this.config.network]];
19688
19465
  }
19689
- async generateMnemonic() {
19690
- return (0, import_bip39.generateMnemonic)(import_english.wordlist);
19466
+ getTokenSignatures() {
19467
+ return this.config.tokenSignatures;
19691
19468
  }
19692
- async mnemonicToSeed(mnemonic) {
19693
- return await (0, import_bip39.mnemonicToSeed)(mnemonic);
19469
+ getTokenValidityDurationSeconds() {
19470
+ return this.config.tokenValidityDurationSeconds;
19694
19471
  }
19695
- async getPublicKeyFromDerivation(keyDerivation) {
19696
- const privateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
19697
- return import_secp256k15.secp256k1.getPublicKey(privateKey);
19472
+ getElectrsUrl() {
19473
+ return this.config.electrsUrl;
19698
19474
  }
19699
- async subtractPrivateKeysGivenDerivationPaths(first, second) {
19700
- const firstPrivateKey = this.deriveSigningKey((0, import_sha22.sha256)(first));
19701
- const secondPrivateKey = this.deriveSigningKey((0, import_sha22.sha256)(second));
19702
- const resultPrivKey = subtractPrivateKeys(
19703
- firstPrivateKey,
19704
- secondPrivateKey
19705
- );
19706
- const resultPubKey = import_secp256k15.secp256k1.getPublicKey(resultPrivKey);
19707
- return resultPubKey;
19475
+ getSspBaseUrl() {
19476
+ return this.config.sspClientOptions.baseUrl;
19708
19477
  }
19709
- async subtractAndSplitSecretWithProofsGivenDerivations({
19710
- first,
19711
- second,
19712
- curveOrder,
19713
- threshold,
19714
- numShares
19715
- }) {
19716
- const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
19717
- const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
19718
- const resultPrivKey = subtractPrivateKeys(
19719
- firstPrivateKey,
19720
- secondPrivateKey
19721
- );
19722
- return await this.splitSecretWithProofs({
19723
- secret: resultPrivKey,
19724
- curveOrder,
19725
- threshold,
19726
- numShares
19727
- });
19478
+ getSspIdentityPublicKey() {
19479
+ return this.config.sspClientOptions.identityPublicKey;
19728
19480
  }
19729
- async subtractSplitAndEncrypt({
19730
- first,
19731
- second,
19732
- curveOrder,
19733
- threshold,
19734
- numShares,
19735
- receiverPublicKey
19736
- }) {
19737
- const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
19738
- const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
19739
- const resultPrivKey = subtractPrivateKeys(
19740
- firstPrivateKey,
19741
- secondPrivateKey
19742
- );
19481
+ getConsoleOptions() {
19743
19482
  return {
19744
- shares: await this.splitSecretWithProofs({
19745
- secret: resultPrivKey,
19746
- curveOrder,
19747
- threshold,
19748
- numShares
19749
- }),
19750
- secretCipher: ecies.encrypt(receiverPublicKey, secondPrivateKey)
19483
+ ...this.config.console
19751
19484
  };
19752
19485
  }
19753
- async splitSecretWithProofs({
19754
- secret,
19755
- curveOrder,
19756
- threshold,
19757
- numShares
19758
- }) {
19759
- const secretAsInt = (0, import_utils5.bytesToNumberBE)(secret);
19760
- return splitSecretWithProofs(secretAsInt, curveOrder, threshold, numShares);
19761
- }
19762
- async signFrost({
19763
- message,
19764
- keyDerivation,
19765
- publicKey,
19766
- verifyingKey,
19767
- selfCommitment,
19768
- statechainCommitments,
19769
- adaptorPubKey
19770
- }) {
19771
- const SparkFrost = await getSparkFrostModule();
19772
- if (!SparkFrost) {
19773
- throw new ValidationError("SparkFrost module not found", {
19774
- field: "SparkFrost"
19775
- });
19486
+ };
19487
+
19488
+ // src/services/connection/connection.ts
19489
+ init_buffer();
19490
+ var import_core10 = require("@lightsparkdev/core");
19491
+ var import_sha22 = require("@noble/hashes/sha2");
19492
+
19493
+ // src/proto/spark_authn.ts
19494
+ init_buffer();
19495
+ var import_wire5 = require("@bufbuild/protobuf/wire");
19496
+ function createBaseChallenge() {
19497
+ return { version: 0, timestamp: 0, nonce: new Uint8Array(0), publicKey: new Uint8Array(0) };
19498
+ }
19499
+ var Challenge = {
19500
+ encode(message, writer = new import_wire5.BinaryWriter()) {
19501
+ if (message.version !== 0) {
19502
+ writer.uint32(8).int32(message.version);
19776
19503
  }
19777
- const signingPrivateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
19778
- if (!signingPrivateKey) {
19779
- throw new ValidationError("Private key not found for public key", {
19780
- field: "privateKey"
19781
- });
19504
+ if (message.timestamp !== 0) {
19505
+ writer.uint32(16).int64(message.timestamp);
19782
19506
  }
19783
- const commitment = selfCommitment.commitment;
19784
- const nonce = this.commitmentToNonceMap.get(commitment);
19785
- if (!nonce) {
19786
- throw new ValidationError("Nonce not found for commitment", {
19787
- field: "nonce"
19788
- });
19789
- }
19790
- const keyPackage = {
19791
- secretKey: signingPrivateKey,
19792
- publicKey,
19793
- verifyingKey
19794
- };
19795
- const logMessage = (0, import_utils5.bytesToHex)(message);
19796
- const result = await SparkFrost.signFrost({
19797
- message,
19798
- keyPackage,
19799
- nonce,
19800
- selfCommitment: commitment,
19801
- statechainCommitments,
19802
- adaptorPubKey
19803
- });
19804
- return result;
19805
- }
19806
- async aggregateFrost({
19807
- message,
19808
- publicKey,
19809
- verifyingKey,
19810
- selfCommitment,
19811
- statechainCommitments,
19812
- adaptorPubKey,
19813
- selfSignature,
19814
- statechainSignatures,
19815
- statechainPublicKeys
19816
- }) {
19817
- const SparkFrost = await getSparkFrostModule();
19818
- if (!SparkFrost) {
19819
- throw new ValidationError("SparkFrost module not found", {
19820
- field: "SparkFrost"
19821
- });
19822
- }
19823
- return SparkFrost.aggregateFrost({
19824
- message,
19825
- statechainSignatures,
19826
- statechainPublicKeys,
19827
- verifyingKey,
19828
- statechainCommitments,
19829
- selfCommitment: selfCommitment.commitment,
19830
- selfPublicKey: publicKey,
19831
- selfSignature,
19832
- adaptorPubKey
19833
- });
19834
- }
19835
- async createSparkWalletFromSeed(seed, accountNumber) {
19836
- if (typeof seed === "string") {
19837
- seed = (0, import_utils5.hexToBytes)(seed);
19838
- }
19839
- const {
19840
- identityKey,
19841
- signingHDKey: signingKey,
19842
- depositKey,
19843
- staticDepositHDKey: staticDepositKey
19844
- } = await this.keysGenerator.deriveKeysFromSeed(seed, accountNumber ?? 0);
19845
- this.identityKey = identityKey;
19846
- this.depositKey = depositKey;
19847
- this.signingKey = signingKey.hdKey;
19848
- this.staticDepositKey = staticDepositKey.hdKey;
19849
- return (0, import_utils5.bytesToHex)(identityKey.publicKey);
19850
- }
19851
- async signMessageWithIdentityKey(message, compact) {
19852
- if (!this.identityKey?.privateKey) {
19853
- throw new ConfigurationError("Identity key not initialized", {
19854
- configKey: "identityKey"
19855
- });
19856
- }
19857
- const signature = import_secp256k15.secp256k1.sign(message, this.identityKey.privateKey);
19858
- if (compact) {
19859
- return signature.toCompactRawBytes();
19860
- }
19861
- return signature.toDERRawBytes();
19862
- }
19863
- async decryptEcies(ciphertext) {
19864
- if (!this.identityKey?.privateKey) {
19865
- throw new ConfigurationError("Identity key not initialized", {
19866
- configKey: "identityKey"
19867
- });
19868
- }
19869
- const receiverEciesPrivKey = ecies.PrivateKey.fromHex(
19870
- (0, import_utils5.bytesToHex)(this.identityKey.privateKey)
19871
- );
19872
- const privateKey = ecies.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
19873
- const publicKey = import_secp256k15.secp256k1.getPublicKey(privateKey);
19874
- return publicKey;
19875
- }
19876
- async getRandomSigningCommitment() {
19877
- const nonce = getRandomSigningNonce();
19878
- const commitment = getSigningCommitmentFromNonce(nonce);
19879
- this.commitmentToNonceMap.set(commitment, nonce);
19880
- return {
19881
- commitment
19882
- };
19883
- }
19884
- async validateMessageWithIdentityKey(message, signature) {
19885
- if (!this.identityKey?.publicKey) {
19886
- throw new ConfigurationError("Identity key not initialized", {
19887
- configKey: "identityKey"
19888
- });
19889
- }
19890
- return import_secp256k15.secp256k1.verify(signature, message, this.identityKey.publicKey);
19891
- }
19892
- signTransactionIndex(tx, index, publicKey) {
19893
- let privateKey;
19894
- if ((0, import_utils5.equalBytes)(publicKey, this.identityKey?.publicKey ?? new Uint8Array())) {
19895
- privateKey = this.identityKey?.privateKey;
19896
- } else if ((0, import_utils5.equalBytes)(publicKey, this.depositKey?.publicKey ?? new Uint8Array())) {
19897
- privateKey = this.depositKey?.privateKey;
19898
- }
19899
- if (!privateKey) {
19900
- throw new ValidationError("Private key not found for public key", {
19901
- field: "privateKey",
19902
- value: (0, import_utils5.bytesToHex)(publicKey)
19903
- });
19904
- }
19905
- tx.signIdx(privateKey, index);
19906
- }
19907
- };
19908
-
19909
- // src/utils/network.ts
19910
- init_buffer();
19911
- var btc = __toESM(require("@scure/btc-signer"), 1);
19912
- var import_base2 = require("@scure/base");
19913
- var Network2 = /* @__PURE__ */ ((Network5) => {
19914
- Network5[Network5["MAINNET"] = 0] = "MAINNET";
19915
- Network5[Network5["TESTNET"] = 1] = "TESTNET";
19916
- Network5[Network5["SIGNET"] = 2] = "SIGNET";
19917
- Network5[Network5["REGTEST"] = 3] = "REGTEST";
19918
- Network5[Network5["LOCAL"] = 4] = "LOCAL";
19919
- return Network5;
19920
- })(Network2 || {});
19921
- var NetworkToProto = {
19922
- [0 /* MAINNET */]: 1 /* MAINNET */,
19923
- [1 /* TESTNET */]: 3 /* TESTNET */,
19924
- [2 /* SIGNET */]: 4 /* SIGNET */,
19925
- [3 /* REGTEST */]: 2 /* REGTEST */,
19926
- [4 /* LOCAL */]: 2 /* REGTEST */
19927
- };
19928
- var protoToNetwork = (protoNetwork) => {
19929
- switch (protoNetwork) {
19930
- case 1 /* MAINNET */:
19931
- return 0 /* MAINNET */;
19932
- case 3 /* TESTNET */:
19933
- return 1 /* TESTNET */;
19934
- case 4 /* SIGNET */:
19935
- return 2 /* SIGNET */;
19936
- case 2 /* REGTEST */:
19937
- return 3 /* REGTEST */;
19938
- default:
19939
- return void 0;
19940
- }
19941
- };
19942
- var NetworkConfig = {
19943
- [0 /* MAINNET */]: btc.NETWORK,
19944
- [1 /* TESTNET */]: btc.TEST_NETWORK,
19945
- [2 /* SIGNET */]: btc.TEST_NETWORK,
19946
- [3 /* REGTEST */]: { ...btc.TEST_NETWORK, bech32: "bcrt" },
19947
- [4 /* LOCAL */]: { ...btc.TEST_NETWORK, bech32: "bcrt" }
19948
- };
19949
- var getNetwork = (network) => NetworkConfig[network];
19950
- function getNetworkFromAddress(address) {
19951
- try {
19952
- const bechAddress = address;
19953
- const decoded = (() => {
19954
- try {
19955
- return import_base2.bech32.decode(bechAddress);
19956
- } catch (_) {
19957
- return import_base2.bech32m.decode(bechAddress);
19958
- }
19959
- })();
19960
- if (decoded.prefix === "bc") {
19961
- return "MAINNET" /* MAINNET */;
19962
- } else if (decoded.prefix === "bcrt") {
19963
- return "REGTEST" /* REGTEST */;
19964
- }
19965
- } catch (err) {
19966
- throw new ValidationError(
19967
- "Invalid Bitcoin address",
19968
- {
19969
- field: "address",
19970
- value: address,
19971
- expected: "Valid Bech32 address with prefix 'bc' or 'bcrt'"
19972
- },
19973
- err instanceof Error ? err : void 0
19974
- );
19975
- }
19976
- return null;
19977
- }
19978
- function getNetworkFromString(network) {
19979
- const net = (network ?? "REGTEST").toUpperCase();
19980
- if (net === "MAINNET") return 0 /* MAINNET */;
19981
- if (net === "TESTNET") return 1 /* TESTNET */;
19982
- if (net === "SIGNET") return 2 /* SIGNET */;
19983
- if (net === "LOCAL") return 4 /* LOCAL */;
19984
- return 3 /* REGTEST */;
19985
- }
19986
-
19987
- // src/services/wallet-config.ts
19988
- init_buffer();
19989
-
19990
- // src/tests/isHermeticTest.ts
19991
- init_buffer();
19992
- var isHermeticTest = Boolean(
19993
- typeof process !== "undefined" && process?.env?.HERMETIC_TEST === "true"
19994
- );
19995
-
19996
- // src/services/wallet-config.ts
19997
- var SSP_IDENTITY_PUBLIC_KEYS = {
19998
- LOCAL: "028c094a432d46a0ac95349d792c2e3730bd60c29188db716f56a99e39b95338b4",
19999
- REGTEST: {
20000
- PROD: "022bf283544b16c0622daecb79422007d167eca6ce9f0c98c0c49833b1f7170bfe"
20001
- },
20002
- MAINNET: {
20003
- PROD: "023e33e2920326f64ea31058d44777442d97d7d5cbfcf54e3060bc1695e5261c93"
20004
- }
20005
- };
20006
- var URL_CONFIG = {
20007
- LOCAL: {
20008
- SSP: "http://127.0.0.1:5000",
20009
- ELECTRS: "http://127.0.0.1:30000"
20010
- },
20011
- REGTEST: {
20012
- PROD: {
20013
- SSP: "https://api.lightspark.com",
20014
- ELECTRS: "https://regtest-mempool.us-west-2.sparkinfra.net/api"
20015
- }
20016
- },
20017
- MAINNET: {
20018
- PROD: {
20019
- SSP: "https://api.lightspark.com",
20020
- ELECTRS: "https://mempool.space/api"
20021
- }
20022
- }
20023
- };
20024
- var ELECTRS_CREDENTIALS = {
20025
- username: "spark-sdk",
20026
- password: "mCMk1JqlBNtetUNy"
20027
- };
20028
- function getElectrsUrl(network) {
20029
- switch (network) {
20030
- case "LOCAL":
20031
- return isHermeticTest ? "http://mempool.minikube.local/api" : URL_CONFIG.LOCAL.ELECTRS;
20032
- case "REGTEST":
20033
- return URL_CONFIG.REGTEST.PROD.ELECTRS;
20034
- case "MAINNET":
20035
- return URL_CONFIG.MAINNET.PROD.ELECTRS;
20036
- default:
20037
- return URL_CONFIG.LOCAL.ELECTRS;
20038
- }
20039
- }
20040
- function getSspIdentityPublicKey(network) {
20041
- switch (network) {
20042
- case "LOCAL":
20043
- return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
20044
- case "REGTEST":
20045
- return SSP_IDENTITY_PUBLIC_KEYS.REGTEST.PROD;
20046
- case "MAINNET":
20047
- return SSP_IDENTITY_PUBLIC_KEYS.MAINNET.PROD;
20048
- default:
20049
- return SSP_IDENTITY_PUBLIC_KEYS.LOCAL;
20050
- }
20051
- }
20052
- function getSspUrl(network) {
20053
- switch (network) {
20054
- case "LOCAL":
20055
- return isHermeticTest ? "http://app.minikube.local" : URL_CONFIG.LOCAL.SSP;
20056
- case "REGTEST":
20057
- return URL_CONFIG.REGTEST.PROD.SSP;
20058
- case "MAINNET":
20059
- return URL_CONFIG.MAINNET.PROD.SSP;
20060
- default:
20061
- return URL_CONFIG.LOCAL.SSP;
20062
- }
20063
- }
20064
- function getSspSchemaEndpoint(network) {
20065
- switch (network) {
20066
- case "LOCAL":
20067
- return "graphql/spark/rc";
20068
- }
20069
- return;
20070
- }
20071
- var PROD_PUBKEYS = [
20072
- "03dfbdff4b6332c220f8fa2ba8ed496c698ceada563fa01b67d9983bfc5c95e763",
20073
- "03e625e9768651c9be268e287245cc33f96a68ce9141b0b4769205db027ee8ed77",
20074
- "022eda13465a59205413086130a65dc0ed1b8f8e51937043161f8be0c369b1a410"
20075
- ];
20076
- function getLocalFrostSignerAddress() {
20077
- return isHermeticTest ? "localhost:9999" : "unix:///tmp/frost_0.sock";
20078
- }
20079
- var BASE_CONFIG = {
20080
- network: "LOCAL",
20081
- coordinatorIdentifier: "0000000000000000000000000000000000000000000000000000000000000001",
20082
- frostSignerAddress: getLocalFrostSignerAddress(),
20083
- threshold: 2,
20084
- signingOperators: getLocalSigningOperators(),
20085
- tokenSignatures: "SCHNORR",
20086
- tokenValidityDurationSeconds: 180,
20087
- electrsUrl: getElectrsUrl("LOCAL"),
20088
- expectedWithdrawBondSats: 1e4,
20089
- expectedWithdrawRelativeBlockLocktime: 1e3,
20090
- sspClientOptions: {
20091
- baseUrl: getSspUrl("LOCAL"),
20092
- identityPublicKey: getSspIdentityPublicKey("LOCAL"),
20093
- schemaEndpoint: getSspSchemaEndpoint("LOCAL")
20094
- },
20095
- signerWithPreExistingKeys: false,
20096
- console: {
20097
- otel: false
20098
- }
20099
- };
20100
- var LOCAL_WALLET_CONFIG = {
20101
- ...BASE_CONFIG,
20102
- threshold: 3
20103
- };
20104
- var LOCAL_WALLET_CONFIG_SCHNORR = {
20105
- ...LOCAL_WALLET_CONFIG,
20106
- threshold: 3
20107
- // 3 for issuance tests.
20108
- };
20109
- var LOCAL_WALLET_CONFIG_ECDSA = {
20110
- ...LOCAL_WALLET_CONFIG,
20111
- tokenSignatures: "ECDSA",
20112
- threshold: 3
20113
- // 3 for issuance tests.
20114
- };
20115
- var REGTEST_WALLET_CONFIG = {
20116
- ...BASE_CONFIG,
20117
- network: "REGTEST",
20118
- signingOperators: getSigningOperators(),
20119
- electrsUrl: getElectrsUrl("REGTEST"),
20120
- expectedWithdrawBondSats: 1e4,
20121
- expectedWithdrawRelativeBlockLocktime: 1e3,
20122
- sspClientOptions: {
20123
- baseUrl: getSspUrl("REGTEST"),
20124
- identityPublicKey: getSspIdentityPublicKey("REGTEST")
20125
- }
20126
- };
20127
- var MAINNET_WALLET_CONFIG = {
20128
- ...BASE_CONFIG,
20129
- network: "MAINNET",
20130
- signingOperators: getSigningOperators(),
20131
- electrsUrl: getElectrsUrl("MAINNET"),
20132
- expectedWithdrawBondSats: 1e4,
20133
- expectedWithdrawRelativeBlockLocktime: 1e3,
20134
- sspClientOptions: {
20135
- baseUrl: getSspUrl("MAINNET"),
20136
- identityPublicKey: getSspIdentityPublicKey("MAINNET")
20137
- }
20138
- };
20139
- var WalletConfig = {
20140
- LOCAL: LOCAL_WALLET_CONFIG,
20141
- LOCAL_SCHNORR: LOCAL_WALLET_CONFIG_SCHNORR,
20142
- LOCAL_ECDSA: LOCAL_WALLET_CONFIG_ECDSA,
20143
- REGTEST: REGTEST_WALLET_CONFIG,
20144
- MAINNET: MAINNET_WALLET_CONFIG
20145
- };
20146
- function getSigningOperators() {
20147
- return {
20148
- "0000000000000000000000000000000000000000000000000000000000000001": {
20149
- id: 0,
20150
- identifier: "0000000000000000000000000000000000000000000000000000000000000001",
20151
- address: "https://0.spark.lightspark.com",
20152
- identityPublicKey: PROD_PUBKEYS[0]
20153
- },
20154
- "0000000000000000000000000000000000000000000000000000000000000002": {
20155
- id: 1,
20156
- identifier: "0000000000000000000000000000000000000000000000000000000000000002",
20157
- address: "https://1.spark.lightspark.com",
20158
- identityPublicKey: PROD_PUBKEYS[1]
20159
- },
20160
- "0000000000000000000000000000000000000000000000000000000000000003": {
20161
- id: 2,
20162
- identifier: "0000000000000000000000000000000000000000000000000000000000000003",
20163
- address: "https://2.spark.flashnet.xyz",
20164
- identityPublicKey: PROD_PUBKEYS[2]
20165
- }
20166
- };
20167
- }
20168
- function getLocalSigningOperators() {
20169
- const addresses = Array.from(
20170
- { length: 5 },
20171
- (_, i) => isHermeticTest ? `https://${i}.spark.minikube.local` : `https://localhost:${i + 8535}`
20172
- );
20173
- const pubkeys = [
20174
- "0322ca18fc489ae25418a0e768273c2c61cabb823edfb14feb891e9bec62016510",
20175
- "0341727a6c41b168f07eb50865ab8c397a53c7eef628ac1020956b705e43b6cb27",
20176
- "0305ab8d485cc752394de4981f8a5ae004f2becfea6f432c9a59d5022d8764f0a6",
20177
- "0352aef4d49439dedd798ac4aef1e7ebef95f569545b647a25338398c1247ffdea",
20178
- "02c05c88cc8fc181b1ba30006df6a4b0597de6490e24514fbdd0266d2b9cd3d0ba"
20179
- ];
20180
- return {
20181
- "0000000000000000000000000000000000000000000000000000000000000001": {
20182
- id: 0,
20183
- identifier: "0000000000000000000000000000000000000000000000000000000000000001",
20184
- address: addresses[0],
20185
- identityPublicKey: pubkeys[0]
20186
- },
20187
- "0000000000000000000000000000000000000000000000000000000000000002": {
20188
- id: 1,
20189
- identifier: "0000000000000000000000000000000000000000000000000000000000000002",
20190
- address: addresses[1],
20191
- identityPublicKey: pubkeys[1]
20192
- },
20193
- "0000000000000000000000000000000000000000000000000000000000000003": {
20194
- id: 2,
20195
- identifier: "0000000000000000000000000000000000000000000000000000000000000003",
20196
- address: addresses[2],
20197
- identityPublicKey: pubkeys[2]
20198
- },
20199
- "0000000000000000000000000000000000000000000000000000000000000004": {
20200
- id: 3,
20201
- identifier: "0000000000000000000000000000000000000000000000000000000000000004",
20202
- address: addresses[3],
20203
- identityPublicKey: pubkeys[3]
20204
- },
20205
- "0000000000000000000000000000000000000000000000000000000000000005": {
20206
- id: 4,
20207
- identifier: "0000000000000000000000000000000000000000000000000000000000000005",
20208
- address: addresses[4],
20209
- identityPublicKey: pubkeys[4]
20210
- }
20211
- };
20212
- }
20213
-
20214
- // src/services/config.ts
20215
- var WalletConfigService = class {
20216
- config;
20217
- signer;
20218
- sspClientOptions;
20219
- constructor(options, signer) {
20220
- const network = options?.network ?? "REGTEST";
20221
- this.config = {
20222
- ...this.getDefaultConfig(Network2[network]),
20223
- ...options
20224
- };
20225
- this.signer = signer ?? new DefaultSparkSigner();
20226
- this.sspClientOptions = this.config.sspClientOptions;
20227
- }
20228
- getDefaultConfig(network) {
20229
- switch (network) {
20230
- case 0 /* MAINNET */:
20231
- return WalletConfig.MAINNET;
20232
- case 3 /* REGTEST */:
20233
- return WalletConfig.REGTEST;
20234
- default:
20235
- return WalletConfig.LOCAL;
20236
- }
20237
- }
20238
- getCoordinatorAddress() {
20239
- const coordinator = this.config.signingOperators[this.config.coordinatorIdentifier];
20240
- if (!coordinator) {
20241
- throw new ConfigurationError(
20242
- "Coordinator not found in signing operators",
20243
- {
20244
- configKey: "signingOperators"
20245
- }
20246
- );
20247
- }
20248
- return coordinator.address;
20249
- }
20250
- getSigningOperators() {
20251
- return this.config.signingOperators;
20252
- }
20253
- getThreshold() {
20254
- return this.config.threshold;
20255
- }
20256
- getCoordinatorIdentifier() {
20257
- return this.config.coordinatorIdentifier;
20258
- }
20259
- getExpectedWithdrawBondSats() {
20260
- return this.config.expectedWithdrawBondSats;
20261
- }
20262
- getExpectedWithdrawRelativeBlockLocktime() {
20263
- return this.config.expectedWithdrawRelativeBlockLocktime;
20264
- }
20265
- getSspNetwork() {
20266
- if (this.config.network === "MAINNET") {
20267
- return "MAINNET" /* MAINNET */;
20268
- } else if (this.config.network === "REGTEST") {
20269
- return "REGTEST" /* REGTEST */;
20270
- } else if (this.config.network === "TESTNET") {
20271
- return "TESTNET" /* TESTNET */;
20272
- } else if (this.config.network === "SIGNET") {
20273
- return "SIGNET" /* SIGNET */;
20274
- }
20275
- return "FUTURE_VALUE" /* FUTURE_VALUE */;
20276
- }
20277
- getNetwork() {
20278
- return Network2[this.config.network];
20279
- }
20280
- getNetworkType() {
20281
- return this.config.network;
20282
- }
20283
- getNetworkProto() {
20284
- return NetworkToProto[Network2[this.config.network]];
20285
- }
20286
- getTokenSignatures() {
20287
- return this.config.tokenSignatures;
20288
- }
20289
- getTokenValidityDurationSeconds() {
20290
- return this.config.tokenValidityDurationSeconds;
20291
- }
20292
- getElectrsUrl() {
20293
- return this.config.electrsUrl;
20294
- }
20295
- getSspBaseUrl() {
20296
- return this.config.sspClientOptions.baseUrl;
20297
- }
20298
- getSspIdentityPublicKey() {
20299
- return this.config.sspClientOptions.identityPublicKey;
20300
- }
20301
- getConsoleOptions() {
20302
- return {
20303
- ...this.config.console
20304
- };
20305
- }
20306
- };
20307
-
20308
- // src/services/connection/connection.ts
20309
- init_buffer();
20310
- var import_core12 = require("@lightsparkdev/core");
20311
- var import_sha23 = require("@noble/hashes/sha2");
20312
-
20313
- // src/proto/spark_authn.ts
20314
- init_buffer();
20315
- var import_wire5 = require("@bufbuild/protobuf/wire");
20316
- function createBaseChallenge() {
20317
- return { version: 0, timestamp: 0, nonce: new Uint8Array(0), publicKey: new Uint8Array(0) };
20318
- }
20319
- var Challenge = {
20320
- encode(message, writer = new import_wire5.BinaryWriter()) {
20321
- if (message.version !== 0) {
20322
- writer.uint32(8).int32(message.version);
20323
- }
20324
- if (message.timestamp !== 0) {
20325
- writer.uint32(16).int64(message.timestamp);
20326
- }
20327
- if (message.nonce.length !== 0) {
20328
- writer.uint32(26).bytes(message.nonce);
19507
+ if (message.nonce.length !== 0) {
19508
+ writer.uint32(26).bytes(message.nonce);
20329
19509
  }
20330
19510
  if (message.publicKey.length !== 0) {
20331
19511
  writer.uint32(34).bytes(message.publicKey);
@@ -23751,7 +22931,7 @@ var ConnectionManager = class {
23751
22931
  const challengeBytes = Challenge.encode(
23752
22932
  challengeResp.protectedChallenge.challenge
23753
22933
  ).finish();
23754
- const hash = (0, import_sha23.sha256)(challengeBytes);
22934
+ const hash = (0, import_sha22.sha256)(challengeBytes);
23755
22935
  const derSignatureBytes = await this.config.signer.signMessageWithIdentityKey(hash);
23756
22936
  const verifyResp = await sparkAuthnClient.verify_challenge({
23757
22937
  protectedChallenge: challengeResp.protectedChallenge,
@@ -23761,7 +22941,7 @@ var ConnectionManager = class {
23761
22941
  sparkAuthnClient.close?.();
23762
22942
  return verifyResp.sessionToken;
23763
22943
  } catch (error) {
23764
- if ((0, import_core12.isError)(error)) {
22944
+ if ((0, import_core10.isError)(error)) {
23765
22945
  sparkAuthnClient?.close?.();
23766
22946
  if (error.message.includes("challenge expired")) {
23767
22947
  console.warn(
@@ -23770,6 +22950,13 @@ var ConnectionManager = class {
23770
22950
  lastError = error;
23771
22951
  continue;
23772
22952
  }
22953
+ if (error.message.includes("UNAVAILABLE: No connection established.")) {
22954
+ console.warn(
22955
+ `Authentication attempt ${attempt + 1} failed due to unavailable status, retrying...`
22956
+ );
22957
+ lastError = error;
22958
+ continue;
22959
+ }
23773
22960
  throw new AuthenticationError(
23774
22961
  "Authentication failed",
23775
22962
  {
@@ -23820,7 +23007,7 @@ var ConnectionManager = class {
23820
23007
  return void 0;
23821
23008
  }
23822
23009
  async *handleMiddlewareError(error, address, call, metadata, options) {
23823
- if ((0, import_core12.isError)(error)) {
23010
+ if ((0, import_core10.isError)(error)) {
23824
23011
  if (error.message.includes("token has expired")) {
23825
23012
  const newAuthToken = await this.authenticate(address);
23826
23013
  const clientData = this.clients.get(address);
@@ -23848,9 +23035,9 @@ var import_uuidv72 = require("uuidv7");
23848
23035
 
23849
23036
  // src/utils/bitcoin.ts
23850
23037
  init_buffer();
23851
- var import_secp256k16 = require("@noble/curves/secp256k1");
23852
- var import_utils7 = require("@noble/curves/utils");
23853
- var import_sha24 = require("@noble/hashes/sha2");
23038
+ var import_secp256k1 = require("@noble/curves/secp256k1");
23039
+ var import_utils2 = require("@noble/curves/utils");
23040
+ var import_sha23 = require("@noble/hashes/sha2");
23854
23041
  var btc2 = __toESM(require("@scure/btc-signer"), 1);
23855
23042
  function computeTaprootKeyNoScript(pubkey) {
23856
23043
  if (pubkey.length !== 32) {
@@ -23860,10 +23047,10 @@ function computeTaprootKeyNoScript(pubkey) {
23860
23047
  expected: 32
23861
23048
  });
23862
23049
  }
23863
- const taggedHash = import_secp256k16.schnorr.utils.taggedHash("TapTweak", pubkey);
23864
- const tweak = (0, import_utils7.bytesToNumberBE)(taggedHash);
23865
- const P = import_secp256k16.schnorr.utils.lift_x(import_secp256k16.schnorr.utils.bytesToNumberBE(pubkey));
23866
- const Q = P.add(import_secp256k16.secp256k1.Point.fromPrivateKey(tweak));
23050
+ const taggedHash = import_secp256k1.schnorr.utils.taggedHash("TapTweak", pubkey);
23051
+ const tweak = (0, import_utils2.bytesToNumberBE)(taggedHash);
23052
+ const P = import_secp256k1.schnorr.utils.lift_x(import_secp256k1.schnorr.utils.bytesToNumberBE(pubkey));
23053
+ const Q = P.add(import_secp256k1.secp256k1.Point.fromPrivateKey(tweak));
23867
23054
  return Q.toBytes();
23868
23055
  }
23869
23056
  function getP2TRScriptFromPublicKey(pubKey, network) {
@@ -23874,7 +23061,7 @@ function getP2TRScriptFromPublicKey(pubKey, network) {
23874
23061
  expected: 33
23875
23062
  });
23876
23063
  }
23877
- const internalKey = import_secp256k16.secp256k1.Point.fromHex(pubKey);
23064
+ const internalKey = import_secp256k1.secp256k1.Point.fromHex(pubKey);
23878
23065
  const script = btc2.p2tr(
23879
23066
  internalKey.toBytes().slice(1, 33),
23880
23067
  void 0,
@@ -23896,7 +23083,7 @@ function getP2TRAddressFromPublicKey(pubKey, network) {
23896
23083
  expected: 33
23897
23084
  });
23898
23085
  }
23899
- const internalKey = import_secp256k16.secp256k1.Point.fromHex(pubKey);
23086
+ const internalKey = import_secp256k1.secp256k1.Point.fromHex(pubKey);
23900
23087
  const address = btc2.p2tr(
23901
23088
  internalKey.toBytes().slice(1, 33),
23902
23089
  void 0,
@@ -23914,7 +23101,7 @@ function getP2TRAddressFromPkScript(pkScript, network) {
23914
23101
  if (pkScript.length !== 34 || pkScript[0] !== 81 || pkScript[1] !== 32) {
23915
23102
  throw new ValidationError("Invalid pkscript", {
23916
23103
  field: "pkScript",
23917
- value: (0, import_utils7.bytesToHex)(pkScript),
23104
+ value: (0, import_utils2.bytesToHex)(pkScript),
23918
23105
  expected: "34 bytes starting with 0x51 0x20"
23919
23106
  });
23920
23107
  }
@@ -23939,7 +23126,7 @@ function getP2WPKHAddressFromPublicKey(pubKey, network) {
23939
23126
  return address;
23940
23127
  }
23941
23128
  function getTxFromRawTxHex(rawTxHex) {
23942
- const txBytes = (0, import_utils7.hexToBytes)(rawTxHex);
23129
+ const txBytes = (0, import_utils2.hexToBytes)(rawTxHex);
23943
23130
  const tx = btc2.Transaction.fromRaw(txBytes, {
23944
23131
  allowUnknownOutputs: true
23945
23132
  });
@@ -23986,10 +23173,10 @@ function getSigHashFromTx(tx, inputIndex, prevOutput) {
23986
23173
  );
23987
23174
  }
23988
23175
  function getTxId(tx) {
23989
- return (0, import_utils7.bytesToHex)((0, import_sha24.sha256)((0, import_sha24.sha256)(tx.toBytes(true))).reverse());
23176
+ return (0, import_utils2.bytesToHex)((0, import_sha23.sha256)((0, import_sha23.sha256)(tx.toBytes(true))).reverse());
23990
23177
  }
23991
23178
  function getTxIdNoReverse(tx) {
23992
- return (0, import_utils7.bytesToHex)((0, import_sha24.sha256)((0, import_sha24.sha256)(tx.toBytes(true))));
23179
+ return (0, import_utils2.bytesToHex)((0, import_sha23.sha256)((0, import_sha23.sha256)(tx.toBytes(true))));
23993
23180
  }
23994
23181
  function getTxEstimatedVbytesSizeByNumberOfInputsOutputs(numInputs, numOutputs) {
23995
23182
  const TX_OVERHEAD = 10;
@@ -24337,17 +23524,20 @@ function getEphemeralAnchorOutput() {
24337
23524
 
24338
23525
  // src/services/transfer.ts
24339
23526
  init_buffer();
24340
- var import_secp256k17 = require("@noble/curves/secp256k1");
24341
- var import_utils9 = require("@noble/curves/utils");
24342
- var import_sha26 = require("@noble/hashes/sha2");
23527
+ var import_secp256k12 = require("@noble/curves/secp256k1");
23528
+ var import_utils4 = require("@noble/curves/utils");
23529
+ var import_sha25 = require("@noble/hashes/sha2");
24343
23530
  var import_btc_signer2 = require("@scure/btc-signer");
24344
- var ecies2 = __toESM(require("eciesjs"), 1);
23531
+ var ecies = __toESM(require("eciesjs"), 1);
24345
23532
  var import_uuidv7 = require("uuidv7");
24346
23533
 
23534
+ // src/signer/types.ts
23535
+ init_buffer();
23536
+
24347
23537
  // src/utils/transfer_package.ts
24348
23538
  init_buffer();
24349
- var import_utils8 = require("@noble/curves/utils");
24350
- var import_sha25 = require("@noble/hashes/sha2");
23539
+ var import_utils3 = require("@noble/curves/utils");
23540
+ var import_sha24 = require("@noble/hashes/sha2");
24351
23541
  function getTransferPackageSigningPayload(transferID, transferPackage) {
24352
23542
  const encryptedPayload = transferPackage.keyTweakPackage;
24353
23543
  const pairs = Object.entries(
@@ -24355,7 +23545,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
24355
23545
  ).map(([key, value]) => ({ key, value }));
24356
23546
  pairs.sort((a, b) => a.key.localeCompare(b.key));
24357
23547
  const encoder = new TextEncoder();
24358
- let message = (0, import_utils8.hexToBytes)(transferID.replaceAll("-", ""));
23548
+ let message = (0, import_utils3.hexToBytes)(transferID.replaceAll("-", ""));
24359
23549
  for (const pair of pairs) {
24360
23550
  const keyPart = encoder.encode(pair.key + ":");
24361
23551
  const separator = encoder.encode(";");
@@ -24366,7 +23556,7 @@ function getTransferPackageSigningPayload(transferID, transferPackage) {
24366
23556
  ...separator
24367
23557
  ]);
24368
23558
  }
24369
- return (0, import_sha25.sha256)(message);
23559
+ return (0, import_sha24.sha256)(message);
24370
23560
  }
24371
23561
 
24372
23562
  // src/services/transfer.ts
@@ -24504,8 +23694,8 @@ var BaseTransferService = class {
24504
23694
  if (!operator) {
24505
23695
  throw new ValidationError("Operator not found");
24506
23696
  }
24507
- const soPublicKey = ecies2.PublicKey.fromHex(operator.identityPublicKey);
24508
- const encryptedProto = ecies2.encrypt(
23697
+ const soPublicKey = ecies.PublicKey.fromHex(operator.identityPublicKey);
23698
+ const encryptedProto = ecies.encrypt(
24509
23699
  soPublicKey.toBytes(),
24510
23700
  protoToEncryptBinary
24511
23701
  );
@@ -24636,8 +23826,8 @@ var BaseTransferService = class {
24636
23826
  return nodeSignatures;
24637
23827
  }
24638
23828
  async prepareSendTransferKeyTweaks(transferID, receiverIdentityPubkey, leaves, cpfpRefundSignatureMap, directRefundSignatureMap, directFromCpfpRefundSignatureMap) {
24639
- const receiverEciesPubKey = ecies2.PublicKey.fromHex(
24640
- (0, import_utils9.bytesToHex)(receiverIdentityPubkey)
23829
+ const receiverEciesPubKey = ecies.PublicKey.fromHex(
23830
+ (0, import_utils4.bytesToHex)(receiverIdentityPubkey)
24641
23831
  );
24642
23832
  const leavesTweaksMap = /* @__PURE__ */ new Map();
24643
23833
  for (const leaf of leaves) {
@@ -24667,7 +23857,7 @@ var BaseTransferService = class {
24667
23857
  first: leaf.keyDerivation,
24668
23858
  second: leaf.newKeyDerivation,
24669
23859
  receiverPublicKey: receiverEciesPubKey.toBytes(),
24670
- curveOrder: import_secp256k17.secp256k1.CURVE.n,
23860
+ curveOrder: import_secp256k12.secp256k1.CURVE.n,
24671
23861
  threshold: this.config.getThreshold(),
24672
23862
  numShares: Object.keys(signingOperators).length
24673
23863
  });
@@ -24677,8 +23867,8 @@ var BaseTransferService = class {
24677
23867
  if (!share) {
24678
23868
  throw new Error(`Share not found for operator ${operator.id}`);
24679
23869
  }
24680
- const pubkeyTweak = import_secp256k17.secp256k1.getPublicKey(
24681
- (0, import_utils9.numberToBytesBE)(share.share, 32),
23870
+ const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
23871
+ (0, import_utils4.numberToBytesBE)(share.share, 32),
24682
23872
  true
24683
23873
  );
24684
23874
  pubkeySharesTweak.set(identifier, pubkeyTweak);
@@ -24689,7 +23879,7 @@ var BaseTransferService = class {
24689
23879
  ...encoder.encode(transferID),
24690
23880
  ...secretCipher
24691
23881
  ]);
24692
- const payloadHash = (0, import_sha26.sha256)(payload);
23882
+ const payloadHash = (0, import_sha25.sha256)(payload);
24693
23883
  const signature = await this.config.signer.signMessageWithIdentityKey(
24694
23884
  payloadHash,
24695
23885
  true
@@ -24703,7 +23893,7 @@ var BaseTransferService = class {
24703
23893
  leafTweaksMap.set(identifier, {
24704
23894
  leafId: leaf.leaf.id,
24705
23895
  secretShareTweak: {
24706
- secretShare: (0, import_utils9.numberToBytesBE)(share.share, 32),
23896
+ secretShare: (0, import_utils4.numberToBytesBE)(share.share, 32),
24707
23897
  proofs: share.proofs
24708
23898
  },
24709
23899
  pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak),
@@ -24726,7 +23916,7 @@ var BaseTransferService = class {
24726
23916
  return void 0;
24727
23917
  }
24728
23918
  compareTransfers(transfer1, transfer2) {
24729
- return transfer1.id === transfer2.id && (0, import_utils9.equalBytes)(
23919
+ return transfer1.id === transfer2.id && (0, import_utils4.equalBytes)(
24730
23920
  transfer1.senderIdentityPublicKey,
24731
23921
  transfer2.senderIdentityPublicKey
24732
23922
  ) && transfer1.status === transfer2.status && transfer1.totalValue === transfer2.totalValue && transfer1.expiryTime?.getTime() === transfer2.expiryTime?.getTime() && transfer1.leaves.length === transfer2.leaves.length;
@@ -24808,8 +23998,8 @@ var TransferService = class extends BaseTransferService {
24808
23998
  ...transferIdBytes,
24809
23999
  ...leaf.secretCipher
24810
24000
  ]);
24811
- const payloadHash = (0, import_sha26.sha256)(payload);
24812
- if (!import_secp256k17.secp256k1.verify(
24001
+ const payloadHash = (0, import_sha25.sha256)(payload);
24002
+ if (!import_secp256k12.secp256k1.verify(
24813
24003
  leaf.signature,
24814
24004
  payloadHash,
24815
24005
  transfer.senderIdentityPublicKey
@@ -24973,7 +24163,7 @@ var TransferService = class extends BaseTransferService {
24973
24163
  }
24974
24164
  const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
24975
24165
  const cpfpNodeOutPoint = {
24976
- txid: (0, import_utils9.hexToBytes)(getTxId(nodeTx)),
24166
+ txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
24977
24167
  index: 0
24978
24168
  };
24979
24169
  let directNodeTx;
@@ -24981,7 +24171,7 @@ var TransferService = class extends BaseTransferService {
24981
24171
  if (leaf.leaf.directTx.length > 0) {
24982
24172
  directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
24983
24173
  directNodeOutPoint = {
24984
- txid: (0, import_utils9.hexToBytes)(getTxId(directNodeTx)),
24174
+ txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
24985
24175
  index: 0
24986
24176
  };
24987
24177
  }
@@ -25103,7 +24293,7 @@ var TransferService = class extends BaseTransferService {
25103
24293
  {
25104
24294
  first: leaf.keyDerivation,
25105
24295
  second: leaf.newKeyDerivation,
25106
- curveOrder: import_secp256k17.secp256k1.CURVE.n,
24296
+ curveOrder: import_secp256k12.secp256k1.CURVE.n,
25107
24297
  threshold: this.config.getThreshold(),
25108
24298
  numShares: Object.keys(signingOperators).length
25109
24299
  }
@@ -25114,8 +24304,8 @@ var TransferService = class extends BaseTransferService {
25114
24304
  if (!share) {
25115
24305
  throw new Error(`Share not found for operator ${operator.id}`);
25116
24306
  }
25117
- const pubkeyTweak = import_secp256k17.secp256k1.getPublicKey(
25118
- (0, import_utils9.numberToBytesBE)(share.share, 32)
24307
+ const pubkeyTweak = import_secp256k12.secp256k1.getPublicKey(
24308
+ (0, import_utils4.numberToBytesBE)(share.share, 32)
25119
24309
  );
25120
24310
  pubkeySharesTweak.set(identifier, pubkeyTweak);
25121
24311
  }
@@ -25128,7 +24318,7 @@ var TransferService = class extends BaseTransferService {
25128
24318
  leafTweaksMap.set(identifier, {
25129
24319
  leafId: leaf.leaf.id,
25130
24320
  secretShareTweak: {
25131
- secretShare: (0, import_utils9.numberToBytesBE)(share.share, 32),
24321
+ secretShare: (0, import_utils4.numberToBytesBE)(share.share, 32),
25132
24322
  proofs: share.proofs
25133
24323
  },
25134
24324
  pubkeySharesTweak: Object.fromEntries(pubkeySharesTweak)
@@ -25296,13 +24486,13 @@ var TransferService = class extends BaseTransferService {
25296
24486
  });
25297
24487
  }
25298
24488
  const newCpfpRefundOutPoint = {
25299
- txid: (0, import_utils9.hexToBytes)(getTxId(cpfpNodeTx)),
24489
+ txid: (0, import_utils4.hexToBytes)(getTxId(cpfpNodeTx)),
25300
24490
  index: 0
25301
24491
  };
25302
24492
  let newDirectRefundOutPoint;
25303
24493
  if (newDirectNodeTx) {
25304
24494
  newDirectRefundOutPoint = {
25305
- txid: (0, import_utils9.hexToBytes)(getTxId(newDirectNodeTx)),
24495
+ txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
25306
24496
  index: 0
25307
24497
  };
25308
24498
  }
@@ -25430,7 +24620,7 @@ var TransferService = class extends BaseTransferService {
25430
24620
  const refundTx = getTxFromRawTxBytes(node.refundTx);
25431
24621
  const refundSequence = refundTx.getInput(0).sequence || 0;
25432
24622
  const newNodeOutPoint = {
25433
- txid: (0, import_utils9.hexToBytes)(getTxId(nodeTx)),
24623
+ txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
25434
24624
  index: 0
25435
24625
  };
25436
24626
  const {
@@ -25467,13 +24657,13 @@ var TransferService = class extends BaseTransferService {
25467
24657
  });
25468
24658
  }
25469
24659
  const newCpfpRefundOutPoint = {
25470
- txid: (0, import_utils9.hexToBytes)(getTxId(newNodeTx)),
24660
+ txid: (0, import_utils4.hexToBytes)(getTxId(newNodeTx)),
25471
24661
  index: 0
25472
24662
  };
25473
24663
  let newDirectRefundOutPoint;
25474
24664
  if (newDirectNodeTx) {
25475
24665
  newDirectRefundOutPoint = {
25476
- txid: (0, import_utils9.hexToBytes)(getTxId(newDirectNodeTx)),
24666
+ txid: (0, import_utils4.hexToBytes)(getTxId(newDirectNodeTx)),
25477
24667
  index: 0
25478
24668
  };
25479
24669
  }
@@ -25707,13 +24897,13 @@ var TransferService = class extends BaseTransferService {
25707
24897
  };
25708
24898
  const signingPublicKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
25709
24899
  const cpfpRefundOutPoint = {
25710
- txid: (0, import_utils9.hexToBytes)(getTxId(nodeTx)),
24900
+ txid: (0, import_utils4.hexToBytes)(getTxId(nodeTx)),
25711
24901
  index: 0
25712
24902
  };
25713
24903
  let directRefundOutPoint;
25714
24904
  if (directNodeTx) {
25715
24905
  directRefundOutPoint = {
25716
- txid: (0, import_utils9.hexToBytes)(getTxId(directNodeTx)),
24906
+ txid: (0, import_utils4.hexToBytes)(getTxId(directNodeTx)),
25717
24907
  index: 0
25718
24908
  };
25719
24909
  }
@@ -25835,7 +25025,8 @@ var CoopExitService = class extends BaseTransferService {
25835
25025
  leaves,
25836
25026
  exitTxId,
25837
25027
  connectorOutputs,
25838
- receiverPubKey
25028
+ receiverPubKey,
25029
+ transferId
25839
25030
  }) {
25840
25031
  const {
25841
25032
  transfer,
@@ -25846,7 +25037,8 @@ var CoopExitService = class extends BaseTransferService {
25846
25037
  leaves,
25847
25038
  exitTxId,
25848
25039
  connectorOutputs,
25849
- receiverPubKey
25040
+ receiverPubKey,
25041
+ transferId
25850
25042
  );
25851
25043
  const transferTweak = await this.deliverTransferPackage(
25852
25044
  transfer,
@@ -25927,7 +25119,7 @@ var CoopExitService = class extends BaseTransferService {
25927
25119
  directFromCpfpRefundTx
25928
25120
  };
25929
25121
  }
25930
- async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey) {
25122
+ async signCoopExitRefunds(leaves, exitTxId, connectorOutputs, receiverPubKey, transferId) {
25931
25123
  if (leaves.length !== connectorOutputs.length) {
25932
25124
  throw new ValidationError(
25933
25125
  "Mismatch between leaves and connector outputs",
@@ -26031,7 +25223,7 @@ var CoopExitService = class extends BaseTransferService {
26031
25223
  try {
26032
25224
  response = await sparkClient.cooperative_exit_v2({
26033
25225
  transfer: {
26034
- transferId: (0, import_uuidv72.uuidv7)(),
25226
+ transferId,
26035
25227
  leavesToSend: signingJobs,
26036
25228
  ownerIdentityPublicKey: await this.config.signer.getIdentityPublicKey(),
26037
25229
  receiverIdentityPublicKey: receiverPubKey,
@@ -26087,15 +25279,114 @@ var CoopExitService = class extends BaseTransferService {
26087
25279
 
26088
25280
  // src/services/deposit.ts
26089
25281
  init_buffer();
26090
- var import_secp256k18 = require("@noble/curves/secp256k1");
26091
- var import_sha28 = require("@noble/hashes/sha2");
26092
- var import_utils10 = require("@noble/hashes/utils");
25282
+ var import_secp256k14 = require("@noble/curves/secp256k1");
25283
+ var import_sha27 = require("@noble/hashes/sha2");
25284
+ var import_utils6 = require("@noble/hashes/utils");
26093
25285
  var import_btc_signer4 = require("@scure/btc-signer");
26094
- var import_utils11 = require("@scure/btc-signer/utils");
25286
+ var import_utils7 = require("@scure/btc-signer/utils");
25287
+
25288
+ // src/utils/keys.ts
25289
+ init_buffer();
25290
+ var import_secp256k13 = require("@noble/curves/secp256k1");
25291
+ var import_utils5 = require("@noble/curves/utils");
25292
+ function addPublicKeys(a, b) {
25293
+ if (a.length !== 33 || b.length !== 33) {
25294
+ throw new ValidationError("Public keys must be 33 bytes", {
25295
+ field: "publicKeys",
25296
+ value: `a: ${a.length}, b: ${b.length}`,
25297
+ expected: 33
25298
+ });
25299
+ }
25300
+ const pubkeyA = import_secp256k13.secp256k1.Point.fromHex(a);
25301
+ const pubkeyB = import_secp256k13.secp256k1.Point.fromHex(b);
25302
+ return pubkeyA.add(pubkeyB).toBytes(true);
25303
+ }
25304
+ function applyAdditiveTweakToPublicKey(pubkey, tweak) {
25305
+ if (pubkey.length !== 33) {
25306
+ throw new ValidationError("Public key must be 33 bytes", {
25307
+ field: "pubkey",
25308
+ value: pubkey.length,
25309
+ expected: 33
25310
+ });
25311
+ }
25312
+ if (tweak.length !== 32) {
25313
+ throw new ValidationError("Tweak must be 32 bytes", {
25314
+ field: "tweak",
25315
+ value: tweak.length,
25316
+ expected: 32
25317
+ });
25318
+ }
25319
+ const pubkeyPoint = import_secp256k13.secp256k1.Point.fromHex(pubkey);
25320
+ const privTweek = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(tweak);
25321
+ const pubTweek = import_secp256k13.secp256k1.getPublicKey(privTweek, true);
25322
+ const tweekPoint = import_secp256k13.secp256k1.Point.fromHex(pubTweek);
25323
+ return pubkeyPoint.add(tweekPoint).toBytes(true);
25324
+ }
25325
+ function subtractPublicKeys(a, b) {
25326
+ if (a.length !== 33 || b.length !== 33) {
25327
+ throw new ValidationError("Public keys must be 33 bytes", {
25328
+ field: "publicKeys",
25329
+ value: `a: ${a.length}, b: ${b.length}`,
25330
+ expected: 33
25331
+ });
25332
+ }
25333
+ const pubkeyA = import_secp256k13.secp256k1.Point.fromHex(a);
25334
+ const pubkeyB = import_secp256k13.secp256k1.Point.fromHex(b);
25335
+ return pubkeyA.subtract(pubkeyB).toBytes(true);
25336
+ }
25337
+ function addPrivateKeys(a, b) {
25338
+ if (a.length !== 32 || b.length !== 32) {
25339
+ throw new ValidationError("Private keys must be 32 bytes", {
25340
+ field: "privateKeys",
25341
+ value: `a: ${a.length}, b: ${b.length}`,
25342
+ expected: 32
25343
+ });
25344
+ }
25345
+ const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
25346
+ const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
25347
+ const sum2 = (privA + privB) % import_secp256k13.secp256k1.CURVE.n;
25348
+ return (0, import_utils5.numberToBytesBE)(sum2, 32);
25349
+ }
25350
+ function subtractPrivateKeys(a, b) {
25351
+ if (a.length !== 32 || b.length !== 32) {
25352
+ throw new ValidationError("Private keys must be 32 bytes", {
25353
+ field: "privateKeys",
25354
+ value: `a: ${a.length}, b: ${b.length}`,
25355
+ expected: 32
25356
+ });
25357
+ }
25358
+ const privA = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(a);
25359
+ const privB = import_secp256k13.secp256k1.utils.normPrivateKeyToScalar(b);
25360
+ const sum2 = (import_secp256k13.secp256k1.CURVE.n - privB + privA) % import_secp256k13.secp256k1.CURVE.n;
25361
+ return (0, import_utils5.numberToBytesBE)(sum2, 32);
25362
+ }
25363
+ function sumOfPrivateKeys(keys) {
25364
+ return keys.reduce((sum2, key) => {
25365
+ if (key.length !== 32) {
25366
+ throw new ValidationError("Private keys must be 32 bytes", {
25367
+ field: "privateKey",
25368
+ value: key.length,
25369
+ expected: 32
25370
+ });
25371
+ }
25372
+ return addPrivateKeys(sum2, key);
25373
+ });
25374
+ }
25375
+ function lastKeyWithTarget(target, keys) {
25376
+ if (target.length !== 32) {
25377
+ throw new ValidationError("Target must be 32 bytes", {
25378
+ field: "target",
25379
+ value: target.length,
25380
+ expected: 32
25381
+ });
25382
+ }
25383
+ const sum2 = sumOfPrivateKeys(keys);
25384
+ return subtractPrivateKeys(target, sum2);
25385
+ }
26095
25386
 
26096
25387
  // src/utils/proof.ts
26097
25388
  init_buffer();
26098
- var import_sha27 = require("@noble/hashes/sha2");
25389
+ var import_sha26 = require("@noble/hashes/sha2");
26099
25390
  function proofOfPossessionMessageHashForDepositAddress(userPubkey, operatorPubkey, depositAddress) {
26100
25391
  const encoder = new TextEncoder();
26101
25392
  const depositAddressBytes = encoder.encode(depositAddress);
@@ -26104,7 +25395,7 @@ function proofOfPossessionMessageHashForDepositAddress(userPubkey, operatorPubke
26104
25395
  ...operatorPubkey,
26105
25396
  ...depositAddressBytes
26106
25397
  ]);
26107
- return (0, import_sha27.sha256)(proofMsg);
25398
+ return (0, import_sha26.sha256)(proofMsg);
26108
25399
  }
26109
25400
 
26110
25401
  // src/services/deposit.ts
@@ -26140,7 +25431,7 @@ var DepositService = class {
26140
25431
  void 0,
26141
25432
  getNetwork(this.config.getNetwork())
26142
25433
  ).tweakedPubkey;
26143
- const isVerified = import_secp256k18.schnorr.verify(
25434
+ const isVerified = import_secp256k14.schnorr.verify(
26144
25435
  address.depositAddressProof.proofOfPossessionSignature,
26145
25436
  msg,
26146
25437
  taprootKey
@@ -26154,12 +25445,12 @@ var DepositService = class {
26154
25445
  }
26155
25446
  );
26156
25447
  }
26157
- const addrHash = (0, import_sha28.sha256)(address.address);
25448
+ const addrHash = (0, import_sha27.sha256)(address.address);
26158
25449
  for (const operator of Object.values(this.config.getSigningOperators())) {
26159
25450
  if (operator.identifier === this.config.getCoordinatorIdentifier() && !verifyCoordinatorProof) {
26160
25451
  continue;
26161
25452
  }
26162
- const operatorPubkey2 = (0, import_utils10.hexToBytes)(operator.identityPublicKey);
25453
+ const operatorPubkey2 = (0, import_utils6.hexToBytes)(operator.identityPublicKey);
26163
25454
  const operatorSig = address.depositAddressProof.addressSignatures[operator.identifier];
26164
25455
  if (!operatorSig) {
26165
25456
  throw new ValidationError("Operator signature not found", {
@@ -26167,8 +25458,8 @@ var DepositService = class {
26167
25458
  value: operator.identifier
26168
25459
  });
26169
25460
  }
26170
- const sig = import_secp256k18.secp256k1.Signature.fromDER(operatorSig);
26171
- const isVerified2 = import_secp256k18.secp256k1.verify(
25461
+ const sig = import_secp256k14.secp256k1.Signature.fromDER(operatorSig);
25462
+ const isVerified2 = import_secp256k14.secp256k1.verify(
26172
25463
  sig.toCompactRawBytes(),
26173
25464
  addrHash,
26174
25465
  operatorPubkey2
@@ -26288,7 +25579,7 @@ var DepositService = class {
26288
25579
  });
26289
25580
  }
26290
25581
  const depositOutPoint = {
26291
- txid: (0, import_utils10.hexToBytes)(getTxId(depositTx)),
25582
+ txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
26292
25583
  index: vout
26293
25584
  };
26294
25585
  const depositTxOut = {
@@ -26307,8 +25598,8 @@ var DepositService = class {
26307
25598
  const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
26308
25599
  sequence: INITIAL_SEQUENCE,
26309
25600
  directSequence: INITIAL_DIRECT_SEQUENCE,
26310
- input: { txid: (0, import_utils10.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
26311
- directInput: { txid: (0, import_utils10.hexToBytes)(getTxId(directRootTx)), index: 0 },
25601
+ input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
25602
+ directInput: { txid: (0, import_utils6.hexToBytes)(getTxId(directRootTx)), index: 0 },
26312
25603
  amountSats: amount,
26313
25604
  receivingPubkey: signingPubKey,
26314
25605
  network: this.config.getNetwork()
@@ -26438,7 +25729,7 @@ var DepositService = class {
26438
25729
  }
26439
25730
  );
26440
25731
  }
26441
- if (!(0, import_utils11.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
25732
+ if (!(0, import_utils7.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
26442
25733
  throw new ValidationError("Verifying key mismatch", {
26443
25734
  field: "verifyingKey",
26444
25735
  value: treeResp.rootNodeSignatureShares.verifyingKey,
@@ -26602,7 +25893,7 @@ var DepositService = class {
26602
25893
  });
26603
25894
  }
26604
25895
  const depositOutPoint = {
26605
- txid: (0, import_utils10.hexToBytes)(getTxId(depositTx)),
25896
+ txid: (0, import_utils6.hexToBytes)(getTxId(depositTx)),
26606
25897
  index: vout
26607
25898
  };
26608
25899
  const depositTxOut = {
@@ -26615,7 +25906,7 @@ var DepositService = class {
26615
25906
  const signingPubKey = await this.config.signer.getPublicKeyFromDerivation(keyDerivation);
26616
25907
  const { cpfpRefundTx } = createRefundTxs({
26617
25908
  sequence: INITIAL_SEQUENCE,
26618
- input: { txid: (0, import_utils10.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
25909
+ input: { txid: (0, import_utils6.hexToBytes)(getTxId(cpfpRootTx)), index: 0 },
26619
25910
  amountSats: amount,
26620
25911
  receivingPubkey: signingPubKey,
26621
25912
  network: this.config.getNetwork()
@@ -26685,7 +25976,7 @@ var DepositService = class {
26685
25976
  }
26686
25977
  );
26687
25978
  }
26688
- if (!(0, import_utils11.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
25979
+ if (!(0, import_utils7.equalBytes)(treeResp.rootNodeSignatureShares.verifyingKey, verifyingKey)) {
26689
25980
  throw new ValidationError("Verifying key mismatch", {
26690
25981
  field: "verifyingKey",
26691
25982
  value: treeResp.rootNodeSignatureShares.verifyingKey,
@@ -26761,11 +26052,23 @@ var DepositService = class {
26761
26052
 
26762
26053
  // src/services/lightning.ts
26763
26054
  init_buffer();
26764
- var import_secp256k19 = require("@noble/curves/secp256k1");
26765
- var import_utils12 = require("@noble/curves/utils");
26766
- var import_sha29 = require("@noble/hashes/sha2");
26055
+ var import_secp256k15 = require("@noble/curves/secp256k1");
26056
+ var import_utils8 = require("@noble/curves/utils");
26057
+ var import_sha28 = require("@noble/hashes/sha2");
26767
26058
  var import_uuidv73 = require("uuidv7");
26768
26059
 
26060
+ // src/utils/crypto.ts
26061
+ init_buffer();
26062
+ var cryptoImpl = globalThis.crypto ?? null;
26063
+ var getCrypto = () => {
26064
+ if (!cryptoImpl) {
26065
+ throw new Error(
26066
+ "Crypto implementation is not set. Please set it using setCrypto()."
26067
+ );
26068
+ }
26069
+ return cryptoImpl;
26070
+ };
26071
+
26769
26072
  // src/services/bolt11-spark.ts
26770
26073
  init_buffer();
26771
26074
  var import_light_bolt11_decoder = require("light-bolt11-decoder");
@@ -26848,8 +26151,8 @@ var LightningService = class {
26848
26151
  }) {
26849
26152
  const crypto = getCrypto();
26850
26153
  const randBytes = crypto.getRandomValues(new Uint8Array(32));
26851
- const preimage = (0, import_utils12.numberToBytesBE)(
26852
- (0, import_utils12.bytesToNumberBE)(randBytes) % import_secp256k19.secp256k1.CURVE.n,
26154
+ const preimage = (0, import_utils8.numberToBytesBE)(
26155
+ (0, import_utils8.bytesToNumberBE)(randBytes) % import_secp256k15.secp256k1.CURVE.n,
26853
26156
  32
26854
26157
  );
26855
26158
  return await this.createLightningInvoiceWithPreImage({
@@ -26869,7 +26172,7 @@ var LightningService = class {
26869
26172
  receiverIdentityPubkey,
26870
26173
  descriptionHash
26871
26174
  }) {
26872
- const paymentHash = (0, import_sha29.sha256)(preimage);
26175
+ const paymentHash = (0, import_sha28.sha256)(preimage);
26873
26176
  const invoice = await invoiceCreator(
26874
26177
  amountSats,
26875
26178
  paymentHash,
@@ -26886,7 +26189,7 @@ var LightningService = class {
26886
26189
  }
26887
26190
  const shares = await this.config.signer.splitSecretWithProofs({
26888
26191
  secret: preimage,
26889
- curveOrder: import_secp256k19.secp256k1.CURVE.n,
26192
+ curveOrder: import_secp256k15.secp256k1.CURVE.n,
26890
26193
  threshold: this.config.getThreshold(),
26891
26194
  numShares: Object.keys(this.config.getSigningOperators()).length
26892
26195
  });
@@ -26904,12 +26207,12 @@ var LightningService = class {
26904
26207
  const sparkClient = await this.connectionManager.createSparkClient(
26905
26208
  operator.address
26906
26209
  );
26907
- const userIdentityPublicKey = receiverIdentityPubkey ? (0, import_utils12.hexToBytes)(receiverIdentityPubkey) : await this.config.signer.getIdentityPublicKey();
26210
+ const userIdentityPublicKey = receiverIdentityPubkey ? (0, import_utils8.hexToBytes)(receiverIdentityPubkey) : await this.config.signer.getIdentityPublicKey();
26908
26211
  try {
26909
26212
  await sparkClient.store_preimage_share({
26910
26213
  paymentHash,
26911
26214
  preimageShare: {
26912
- secretShare: (0, import_utils12.numberToBytesBE)(share.share, 32),
26215
+ secretShare: (0, import_utils8.numberToBytesBE)(share.share, 32),
26913
26216
  proofs: share.proofs
26914
26217
  },
26915
26218
  threshold: this.config.getThreshold(),
@@ -27078,7 +26381,7 @@ var LightningService = class {
27078
26381
  const sparkClient = await this.connectionManager.createSparkClient(
27079
26382
  this.config.getCoordinatorAddress()
27080
26383
  );
27081
- const paymentHash = (0, import_sha29.sha256)(preimage);
26384
+ const paymentHash = (0, import_sha28.sha256)(preimage);
27082
26385
  let response;
27083
26386
  try {
27084
26387
  response = await sparkClient.provide_preimage({
@@ -27110,21 +26413,21 @@ var LightningService = class {
27110
26413
 
27111
26414
  // src/services/token-transactions.ts
27112
26415
  init_buffer();
27113
- var import_utils16 = require("@noble/curves/utils");
27114
- var import_utils17 = require("@noble/hashes/utils");
26416
+ var import_utils12 = require("@noble/curves/utils");
26417
+ var import_utils13 = require("@noble/hashes/utils");
27115
26418
 
27116
26419
  // src/utils/address.ts
27117
26420
  init_buffer();
27118
26421
  var import_wire7 = require("@bufbuild/protobuf/wire");
27119
- var import_secp256k110 = require("@noble/curves/secp256k1");
27120
- var import_utils13 = require("@noble/curves/utils");
27121
- var import_utils14 = require("@noble/hashes/utils");
26422
+ var import_secp256k16 = require("@noble/curves/secp256k1");
26423
+ var import_utils9 = require("@noble/curves/utils");
26424
+ var import_utils10 = require("@noble/hashes/utils");
27122
26425
  var import_base3 = require("@scure/base");
27123
26426
  var import_uuidv74 = require("uuidv7");
27124
26427
 
27125
26428
  // src/utils/invoice-hashing.ts
27126
26429
  init_buffer();
27127
- var import_sha210 = require("@noble/hashes/sha2");
26430
+ var import_sha29 = require("@noble/hashes/sha2");
27128
26431
  function HashSparkInvoice(sparkInvoiceFields, receiverPublicKey, network) {
27129
26432
  if (!sparkInvoiceFields) {
27130
26433
  throw new Error("Missing sparkInvoiceFields");
@@ -27161,20 +26464,20 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27161
26464
  }
27162
26465
  const { version, id, paymentType, memo, senderPublicKey, expiryTime } = sparkInvoiceFields;
27163
26466
  const allHashes = [];
27164
- const versionHashObj = import_sha210.sha256.create();
26467
+ const versionHashObj = import_sha29.sha256.create();
27165
26468
  const versionBytes = uint32be(version);
27166
26469
  versionHashObj.update(versionBytes);
27167
26470
  allHashes.push(versionHashObj.digest());
27168
- const idHashObj = import_sha210.sha256.create();
26471
+ const idHashObj = import_sha29.sha256.create();
27169
26472
  if (!id || id.length !== 16) {
27170
26473
  throw new Error("invoice id must be exactly 16 bytes");
27171
26474
  }
27172
26475
  idHashObj.update(id);
27173
26476
  allHashes.push(idHashObj.digest());
27174
- const networkHashObj = import_sha210.sha256.create();
26477
+ const networkHashObj = import_sha29.sha256.create();
27175
26478
  hashNetworkMagicInto(networkHashObj, network);
27176
26479
  allHashes.push(networkHashObj.digest());
27177
- const receiverPubKeyHashObj = import_sha210.sha256.create();
26480
+ const receiverPubKeyHashObj = import_sha29.sha256.create();
27178
26481
  if (!receiverPublicKey || receiverPublicKey.length !== 33) {
27179
26482
  throw new Error("receiver public key must be exactly 33 bytes");
27180
26483
  }
@@ -27183,10 +26486,10 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27183
26486
  switch (paymentType?.$case) {
27184
26487
  case "tokensPayment": {
27185
26488
  const tp = paymentType.tokensPayment;
27186
- const discrHash = import_sha210.sha256.create();
26489
+ const discrHash = import_sha29.sha256.create();
27187
26490
  discrHash.update(new Uint8Array([1]));
27188
26491
  allHashes.push(discrHash.digest());
27189
- const tokenIdHash = import_sha210.sha256.create();
26492
+ const tokenIdHash = import_sha29.sha256.create();
27190
26493
  const tokenIdentifier = tp.tokenIdentifier;
27191
26494
  if (!tokenIdentifier || tokenIdentifier.length === 0) {
27192
26495
  tokenIdHash.update(new Uint8Array(32));
@@ -27197,7 +26500,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27197
26500
  tokenIdHash.update(tokenIdentifier);
27198
26501
  }
27199
26502
  allHashes.push(tokenIdHash.digest());
27200
- const amountHash = import_sha210.sha256.create();
26503
+ const amountHash = import_sha29.sha256.create();
27201
26504
  const amount = tp.amount;
27202
26505
  if (amount && amount.length > 16) {
27203
26506
  throw new Error("token amount exceeds 16 bytes");
@@ -27210,10 +26513,10 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27210
26513
  }
27211
26514
  case "satsPayment": {
27212
26515
  const sp = paymentType.satsPayment;
27213
- const discrHash = import_sha210.sha256.create();
26516
+ const discrHash = import_sha29.sha256.create();
27214
26517
  discrHash.update(new Uint8Array([2]));
27215
26518
  allHashes.push(discrHash.digest());
27216
- const satsHash = import_sha210.sha256.create();
26519
+ const satsHash = import_sha29.sha256.create();
27217
26520
  let sats = 0n;
27218
26521
  if (sp && typeof sp.amount === "number" && sp.amount !== 0) {
27219
26522
  sats = BigInt(sp.amount);
@@ -27226,12 +26529,12 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27226
26529
  throw new Error("unsupported or missing payment type");
27227
26530
  }
27228
26531
  }
27229
- const memoHashObj = import_sha210.sha256.create();
26532
+ const memoHashObj = import_sha29.sha256.create();
27230
26533
  if (memo != null) {
27231
26534
  memoHashObj.update(new TextEncoder().encode(memo));
27232
26535
  }
27233
26536
  allHashes.push(memoHashObj.digest());
27234
- const senderPubKeyHashObj = import_sha210.sha256.create();
26537
+ const senderPubKeyHashObj = import_sha29.sha256.create();
27235
26538
  const spk = senderPublicKey;
27236
26539
  if (!spk || spk.length === 0) {
27237
26540
  senderPubKeyHashObj.update(new Uint8Array(33));
@@ -27242,7 +26545,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27242
26545
  senderPubKeyHashObj.update(spk);
27243
26546
  }
27244
26547
  allHashes.push(senderPubKeyHashObj.digest());
27245
- const expiryHashObj = import_sha210.sha256.create();
26548
+ const expiryHashObj = import_sha29.sha256.create();
27246
26549
  let exp = 0n;
27247
26550
  if (expiryTime instanceof Date) {
27248
26551
  const seconds = Math.floor(expiryTime.getTime() / 1e3);
@@ -27252,7 +26555,7 @@ function HashSparkInvoiceV1(sparkInvoiceFields, receiverPublicKey, network) {
27252
26555
  }
27253
26556
  expiryHashObj.update(uint64be(exp));
27254
26557
  allHashes.push(expiryHashObj.digest());
27255
- const finalHash = import_sha210.sha256.create();
26558
+ const finalHash = import_sha29.sha256.create();
27256
26559
  for (const hash of allHashes) {
27257
26560
  finalHash.update(hash);
27258
26561
  }
@@ -27276,7 +26579,7 @@ function bitcoinNetworkIdentifierFromNetwork(network) {
27276
26579
  function hashNetworkMagicInto(hasher, network) {
27277
26580
  const magic = bitcoinNetworkIdentifierFromNetwork(network);
27278
26581
  const magicBE = uint32be(magic);
27279
- hasher.update((0, import_sha210.sha256)(magicBE));
26582
+ hasher.update((0, import_sha29.sha256)(magicBE));
27280
26583
  }
27281
26584
  function uint32be(n) {
27282
26585
  const b = new Uint8Array(4);
@@ -27311,7 +26614,7 @@ function encodeSparkAddress(payload) {
27311
26614
  function encodeSparkAddressWithSignature(payload, signature) {
27312
26615
  try {
27313
26616
  isValidPublicKey(payload.identityPublicKey);
27314
- const identityPublicKey = (0, import_utils14.hexToBytes)(payload.identityPublicKey);
26617
+ const identityPublicKey = (0, import_utils10.hexToBytes)(payload.identityPublicKey);
27315
26618
  let sparkInvoiceFields;
27316
26619
  if (payload.sparkInvoiceFields) {
27317
26620
  validateSparkInvoiceFields(payload.sparkInvoiceFields);
@@ -27355,8 +26658,8 @@ function decodeSparkAddress(address, network) {
27355
26658
  const decoded = bech32mDecode(address);
27356
26659
  const payload = SparkAddress.decode(import_base3.bech32m.fromWords(decoded.words));
27357
26660
  const { identityPublicKey, sparkInvoiceFields, signature } = payload;
27358
- const identityPubkeyHex = (0, import_utils14.bytesToHex)(identityPublicKey);
27359
- const signatureHex = signature ? (0, import_utils14.bytesToHex)(signature) : void 0;
26661
+ const identityPubkeyHex = (0, import_utils10.bytesToHex)(identityPublicKey);
26662
+ const signatureHex = signature ? (0, import_utils10.bytesToHex)(signature) : void 0;
27360
26663
  isValidPublicKey(identityPubkeyHex);
27361
26664
  return {
27362
26665
  identityPublicKey: identityPubkeyHex,
@@ -27366,10 +26669,10 @@ function decodeSparkAddress(address, network) {
27366
26669
  id: import_uuidv74.UUID.ofInner(sparkInvoiceFields.id).toString(),
27367
26670
  paymentType: sparkInvoiceFields.paymentType ? sparkInvoiceFields.paymentType.$case === "tokensPayment" ? {
27368
26671
  type: "tokens",
27369
- tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0, import_utils14.bytesToHex)(
26672
+ tokenIdentifier: sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier ? (0, import_utils10.bytesToHex)(
27370
26673
  sparkInvoiceFields.paymentType.tokensPayment.tokenIdentifier
27371
26674
  ) : void 0,
27372
- amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0, import_utils13.bytesToNumberBE)(
26675
+ amount: sparkInvoiceFields.paymentType.tokensPayment.amount ? (0, import_utils9.bytesToNumberBE)(
27373
26676
  sparkInvoiceFields.paymentType.tokensPayment.amount
27374
26677
  ) : void 0
27375
26678
  } : sparkInvoiceFields.paymentType.$case === "satsPayment" ? {
@@ -27377,7 +26680,7 @@ function decodeSparkAddress(address, network) {
27377
26680
  amount: sparkInvoiceFields.paymentType.satsPayment.amount
27378
26681
  } : void 0 : void 0,
27379
26682
  memo: sparkInvoiceFields.memo,
27380
- senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0, import_utils14.bytesToHex)(sparkInvoiceFields.senderPublicKey) : void 0,
26683
+ senderPublicKey: sparkInvoiceFields.senderPublicKey ? (0, import_utils10.bytesToHex)(sparkInvoiceFields.senderPublicKey) : void 0,
27381
26684
  expiryTime: sparkInvoiceFields.expiryTime
27382
26685
  },
27383
26686
  signature: signatureHex
@@ -27443,7 +26746,7 @@ function isValidSparkAddress(address) {
27443
26746
  }
27444
26747
  function isValidPublicKey(publicKey) {
27445
26748
  try {
27446
- const point = import_secp256k110.secp256k1.Point.fromHex(publicKey);
26749
+ const point = import_secp256k16.secp256k1.Point.fromHex(publicKey);
27447
26750
  point.assertValidity();
27448
26751
  } catch (error) {
27449
26752
  throw new ValidationError(
@@ -27478,7 +26781,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
27478
26781
  }
27479
26782
  if (senderPublicKey) {
27480
26783
  try {
27481
- isValidPublicKey((0, import_utils14.bytesToHex)(senderPublicKey));
26784
+ isValidPublicKey((0, import_utils10.bytesToHex)(senderPublicKey));
27482
26785
  } catch (error) {
27483
26786
  throw new ValidationError(
27484
26787
  "Invalid sender public key",
@@ -27529,7 +26832,7 @@ function validateSparkInvoiceFields(sparkInvoiceFields) {
27529
26832
  value: tokensAmount
27530
26833
  });
27531
26834
  }
27532
- const tokensAmountBigInt = (0, import_utils13.bytesToNumberBE)(tokensAmount);
26835
+ const tokensAmountBigInt = (0, import_utils9.bytesToNumberBE)(tokensAmount);
27533
26836
  if (tokensAmountBigInt < 0 || tokensAmountBigInt > MAX_UINT128) {
27534
26837
  throw new ValidationError(
27535
26838
  "Asset amount must be between 0 and MAX_UINT128",
@@ -27596,10 +26899,10 @@ function validateSparkInvoiceSignature(invoice) {
27596
26899
  identityPublicKey,
27597
26900
  network
27598
26901
  );
27599
- const sec256k1PublicKey = import_secp256k110.secp256k1.Point.fromHex(identityPublicKey);
26902
+ const sec256k1PublicKey = import_secp256k16.secp256k1.Point.fromHex(identityPublicKey);
27600
26903
  const compressed = sec256k1PublicKey.toBytes(true);
27601
26904
  const xOnly = compressed.slice(1);
27602
- const isValid = import_secp256k110.schnorr.verify(signature, hash, xOnly);
26905
+ const isValid = import_secp256k16.schnorr.verify(signature, hash, xOnly);
27603
26906
  if (!isValid) {
27604
26907
  throw new ValidationError("Invalid signature", {
27605
26908
  field: "signature",
@@ -27666,7 +26969,7 @@ function isSafeForNumber(bi) {
27666
26969
 
27667
26970
  // src/utils/token-hashing.ts
27668
26971
  init_buffer();
27669
- var import_sha211 = require("@noble/hashes/sha2");
26972
+ var import_sha210 = require("@noble/hashes/sha2");
27670
26973
  var import_base4 = require("@scure/base");
27671
26974
  function hashTokenTransaction(tokenTransaction, partialHash = false) {
27672
26975
  switch (tokenTransaction.version) {
@@ -27688,7 +26991,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27688
26991
  });
27689
26992
  }
27690
26993
  let allHashes = [];
27691
- const versionHashObj = import_sha211.sha256.create();
26994
+ const versionHashObj = import_sha210.sha256.create();
27692
26995
  const versionBytes = new Uint8Array(4);
27693
26996
  new DataView(versionBytes.buffer).setUint32(
27694
26997
  0,
@@ -27698,7 +27001,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27698
27001
  );
27699
27002
  versionHashObj.update(versionBytes);
27700
27003
  allHashes.push(versionHashObj.digest());
27701
- const typeHashObj = import_sha211.sha256.create();
27004
+ const typeHashObj = import_sha210.sha256.create();
27702
27005
  const typeBytes = new Uint8Array(4);
27703
27006
  let transactionType = 0;
27704
27007
  if (tokenTransaction.tokenInputs?.$case === "mintInput") {
@@ -27729,7 +27032,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27729
27032
  field: "tokenInputs.transferInput.outputsToSpend"
27730
27033
  });
27731
27034
  }
27732
- const outputsLenHashObj2 = import_sha211.sha256.create();
27035
+ const outputsLenHashObj2 = import_sha210.sha256.create();
27733
27036
  const outputsLenBytes2 = new Uint8Array(4);
27734
27037
  new DataView(outputsLenBytes2.buffer).setUint32(
27735
27038
  0,
@@ -27748,7 +27051,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27748
27051
  index: i
27749
27052
  });
27750
27053
  }
27751
- const hashObj2 = import_sha211.sha256.create();
27054
+ const hashObj2 = import_sha210.sha256.create();
27752
27055
  if (output.prevTokenTransactionHash) {
27753
27056
  const prevHash = output.prevTokenTransactionHash;
27754
27057
  if (output.prevTokenTransactionHash.length !== 32) {
@@ -27775,7 +27078,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27775
27078
  allHashes.push(hashObj2.digest());
27776
27079
  }
27777
27080
  } else if (tokenTransaction.tokenInputs?.$case === "mintInput") {
27778
- const hashObj2 = import_sha211.sha256.create();
27081
+ const hashObj2 = import_sha210.sha256.create();
27779
27082
  if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
27780
27083
  const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
27781
27084
  if (issuerPubKey.length === 0) {
@@ -27788,7 +27091,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27788
27091
  }
27789
27092
  hashObj2.update(issuerPubKey);
27790
27093
  allHashes.push(hashObj2.digest());
27791
- const tokenIdentifierHashObj = import_sha211.sha256.create();
27094
+ const tokenIdentifierHashObj = import_sha210.sha256.create();
27792
27095
  if (tokenTransaction.tokenInputs.mintInput.tokenIdentifier) {
27793
27096
  tokenIdentifierHashObj.update(
27794
27097
  tokenTransaction.tokenInputs.mintInput.tokenIdentifier
@@ -27800,7 +27103,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27800
27103
  }
27801
27104
  } else if (tokenTransaction.tokenInputs?.$case === "createInput") {
27802
27105
  const createInput = tokenTransaction.tokenInputs.createInput;
27803
- const issuerPubKeyHashObj = import_sha211.sha256.create();
27106
+ const issuerPubKeyHashObj = import_sha210.sha256.create();
27804
27107
  if (!createInput.issuerPublicKey || createInput.issuerPublicKey.length === 0) {
27805
27108
  throw new ValidationError("issuer public key cannot be nil or empty", {
27806
27109
  field: "tokenInputs.createInput.issuerPublicKey"
@@ -27808,7 +27111,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27808
27111
  }
27809
27112
  issuerPubKeyHashObj.update(createInput.issuerPublicKey);
27810
27113
  allHashes.push(issuerPubKeyHashObj.digest());
27811
- const tokenNameHashObj = import_sha211.sha256.create();
27114
+ const tokenNameHashObj = import_sha210.sha256.create();
27812
27115
  if (!createInput.tokenName || createInput.tokenName.length === 0) {
27813
27116
  throw new ValidationError("token name cannot be empty", {
27814
27117
  field: "tokenInputs.createInput.tokenName"
@@ -27825,7 +27128,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27825
27128
  const tokenNameEncoder = new TextEncoder();
27826
27129
  tokenNameHashObj.update(tokenNameEncoder.encode(createInput.tokenName));
27827
27130
  allHashes.push(tokenNameHashObj.digest());
27828
- const tokenTickerHashObj = import_sha211.sha256.create();
27131
+ const tokenTickerHashObj = import_sha210.sha256.create();
27829
27132
  if (!createInput.tokenTicker || createInput.tokenTicker.length === 0) {
27830
27133
  throw new ValidationError("token ticker cannot be empty", {
27831
27134
  field: "tokenInputs.createInput.tokenTicker"
@@ -27844,7 +27147,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27844
27147
  tokenTickerEncoder.encode(createInput.tokenTicker)
27845
27148
  );
27846
27149
  allHashes.push(tokenTickerHashObj.digest());
27847
- const decimalsHashObj = import_sha211.sha256.create();
27150
+ const decimalsHashObj = import_sha210.sha256.create();
27848
27151
  const decimalsBytes = new Uint8Array(4);
27849
27152
  new DataView(decimalsBytes.buffer).setUint32(
27850
27153
  0,
@@ -27853,7 +27156,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27853
27156
  );
27854
27157
  decimalsHashObj.update(decimalsBytes);
27855
27158
  allHashes.push(decimalsHashObj.digest());
27856
- const maxSupplyHashObj = import_sha211.sha256.create();
27159
+ const maxSupplyHashObj = import_sha210.sha256.create();
27857
27160
  if (!createInput.maxSupply) {
27858
27161
  throw new ValidationError("max supply cannot be nil", {
27859
27162
  field: "tokenInputs.createInput.maxSupply"
@@ -27869,12 +27172,12 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27869
27172
  }
27870
27173
  maxSupplyHashObj.update(createInput.maxSupply);
27871
27174
  allHashes.push(maxSupplyHashObj.digest());
27872
- const isFreezableHashObj = import_sha211.sha256.create();
27175
+ const isFreezableHashObj = import_sha210.sha256.create();
27873
27176
  isFreezableHashObj.update(
27874
27177
  new Uint8Array([createInput.isFreezable ? 1 : 0])
27875
27178
  );
27876
27179
  allHashes.push(isFreezableHashObj.digest());
27877
- const creationEntityHashObj = import_sha211.sha256.create();
27180
+ const creationEntityHashObj = import_sha210.sha256.create();
27878
27181
  if (!partialHash && createInput.creationEntityPublicKey) {
27879
27182
  creationEntityHashObj.update(createInput.creationEntityPublicKey);
27880
27183
  }
@@ -27885,7 +27188,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27885
27188
  field: "tokenOutputs"
27886
27189
  });
27887
27190
  }
27888
- const outputsLenHashObj = import_sha211.sha256.create();
27191
+ const outputsLenHashObj = import_sha210.sha256.create();
27889
27192
  const outputsLenBytes = new Uint8Array(4);
27890
27193
  new DataView(outputsLenBytes.buffer).setUint32(
27891
27194
  0,
@@ -27901,7 +27204,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
27901
27204
  index: i
27902
27205
  });
27903
27206
  }
27904
- const hashObj2 = import_sha211.sha256.create();
27207
+ const hashObj2 = import_sha210.sha256.create();
27905
27208
  if (output.id && !partialHash) {
27906
27209
  if (output.id.length === 0) {
27907
27210
  throw new ValidationError(`output ID at index ${i} cannot be empty`, {
@@ -28002,7 +27305,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
28002
27305
  }
28003
27306
  return a.length - b.length;
28004
27307
  });
28005
- const operatorLenHashObj = import_sha211.sha256.create();
27308
+ const operatorLenHashObj = import_sha210.sha256.create();
28006
27309
  const operatorLenBytes = new Uint8Array(4);
28007
27310
  new DataView(operatorLenBytes.buffer).setUint32(
28008
27311
  0,
@@ -28030,11 +27333,11 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
28030
27333
  }
28031
27334
  );
28032
27335
  }
28033
- const hashObj2 = import_sha211.sha256.create();
27336
+ const hashObj2 = import_sha210.sha256.create();
28034
27337
  hashObj2.update(pubKey);
28035
27338
  allHashes.push(hashObj2.digest());
28036
27339
  }
28037
- const hashObj = import_sha211.sha256.create();
27340
+ const hashObj = import_sha210.sha256.create();
28038
27341
  let networkBytes = new Uint8Array(4);
28039
27342
  new DataView(networkBytes.buffer).setUint32(
28040
27343
  0,
@@ -28044,7 +27347,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
28044
27347
  );
28045
27348
  hashObj.update(networkBytes);
28046
27349
  allHashes.push(hashObj.digest());
28047
- const clientTimestampHashObj = import_sha211.sha256.create();
27350
+ const clientTimestampHashObj = import_sha210.sha256.create();
28048
27351
  const clientCreatedTs = tokenTransaction.clientCreatedTimestamp;
28049
27352
  if (!clientCreatedTs) {
28050
27353
  throw new ValidationError(
@@ -28064,7 +27367,7 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
28064
27367
  clientTimestampHashObj.update(clientTimestampBytes);
28065
27368
  allHashes.push(clientTimestampHashObj.digest());
28066
27369
  if (!partialHash) {
28067
- const expiryHashObj = import_sha211.sha256.create();
27370
+ const expiryHashObj = import_sha210.sha256.create();
28068
27371
  const expiryTimeBytes = new Uint8Array(8);
28069
27372
  const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
28070
27373
  new DataView(expiryTimeBytes.buffer).setBigUint64(
@@ -28076,9 +27379,9 @@ function hashTokenTransactionV1(tokenTransaction, partialHash = false) {
28076
27379
  expiryHashObj.update(expiryTimeBytes);
28077
27380
  allHashes.push(expiryHashObj.digest());
28078
27381
  }
28079
- const finalHashObj = import_sha211.sha256.create();
27382
+ const finalHashObj = import_sha210.sha256.create();
28080
27383
  const concatenatedHashes = new Uint8Array(
28081
- allHashes.reduce((sum, hash) => sum + hash.length, 0)
27384
+ allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
28082
27385
  );
28083
27386
  let offset = 0;
28084
27387
  for (const hash of allHashes) {
@@ -28095,7 +27398,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28095
27398
  });
28096
27399
  }
28097
27400
  let allHashes = [];
28098
- const versionHashObj = import_sha211.sha256.create();
27401
+ const versionHashObj = import_sha210.sha256.create();
28099
27402
  const versionBytes = new Uint8Array(4);
28100
27403
  new DataView(versionBytes.buffer).setUint32(
28101
27404
  0,
@@ -28105,7 +27408,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28105
27408
  );
28106
27409
  versionHashObj.update(versionBytes);
28107
27410
  allHashes.push(versionHashObj.digest());
28108
- const typeHashObj = import_sha211.sha256.create();
27411
+ const typeHashObj = import_sha210.sha256.create();
28109
27412
  const typeBytes = new Uint8Array(4);
28110
27413
  let transactionType = 0;
28111
27414
  if (tokenTransaction.tokenInputs?.$case === "mintInput") {
@@ -28136,7 +27439,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28136
27439
  field: "tokenInputs.transferInput.outputsToSpend"
28137
27440
  });
28138
27441
  }
28139
- const outputsLenHashObj2 = import_sha211.sha256.create();
27442
+ const outputsLenHashObj2 = import_sha210.sha256.create();
28140
27443
  const outputsLenBytes2 = new Uint8Array(4);
28141
27444
  new DataView(outputsLenBytes2.buffer).setUint32(
28142
27445
  0,
@@ -28155,7 +27458,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28155
27458
  index: i
28156
27459
  });
28157
27460
  }
28158
- const hashObj2 = import_sha211.sha256.create();
27461
+ const hashObj2 = import_sha210.sha256.create();
28159
27462
  if (output.prevTokenTransactionHash) {
28160
27463
  const prevHash = output.prevTokenTransactionHash;
28161
27464
  if (output.prevTokenTransactionHash.length !== 32) {
@@ -28182,7 +27485,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28182
27485
  allHashes.push(hashObj2.digest());
28183
27486
  }
28184
27487
  } else if (tokenTransaction.tokenInputs?.$case === "mintInput") {
28185
- const hashObj2 = import_sha211.sha256.create();
27488
+ const hashObj2 = import_sha210.sha256.create();
28186
27489
  if (tokenTransaction.tokenInputs.mintInput.issuerPublicKey) {
28187
27490
  const issuerPubKey = tokenTransaction.tokenInputs.mintInput.issuerPublicKey;
28188
27491
  if (issuerPubKey.length === 0) {
@@ -28195,7 +27498,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28195
27498
  }
28196
27499
  hashObj2.update(issuerPubKey);
28197
27500
  allHashes.push(hashObj2.digest());
28198
- const tokenIdentifierHashObj = import_sha211.sha256.create();
27501
+ const tokenIdentifierHashObj = import_sha210.sha256.create();
28199
27502
  if (tokenTransaction.tokenInputs.mintInput.tokenIdentifier) {
28200
27503
  tokenIdentifierHashObj.update(
28201
27504
  tokenTransaction.tokenInputs.mintInput.tokenIdentifier
@@ -28207,7 +27510,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28207
27510
  }
28208
27511
  } else if (tokenTransaction.tokenInputs?.$case === "createInput") {
28209
27512
  const createInput = tokenTransaction.tokenInputs.createInput;
28210
- const issuerPubKeyHashObj = import_sha211.sha256.create();
27513
+ const issuerPubKeyHashObj = import_sha210.sha256.create();
28211
27514
  if (!createInput.issuerPublicKey || createInput.issuerPublicKey.length === 0) {
28212
27515
  throw new ValidationError("issuer public key cannot be nil or empty", {
28213
27516
  field: "tokenInputs.createInput.issuerPublicKey"
@@ -28215,7 +27518,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28215
27518
  }
28216
27519
  issuerPubKeyHashObj.update(createInput.issuerPublicKey);
28217
27520
  allHashes.push(issuerPubKeyHashObj.digest());
28218
- const tokenNameHashObj = import_sha211.sha256.create();
27521
+ const tokenNameHashObj = import_sha210.sha256.create();
28219
27522
  if (!createInput.tokenName || createInput.tokenName.length === 0) {
28220
27523
  throw new ValidationError("token name cannot be empty", {
28221
27524
  field: "tokenInputs.createInput.tokenName"
@@ -28232,7 +27535,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28232
27535
  const tokenNameEncoder = new TextEncoder();
28233
27536
  tokenNameHashObj.update(tokenNameEncoder.encode(createInput.tokenName));
28234
27537
  allHashes.push(tokenNameHashObj.digest());
28235
- const tokenTickerHashObj = import_sha211.sha256.create();
27538
+ const tokenTickerHashObj = import_sha210.sha256.create();
28236
27539
  if (!createInput.tokenTicker || createInput.tokenTicker.length === 0) {
28237
27540
  throw new ValidationError("token ticker cannot be empty", {
28238
27541
  field: "tokenInputs.createInput.tokenTicker"
@@ -28251,7 +27554,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28251
27554
  tokenTickerEncoder.encode(createInput.tokenTicker)
28252
27555
  );
28253
27556
  allHashes.push(tokenTickerHashObj.digest());
28254
- const decimalsHashObj = import_sha211.sha256.create();
27557
+ const decimalsHashObj = import_sha210.sha256.create();
28255
27558
  const decimalsBytes = new Uint8Array(4);
28256
27559
  new DataView(decimalsBytes.buffer).setUint32(
28257
27560
  0,
@@ -28260,7 +27563,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28260
27563
  );
28261
27564
  decimalsHashObj.update(decimalsBytes);
28262
27565
  allHashes.push(decimalsHashObj.digest());
28263
- const maxSupplyHashObj = import_sha211.sha256.create();
27566
+ const maxSupplyHashObj = import_sha210.sha256.create();
28264
27567
  if (!createInput.maxSupply) {
28265
27568
  throw new ValidationError("max supply cannot be nil", {
28266
27569
  field: "tokenInputs.createInput.maxSupply"
@@ -28276,12 +27579,12 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28276
27579
  }
28277
27580
  maxSupplyHashObj.update(createInput.maxSupply);
28278
27581
  allHashes.push(maxSupplyHashObj.digest());
28279
- const isFreezableHashObj = import_sha211.sha256.create();
27582
+ const isFreezableHashObj = import_sha210.sha256.create();
28280
27583
  isFreezableHashObj.update(
28281
27584
  new Uint8Array([createInput.isFreezable ? 1 : 0])
28282
27585
  );
28283
27586
  allHashes.push(isFreezableHashObj.digest());
28284
- const creationEntityHashObj = import_sha211.sha256.create();
27587
+ const creationEntityHashObj = import_sha210.sha256.create();
28285
27588
  if (!partialHash && createInput.creationEntityPublicKey) {
28286
27589
  creationEntityHashObj.update(createInput.creationEntityPublicKey);
28287
27590
  }
@@ -28292,7 +27595,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28292
27595
  field: "tokenOutputs"
28293
27596
  });
28294
27597
  }
28295
- const outputsLenHashObj = import_sha211.sha256.create();
27598
+ const outputsLenHashObj = import_sha210.sha256.create();
28296
27599
  const outputsLenBytes = new Uint8Array(4);
28297
27600
  new DataView(outputsLenBytes.buffer).setUint32(
28298
27601
  0,
@@ -28308,7 +27611,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28308
27611
  index: i
28309
27612
  });
28310
27613
  }
28311
- const hashObj2 = import_sha211.sha256.create();
27614
+ const hashObj2 = import_sha210.sha256.create();
28312
27615
  if (output.id && !partialHash) {
28313
27616
  if (output.id.length === 0) {
28314
27617
  throw new ValidationError(`output ID at index ${i} cannot be empty`, {
@@ -28409,7 +27712,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28409
27712
  }
28410
27713
  return a.length - b.length;
28411
27714
  });
28412
- const operatorLenHashObj = import_sha211.sha256.create();
27715
+ const operatorLenHashObj = import_sha210.sha256.create();
28413
27716
  const operatorLenBytes = new Uint8Array(4);
28414
27717
  new DataView(operatorLenBytes.buffer).setUint32(
28415
27718
  0,
@@ -28437,11 +27740,11 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28437
27740
  }
28438
27741
  );
28439
27742
  }
28440
- const hashObj2 = import_sha211.sha256.create();
27743
+ const hashObj2 = import_sha210.sha256.create();
28441
27744
  hashObj2.update(pubKey);
28442
27745
  allHashes.push(hashObj2.digest());
28443
27746
  }
28444
- const hashObj = import_sha211.sha256.create();
27747
+ const hashObj = import_sha210.sha256.create();
28445
27748
  let networkBytes = new Uint8Array(4);
28446
27749
  new DataView(networkBytes.buffer).setUint32(
28447
27750
  0,
@@ -28451,7 +27754,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28451
27754
  );
28452
27755
  hashObj.update(networkBytes);
28453
27756
  allHashes.push(hashObj.digest());
28454
- const clientTimestampHashObj = import_sha211.sha256.create();
27757
+ const clientTimestampHashObj = import_sha210.sha256.create();
28455
27758
  const clientCreatedTs = tokenTransaction.clientCreatedTimestamp;
28456
27759
  if (!clientCreatedTs) {
28457
27760
  throw new ValidationError(
@@ -28471,7 +27774,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28471
27774
  clientTimestampHashObj.update(clientTimestampBytes);
28472
27775
  allHashes.push(clientTimestampHashObj.digest());
28473
27776
  if (!partialHash) {
28474
- const expiryHashObj = import_sha211.sha256.create();
27777
+ const expiryHashObj = import_sha210.sha256.create();
28475
27778
  const expiryTimeBytes = new Uint8Array(8);
28476
27779
  const expiryUnixTime = tokenTransaction.expiryTime ? Math.floor(tokenTransaction.expiryTime.getTime() / 1e3) : 0;
28477
27780
  new DataView(expiryTimeBytes.buffer).setBigUint64(
@@ -28484,7 +27787,7 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28484
27787
  allHashes.push(expiryHashObj.digest());
28485
27788
  }
28486
27789
  const attachments = tokenTransaction.invoiceAttachments;
28487
- const lenHash = import_sha211.sha256.create();
27790
+ const lenHash = import_sha210.sha256.create();
28488
27791
  const lenBytes = new Uint8Array(4);
28489
27792
  new DataView(lenBytes.buffer).setUint32(
28490
27793
  0,
@@ -28545,13 +27848,13 @@ function hashTokenTransactionV2(tokenTransaction, partialHash = false) {
28545
27848
  });
28546
27849
  const encoder = new TextEncoder();
28547
27850
  for (const k of sortedInvoices) {
28548
- const h = import_sha211.sha256.create();
27851
+ const h = import_sha210.sha256.create();
28549
27852
  h.update(encoder.encode(k.raw));
28550
27853
  allHashes.push(h.digest());
28551
27854
  }
28552
- const finalHashObj = import_sha211.sha256.create();
27855
+ const finalHashObj = import_sha210.sha256.create();
28553
27856
  const concatenatedHashes = new Uint8Array(
28554
- allHashes.reduce((sum, hash) => sum + hash.length, 0)
27857
+ allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
28555
27858
  );
28556
27859
  let offset = 0;
28557
27860
  for (const hash of allHashes) {
@@ -28572,7 +27875,7 @@ function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
28572
27875
  }
28573
27876
  let allHashes = [];
28574
27877
  if (payload.finalTokenTransactionHash) {
28575
- const hashObj2 = import_sha211.sha256.create();
27878
+ const hashObj2 = import_sha210.sha256.create();
28576
27879
  if (payload.finalTokenTransactionHash.length !== 32) {
28577
27880
  throw new ValidationError(`invalid final token transaction hash length`, {
28578
27881
  field: "finalTokenTransactionHash",
@@ -28594,12 +27897,12 @@ function hashOperatorSpecificTokenTransactionSignablePayload(payload) {
28594
27897
  field: "operatorIdentityPublicKey"
28595
27898
  });
28596
27899
  }
28597
- const hashObj = import_sha211.sha256.create();
27900
+ const hashObj = import_sha210.sha256.create();
28598
27901
  hashObj.update(payload.operatorIdentityPublicKey);
28599
27902
  allHashes.push(hashObj.digest());
28600
- const finalHashObj = import_sha211.sha256.create();
27903
+ const finalHashObj = import_sha210.sha256.create();
28601
27904
  const concatenatedHashes = new Uint8Array(
28602
- allHashes.reduce((sum, hash) => sum + hash.length, 0)
27905
+ allHashes.reduce((sum2, hash) => sum2 + hash.length, 0)
28603
27906
  );
28604
27907
  let offset = 0;
28605
27908
  for (const hash of allHashes) {
@@ -29002,11 +28305,11 @@ function validateTokenTransaction(finalTokenTransaction, partialTokenTransaction
29002
28305
 
29003
28306
  // src/utils/token-transactions.ts
29004
28307
  init_buffer();
29005
- var import_utils15 = require("@noble/curves/utils");
28308
+ var import_utils11 = require("@noble/curves/utils");
29006
28309
  function sumAvailableTokens(outputs) {
29007
28310
  try {
29008
28311
  return outputs.reduce(
29009
- (sum, output) => sum + BigInt((0, import_utils15.bytesToNumberBE)(output.output.tokenAmount)),
28312
+ (sum2, output) => sum2 + BigInt((0, import_utils11.bytesToNumberBE)(output.output.tokenAmount)),
29010
28313
  BigInt(0)
29011
28314
  );
29012
28315
  } catch (error) {
@@ -29037,7 +28340,7 @@ function filterTokenBalanceForTokenIdentifier(tokenBalances, tokenIdentifier) {
29037
28340
  }
29038
28341
  const tokenIdentifierBytes = decodeBech32mTokenIdentifier(tokenIdentifier).tokenIdentifier;
29039
28342
  const tokenBalance = [...tokenBalances.entries()].find(
29040
- ([, info]) => (0, import_utils15.equalBytes)(info.tokenMetadata.rawTokenIdentifier, tokenIdentifierBytes)
28343
+ ([, info]) => (0, import_utils11.equalBytes)(info.tokenMetadata.rawTokenIdentifier, tokenIdentifierBytes)
29041
28344
  );
29042
28345
  if (!tokenBalance) {
29043
28346
  return {
@@ -29073,7 +28376,7 @@ var TokenTransactionService = class {
29073
28376
  });
29074
28377
  }
29075
28378
  const totalTokenAmount = receiverOutputs.reduce(
29076
- (sum, transfer) => sum + transfer.tokenAmount,
28379
+ (sum2, transfer) => sum2 + transfer.tokenAmount,
29077
28380
  0n
29078
28381
  );
29079
28382
  let outputsToUse;
@@ -29131,14 +28434,14 @@ var TokenTransactionService = class {
29131
28434
  }
29132
28435
  if (receiverAddress.sparkInvoiceFields) {
29133
28436
  return {
29134
- receiverPublicKey: (0, import_utils17.hexToBytes)(receiverAddress.identityPublicKey),
28437
+ receiverPublicKey: (0, import_utils13.hexToBytes)(receiverAddress.identityPublicKey),
29135
28438
  rawTokenIdentifier,
29136
28439
  tokenAmount: transfer.tokenAmount,
29137
28440
  sparkInvoice: transfer.receiverSparkAddress
29138
28441
  };
29139
28442
  }
29140
28443
  return {
29141
- receiverPublicKey: (0, import_utils17.hexToBytes)(receiverAddress.identityPublicKey),
28444
+ receiverPublicKey: (0, import_utils13.hexToBytes)(receiverAddress.identityPublicKey),
29142
28445
  rawTokenIdentifier,
29143
28446
  tokenAmount: transfer.tokenAmount
29144
28447
  };
@@ -29161,14 +28464,14 @@ var TokenTransactionService = class {
29161
28464
  );
29162
28465
  const availableTokenAmount = sumAvailableTokens(selectedOutputs);
29163
28466
  const totalRequestedAmount = tokenOutputData.reduce(
29164
- (sum, output) => sum + output.tokenAmount,
28467
+ (sum2, output) => sum2 + output.tokenAmount,
29165
28468
  0n
29166
28469
  );
29167
28470
  const tokenOutputs = tokenOutputData.map(
29168
28471
  (output) => ({
29169
28472
  ownerPublicKey: output.receiverPublicKey,
29170
28473
  tokenIdentifier: output.rawTokenIdentifier,
29171
- tokenAmount: (0, import_utils16.numberToBytesBE)(output.tokenAmount, 16)
28474
+ tokenAmount: (0, import_utils12.numberToBytesBE)(output.tokenAmount, 16)
29172
28475
  })
29173
28476
  );
29174
28477
  if (availableTokenAmount > totalRequestedAmount) {
@@ -29177,7 +28480,7 @@ var TokenTransactionService = class {
29177
28480
  tokenOutputs.push({
29178
28481
  ownerPublicKey: await this.config.signer.getIdentityPublicKey(),
29179
28482
  tokenIdentifier: firstTokenIdentifierBytes,
29180
- tokenAmount: (0, import_utils16.numberToBytesBE)(changeAmount, 16)
28483
+ tokenAmount: (0, import_utils12.numberToBytesBE)(changeAmount, 16)
29181
28484
  });
29182
28485
  }
29183
28486
  return {
@@ -29204,7 +28507,7 @@ var TokenTransactionService = class {
29204
28507
  for (const [_, operator] of Object.entries(
29205
28508
  this.config.getSigningOperators()
29206
28509
  )) {
29207
- operatorKeys.push((0, import_utils17.hexToBytes)(operator.identityPublicKey));
28510
+ operatorKeys.push((0, import_utils13.hexToBytes)(operator.identityPublicKey));
29208
28511
  }
29209
28512
  return operatorKeys;
29210
28513
  }
@@ -29221,7 +28524,7 @@ var TokenTransactionService = class {
29221
28524
  finalTokenTransactionHash,
29222
28525
  signingOperators
29223
28526
  );
29224
- return (0, import_utils16.bytesToHex)(finalTokenTransactionHash);
28527
+ return (0, import_utils12.bytesToHex)(finalTokenTransactionHash);
29225
28528
  }
29226
28529
  async startTokenTransaction(tokenTransaction, signingOperators, outputsToSpendSigningPublicKeys, outputsToSpendCommitments) {
29227
28530
  const sparkClient = await this.connectionManager.createSparkTokenClient(
@@ -29396,10 +28699,10 @@ var TokenTransactionService = class {
29396
28699
  });
29397
28700
  }
29398
28701
  for (const ownerPublicKey of ownerPublicKeys) {
29399
- isValidPublicKey((0, import_utils16.bytesToHex)(ownerPublicKey));
28702
+ isValidPublicKey((0, import_utils12.bytesToHex)(ownerPublicKey));
29400
28703
  }
29401
28704
  for (const issuerPublicKey of issuerPublicKeys) {
29402
- isValidPublicKey((0, import_utils16.bytesToHex)(issuerPublicKey));
28705
+ isValidPublicKey((0, import_utils12.bytesToHex)(issuerPublicKey));
29403
28706
  }
29404
28707
  for (const tokenIdentifier of tokenIdentifiers) {
29405
28708
  if (tokenIdentifier.length !== 32) {
@@ -29467,8 +28770,8 @@ var TokenTransactionService = class {
29467
28770
  this.config.getCoordinatorAddress()
29468
28771
  );
29469
28772
  let queryParams = {
29470
- issuerPublicKeys: issuerPublicKeys?.map(import_utils17.hexToBytes),
29471
- ownerPublicKeys: ownerPublicKeys?.map(import_utils17.hexToBytes),
28773
+ issuerPublicKeys: issuerPublicKeys?.map(import_utils13.hexToBytes),
28774
+ ownerPublicKeys: ownerPublicKeys?.map(import_utils13.hexToBytes),
29472
28775
  tokenIdentifiers: tokenIdentifiers?.map((identifier) => {
29473
28776
  const { tokenIdentifier } = decodeBech32mTokenIdentifier(
29474
28777
  identifier,
@@ -29476,7 +28779,7 @@ var TokenTransactionService = class {
29476
28779
  );
29477
28780
  return tokenIdentifier;
29478
28781
  }),
29479
- tokenTransactionHashes: tokenTransactionHashes?.map(import_utils17.hexToBytes),
28782
+ tokenTransactionHashes: tokenTransactionHashes?.map(import_utils13.hexToBytes),
29480
28783
  outputIds: outputIds || [],
29481
28784
  limit: pageSize,
29482
28785
  offset
@@ -29511,7 +28814,7 @@ var TokenTransactionService = class {
29511
28814
  });
29512
28815
  }
29513
28816
  const exactMatch = tokenOutputs.find(
29514
- (item) => (0, import_utils16.bytesToNumberBE)(item.output.tokenAmount) === tokenAmount
28817
+ (item) => (0, import_utils12.bytesToNumberBE)(item.output.tokenAmount) === tokenAmount
29515
28818
  );
29516
28819
  if (exactMatch) {
29517
28820
  return [exactMatch];
@@ -29522,7 +28825,7 @@ var TokenTransactionService = class {
29522
28825
  for (const outputWithPreviousTransactionData of tokenOutputs) {
29523
28826
  if (remainingAmount <= 0n) break;
29524
28827
  selectedOutputs.push(outputWithPreviousTransactionData);
29525
- remainingAmount -= (0, import_utils16.bytesToNumberBE)(
28828
+ remainingAmount -= (0, import_utils12.bytesToNumberBE)(
29526
28829
  outputWithPreviousTransactionData.output.tokenAmount
29527
28830
  );
29528
28831
  }
@@ -29537,22 +28840,22 @@ var TokenTransactionService = class {
29537
28840
  sortTokenOutputsByStrategy(tokenOutputs, strategy) {
29538
28841
  if (strategy === "SMALL_FIRST") {
29539
28842
  tokenOutputs.sort((a, b) => {
29540
- return Number(
29541
- (0, import_utils16.bytesToNumberBE)(a.output.tokenAmount) - (0, import_utils16.bytesToNumberBE)(b.output.tokenAmount)
29542
- );
28843
+ const amountA = (0, import_utils12.bytesToNumberBE)(a.output.tokenAmount);
28844
+ const amountB = (0, import_utils12.bytesToNumberBE)(b.output.tokenAmount);
28845
+ return amountA < amountB ? -1 : amountA > amountB ? 1 : 0;
29543
28846
  });
29544
28847
  } else {
29545
28848
  tokenOutputs.sort((a, b) => {
29546
- return Number(
29547
- (0, import_utils16.bytesToNumberBE)(b.output.tokenAmount) - (0, import_utils16.bytesToNumberBE)(a.output.tokenAmount)
29548
- );
28849
+ const amountA = (0, import_utils12.bytesToNumberBE)(a.output.tokenAmount);
28850
+ const amountB = (0, import_utils12.bytesToNumberBE)(b.output.tokenAmount);
28851
+ return amountB < amountA ? -1 : amountB > amountA ? 1 : 0;
29549
28852
  });
29550
28853
  }
29551
28854
  }
29552
28855
  // Helper function for deciding if the signer public key is the identity public key
29553
28856
  async signMessageWithKey(message, publicKey) {
29554
28857
  const tokenSignatures = this.config.getTokenSignatures();
29555
- if ((0, import_utils16.bytesToHex)(publicKey) === (0, import_utils16.bytesToHex)(await this.config.signer.getIdentityPublicKey())) {
28858
+ if ((0, import_utils12.bytesToHex)(publicKey) === (0, import_utils12.bytesToHex)(await this.config.signer.getIdentityPublicKey())) {
29556
28859
  if (tokenSignatures === "SCHNORR") {
29557
28860
  return await this.config.signer.signSchnorrWithIdentityKey(message);
29558
28861
  } else {
@@ -29561,8 +28864,8 @@ var TokenTransactionService = class {
29561
28864
  } else {
29562
28865
  throw new ValidationError("Invalid public key", {
29563
28866
  field: "publicKey",
29564
- value: (0, import_utils16.bytesToHex)(publicKey),
29565
- expected: (0, import_utils16.bytesToHex)(await this.config.signer.getIdentityPublicKey())
28867
+ value: (0, import_utils12.bytesToHex)(publicKey),
28868
+ expected: (0, import_utils12.bytesToHex)(await this.config.signer.getIdentityPublicKey())
29566
28869
  });
29567
28870
  }
29568
28871
  }
@@ -29581,7 +28884,7 @@ var TokenTransactionService = class {
29581
28884
  }
29582
28885
  const payload = {
29583
28886
  finalTokenTransactionHash,
29584
- operatorIdentityPublicKey: (0, import_utils17.hexToBytes)(operator.identityPublicKey)
28887
+ operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
29585
28888
  };
29586
28889
  const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
29587
28890
  const ownerSignature = await this.signMessageWithKey(
@@ -29603,7 +28906,7 @@ var TokenTransactionService = class {
29603
28906
  }
29604
28907
  const payload = {
29605
28908
  finalTokenTransactionHash,
29606
- operatorIdentityPublicKey: (0, import_utils17.hexToBytes)(operator.identityPublicKey)
28909
+ operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
29607
28910
  };
29608
28911
  const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
29609
28912
  const ownerSignature = await this.signMessageWithKey(
@@ -29619,7 +28922,7 @@ var TokenTransactionService = class {
29619
28922
  for (let i = 0; i < transferInput.outputsToSpend.length; i++) {
29620
28923
  const payload = {
29621
28924
  finalTokenTransactionHash,
29622
- operatorIdentityPublicKey: (0, import_utils17.hexToBytes)(operator.identityPublicKey)
28925
+ operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
29623
28926
  };
29624
28927
  const payloadHash = await hashOperatorSpecificTokenTransactionSignablePayload(payload);
29625
28928
  let ownerSignature;
@@ -29636,315 +28939,1020 @@ var TokenTransactionService = class {
29636
28939
  }
29637
28940
  inputTtxoSignaturesPerOperator.push({
29638
28941
  ttxoSignatures,
29639
- operatorIdentityPublicKey: (0, import_utils17.hexToBytes)(operator.identityPublicKey)
28942
+ operatorIdentityPublicKey: (0, import_utils13.hexToBytes)(operator.identityPublicKey)
28943
+ });
28944
+ }
28945
+ return inputTtxoSignaturesPerOperator;
28946
+ }
28947
+ };
28948
+
28949
+ // src/utils/adaptor-signature.ts
28950
+ init_buffer();
28951
+ var import_modular = require("@noble/curves/abstract/modular");
28952
+ var import_secp256k17 = require("@noble/curves/secp256k1");
28953
+ var import_utils14 = require("@noble/curves/utils");
28954
+ function generateSignatureFromExistingAdaptor(signature, adaptorPrivateKeyBytes) {
28955
+ const { r, s: s2 } = parseSignature(signature);
28956
+ const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
28957
+ const tBigInt = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKeyBytes);
28958
+ const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
28959
+ const newSignature = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
28960
+ return newSignature;
28961
+ }
28962
+ function generateAdaptorFromSignature(signature) {
28963
+ const adaptorPrivateKey = import_secp256k17.secp256k1.utils.randomPrivateKey();
28964
+ const { r, s: s2 } = parseSignature(signature);
28965
+ const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
28966
+ const tBigInt = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKey);
28967
+ const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k17.secp256k1.CURVE.n);
28968
+ const newSignature = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
28969
+ return {
28970
+ adaptorSignature: newSignature,
28971
+ adaptorPrivateKey
28972
+ };
28973
+ }
28974
+ function validateOutboundAdaptorSignature(pubkey, hash, signature, adaptorPubkey) {
28975
+ return schnorrVerifyWithAdaptor(
28976
+ signature,
28977
+ hash,
28978
+ pubkey,
28979
+ adaptorPubkey,
28980
+ false
28981
+ );
28982
+ }
28983
+ function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes) {
28984
+ const { r, s: s2 } = parseSignature(signature);
28985
+ const sBigInt = (0, import_utils14.bytesToNumberBE)(s2);
28986
+ const adaptorPrivateKey = (0, import_utils14.bytesToNumberBE)(adaptorPrivateKeyBytes);
28987
+ const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
28988
+ const newSig = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(newS, 32)]);
28989
+ try {
28990
+ if (import_secp256k17.schnorr.verify(newSig, hash, pubkey)) {
28991
+ return newSig;
28992
+ }
28993
+ } catch (e) {
28994
+ console.error("[applyAdaptorToSignature] Addition verification failed:", e);
28995
+ }
28996
+ const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k17.secp256k1.CURVE.n);
28997
+ const altSig = new Uint8Array([...r, ...(0, import_utils14.numberToBytesBE)(altS, 32)]);
28998
+ try {
28999
+ if (import_secp256k17.schnorr.verify(altSig, hash, pubkey)) {
29000
+ return altSig;
29001
+ }
29002
+ } catch (e) {
29003
+ console.error(
29004
+ "[applyAdaptorToSignature] Subtraction verification failed:",
29005
+ e
29006
+ );
29007
+ }
29008
+ throw new Error("Cannot apply adaptor to signature");
29009
+ }
29010
+ function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, inbound) {
29011
+ if (hash.length !== 32) {
29012
+ throw new Error(`wrong size for message (got ${hash.length}, want 32)`);
29013
+ }
29014
+ const pubKey = import_secp256k17.schnorr.utils.lift_x((0, import_utils14.bytesToNumberBE)(pubKeyBytes));
29015
+ pubKey.assertValidity();
29016
+ const { r, s: s2 } = parseSignature(signature);
29017
+ const commitmenet = import_secp256k17.schnorr.utils.taggedHash(
29018
+ "BIP0340/challenge",
29019
+ r,
29020
+ pubKey.toBytes().slice(1),
29021
+ hash
29022
+ );
29023
+ if (commitmenet.length > 32) {
29024
+ throw new Error("hash of (r || P || m) too big");
29025
+ }
29026
+ const e = (0, import_modular.mod)((0, import_utils14.bytesToNumberBE)(commitmenet), import_secp256k17.secp256k1.CURVE.n);
29027
+ const negE = (0, import_modular.mod)(-e, import_secp256k17.secp256k1.CURVE.n);
29028
+ const sG = import_secp256k17.secp256k1.Point.BASE.multiplyUnsafe((0, import_utils14.bytesToNumberBE)(s2));
29029
+ const eP = pubKey.multiplyUnsafe(negE);
29030
+ const R = sG.add(eP);
29031
+ if (R.is0()) {
29032
+ throw new Error("R is zero");
29033
+ }
29034
+ R.assertValidity();
29035
+ const adaptorPoint = import_secp256k17.secp256k1.Point.fromHex(adaptorPubkey);
29036
+ const newR = R.add(adaptorPoint);
29037
+ if (!inbound && newR.equals(import_secp256k17.secp256k1.Point.ZERO)) {
29038
+ throw new Error("calculated R point is the point at infinity");
29039
+ }
29040
+ newR.assertValidity();
29041
+ if (newR.y % 2n !== 0n) {
29042
+ throw new Error("calculated R y-value is odd");
29043
+ }
29044
+ const rNum = (0, import_utils14.bytesToNumberBE)(r);
29045
+ if (newR.toAffine().x !== rNum) {
29046
+ throw new Error("calculated R point was not given R");
29047
+ }
29048
+ return true;
29049
+ }
29050
+ function parseSignature(signature) {
29051
+ if (signature.length < 64) {
29052
+ throw new ValidationError("Signature too short", {
29053
+ expectedLength: 64,
29054
+ actualLength: signature.length
29055
+ });
29056
+ }
29057
+ if (signature.length > 64) {
29058
+ throw new ValidationError("Signature too long", {
29059
+ expectedLength: 64,
29060
+ actualLength: signature.length
29061
+ });
29062
+ }
29063
+ const r = signature.slice(0, 32);
29064
+ const s2 = signature.slice(32, 64);
29065
+ if ((0, import_utils14.bytesToNumberBE)(r) >= import_secp256k17.secp256k1.CURVE.Fp.ORDER) {
29066
+ throw new ValidationError("Invalid signature: r >= field prime", {
29067
+ rValue: (0, import_utils14.bytesToNumberBE)(r),
29068
+ fieldPrime: import_secp256k17.secp256k1.CURVE.Fp.ORDER
29069
+ });
29070
+ }
29071
+ if ((0, import_utils14.bytesToNumberBE)(s2) >= import_secp256k17.secp256k1.CURVE.n) {
29072
+ throw new ValidationError("Invalid signature: s >= group order", {
29073
+ sValue: (0, import_utils14.bytesToNumberBE)(s2),
29074
+ groupOrder: import_secp256k17.secp256k1.CURVE.n
29075
+ });
29076
+ }
29077
+ return { r, s: s2 };
29078
+ }
29079
+
29080
+ // src/spark-wallet/spark-wallet.ts
29081
+ var import_sha212 = require("@noble/hashes/sha2");
29082
+ var import_api = require("@opentelemetry/api");
29083
+ var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
29084
+ var import_eventemitter3 = require("eventemitter3");
29085
+ var import_nice_grpc_common = require("nice-grpc-common");
29086
+
29087
+ // src/constants.ts
29088
+ init_buffer();
29089
+ var import_core11 = require("@lightsparkdev/core");
29090
+ var isReactNative = "navigator" in globalThis && navigator.product === "ReactNative";
29091
+ var isBun = "Bun" in globalThis;
29092
+ var isWebExtension = (
29093
+ /* globalThis.chrome actually exists in extension contexts for all browsers for legacy reasons: */
29094
+ "chrome" in globalThis && globalThis.chrome.runtime?.id
29095
+ );
29096
+ var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
29097
+ var packageVersion = true ? "0.3.7" : "unknown";
29098
+ var baseEnvStr = "unknown";
29099
+ if (isBun) {
29100
+ const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
29101
+ baseEnvStr = `bun/${bunVersion}`;
29102
+ } else if (import_core11.isNode) {
29103
+ baseEnvStr = `node/${globalThis.process.version}`;
29104
+ } else if (isReactNative) {
29105
+ baseEnvStr = "react-native";
29106
+ } else if (import_core11.isBare) {
29107
+ const bareVersion = Bare.version;
29108
+ baseEnvStr = `bare/${bareVersion}`;
29109
+ } else if (isWebExtension) {
29110
+ const protocol = "location" in globalThis ? globalThis.location.protocol : "";
29111
+ const extScriptType = "window" in globalThis ? "content-script" : "background-script";
29112
+ baseEnvStr = `web-extension/${protocol.replace(":", "")}/${extScriptType}/${userAgent}`;
29113
+ } else {
29114
+ baseEnvStr = `browser/${userAgent}`;
29115
+ }
29116
+ var clientEnv = `js-spark-sdk/${packageVersion} ${baseEnvStr}`;
29117
+
29118
+ // src/services/signing.ts
29119
+ init_buffer();
29120
+ var import_utils15 = require("@noble/curves/utils");
29121
+ var SigningService = class {
29122
+ config;
29123
+ constructor(config) {
29124
+ this.config = config;
29125
+ }
29126
+ async signRefundsInternal(refundTx, sighash, leaf, signingCommitments) {
29127
+ const leafSigningJobs = [];
29128
+ const signingCommitment = await this.config.signer.getRandomSigningCommitment();
29129
+ if (!signingCommitments) {
29130
+ throw new ValidationError("Invalid signing commitments", {
29131
+ field: "signingNonceCommitments",
29132
+ value: signingCommitments,
29133
+ expected: "Non-null signing commitments"
29134
+ });
29135
+ }
29136
+ const signingResult = await this.config.signer.signFrost({
29137
+ message: sighash,
29138
+ keyDerivation: leaf.keyDerivation,
29139
+ publicKey: await this.config.signer.getPublicKeyFromDerivation(
29140
+ leaf.keyDerivation
29141
+ ),
29142
+ selfCommitment: signingCommitment,
29143
+ statechainCommitments: signingCommitments,
29144
+ adaptorPubKey: new Uint8Array(),
29145
+ verifyingKey: leaf.leaf.verifyingPublicKey
29146
+ });
29147
+ leafSigningJobs.push({
29148
+ leafId: leaf.leaf.id,
29149
+ signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
29150
+ leaf.keyDerivation
29151
+ ),
29152
+ rawTx: refundTx.toBytes(),
29153
+ signingNonceCommitment: signingCommitment.commitment,
29154
+ userSignature: signingResult,
29155
+ signingCommitments: {
29156
+ signingCommitments
29157
+ }
29158
+ });
29159
+ return leafSigningJobs;
29160
+ }
29161
+ async signRefunds(leaves, receiverIdentityPubkey, cpfpSigningCommitments, directSigningCommitments, directFromCpfpSigningCommitments) {
29162
+ const cpfpLeafSigningJobs = [];
29163
+ const directLeafSigningJobs = [];
29164
+ const directFromCpfpLeafSigningJobs = [];
29165
+ for (let i = 0; i < leaves.length; i++) {
29166
+ const leaf = leaves[i];
29167
+ if (!leaf?.leaf) {
29168
+ throw new ValidationError("Leaf not found in signRefunds", {
29169
+ field: "leaf",
29170
+ value: leaf,
29171
+ expected: "Non-null leaf"
29172
+ });
29173
+ }
29174
+ const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
29175
+ const cpfpNodeOutPoint = {
29176
+ txid: (0, import_utils15.hexToBytes)(getTxId(nodeTx)),
29177
+ index: 0
29178
+ };
29179
+ const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
29180
+ const sequence = currRefundTx.getInput(0).sequence;
29181
+ if (!sequence) {
29182
+ throw new ValidationError("Invalid refund transaction", {
29183
+ field: "sequence",
29184
+ value: currRefundTx.getInput(0),
29185
+ expected: "Non-null sequence"
29186
+ });
29187
+ }
29188
+ const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
29189
+ const amountSats = currRefundTx.getOutput(0).amount;
29190
+ if (amountSats === void 0) {
29191
+ throw new ValidationError("Invalid refund transaction", {
29192
+ field: "amount",
29193
+ value: currRefundTx.getOutput(0),
29194
+ expected: "Non-null amount"
29195
+ });
29196
+ }
29197
+ let directNodeTx;
29198
+ let directNodeOutPoint;
29199
+ if (leaf.leaf.directTx.length > 0) {
29200
+ directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
29201
+ directNodeOutPoint = {
29202
+ txid: (0, import_utils15.hexToBytes)(getTxId(directNodeTx)),
29203
+ index: 0
29204
+ };
29205
+ }
29206
+ const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
29207
+ sequence: nextSequence,
29208
+ directSequence: nextDirectSequence,
29209
+ input: cpfpNodeOutPoint,
29210
+ directInput: directNodeOutPoint,
29211
+ amountSats,
29212
+ receivingPubkey: receiverIdentityPubkey,
29213
+ network: this.config.getNetwork()
29214
+ });
29215
+ const refundSighash = getSigHashFromTx(
29216
+ cpfpRefundTx,
29217
+ 0,
29218
+ nodeTx.getOutput(0)
29219
+ );
29220
+ const signingJobs = await this.signRefundsInternal(
29221
+ cpfpRefundTx,
29222
+ refundSighash,
29223
+ leaf,
29224
+ cpfpSigningCommitments[i]?.signingNonceCommitments
29225
+ );
29226
+ cpfpLeafSigningJobs.push(...signingJobs);
29227
+ if (directRefundTx) {
29228
+ if (!directNodeTx) {
29229
+ throw new ValidationError(
29230
+ "Direct node transaction undefined while direct refund transaction is defined",
29231
+ {
29232
+ field: "directNodeTx",
29233
+ value: directNodeTx,
29234
+ expected: "Non-null direct node transaction"
29235
+ }
29236
+ );
29237
+ }
29238
+ const refundSighash2 = getSigHashFromTx(
29239
+ directRefundTx,
29240
+ 0,
29241
+ directNodeTx.getOutput(0)
29242
+ );
29243
+ const signingJobs2 = await this.signRefundsInternal(
29244
+ directRefundTx,
29245
+ refundSighash2,
29246
+ leaf,
29247
+ directSigningCommitments[i]?.signingNonceCommitments
29248
+ );
29249
+ directLeafSigningJobs.push(...signingJobs2);
29250
+ }
29251
+ if (directFromCpfpRefundTx) {
29252
+ if (!directNodeTx) {
29253
+ throw new ValidationError(
29254
+ "Direct node transaction undefined while direct from CPFP refund transaction is defined",
29255
+ {
29256
+ field: "directNodeTx",
29257
+ value: directNodeTx,
29258
+ expected: "Non-null direct node transaction"
29259
+ }
29260
+ );
29261
+ }
29262
+ const refundSighash2 = getSigHashFromTx(
29263
+ directFromCpfpRefundTx,
29264
+ 0,
29265
+ nodeTx.getOutput(0)
29266
+ );
29267
+ const signingJobs2 = await this.signRefundsInternal(
29268
+ directFromCpfpRefundTx,
29269
+ refundSighash2,
29270
+ leaf,
29271
+ directFromCpfpSigningCommitments[i]?.signingNonceCommitments
29272
+ );
29273
+ directFromCpfpLeafSigningJobs.push(...signingJobs2);
29274
+ }
29275
+ }
29276
+ return {
29277
+ cpfpLeafSigningJobs,
29278
+ directLeafSigningJobs,
29279
+ directFromCpfpLeafSigningJobs
29280
+ };
29281
+ }
29282
+ };
29283
+
29284
+ // src/signer/signer.ts
29285
+ init_buffer();
29286
+ var import_secp256k110 = require("@bitcoinerlab/secp256k1");
29287
+ var import_secp256k111 = require("@noble/curves/secp256k1");
29288
+ var import_utils18 = require("@noble/curves/utils");
29289
+ var import_sha211 = require("@noble/hashes/sha2");
29290
+ var import_bip32 = require("@scure/bip32");
29291
+ var import_bip39 = require("@scure/bip39");
29292
+ var import_english = require("@scure/bip39/wordlists/english");
29293
+ var import_utils19 = require("@scure/btc-signer/utils");
29294
+ var ecies2 = __toESM(require("eciesjs"), 1);
29295
+
29296
+ // src/utils/secret-sharing.ts
29297
+ init_buffer();
29298
+ var import_secp256k18 = require("@noble/curves/secp256k1");
29299
+ var import_utils16 = require("@noble/curves/utils");
29300
+ function getRandomBigInt(max) {
29301
+ const byteLength = max.toString(2).length + 7 >> 3;
29302
+ const maxBigInt = max;
29303
+ const mask = (1n << BigInt(max.toString(2).length)) - 1n;
29304
+ while (true) {
29305
+ const crypto = getCrypto();
29306
+ const randBytes = crypto.getRandomValues(new Uint8Array(byteLength + 1));
29307
+ const randValue = BigInt("0x" + (0, import_utils16.bytesToHex)(randBytes)) & mask;
29308
+ if (randValue < maxBigInt) {
29309
+ return randValue;
29310
+ }
29311
+ }
29312
+ }
29313
+ function modInverse(a, m) {
29314
+ a = (a % m + m) % m;
29315
+ let [old_r, r] = [a, m];
29316
+ let [old_s, s2] = [1n, 0n];
29317
+ let [old_t, t] = [0n, 1n];
29318
+ while (r !== 0n) {
29319
+ const quotient = old_r / r;
29320
+ [old_r, r] = [r, old_r - quotient * r];
29321
+ [old_s, s2] = [s2, old_s - quotient * s2];
29322
+ [old_t, t] = [t, old_t - quotient * t];
29323
+ }
29324
+ if (old_r !== 1n) {
29325
+ throw new ValidationError("Modular inverse does not exist", {
29326
+ field: "modInverse",
29327
+ value: `a: ${a}, m: ${m}`,
29328
+ expected: "a and m must be coprime"
29329
+ });
29330
+ }
29331
+ return (old_s % m + m) % m;
29332
+ }
29333
+ function evaluatePolynomial(polynomial, x) {
29334
+ let result = 0n;
29335
+ for (let i = 0; i < polynomial.coefficients.length; i++) {
29336
+ const coeff = polynomial.coefficients[i];
29337
+ if (!coeff) {
29338
+ throw new ValidationError("Coefficient is undefined", {
29339
+ field: "coefficient",
29340
+ value: "undefined",
29341
+ expected: "A valid bigint coefficient"
29342
+ });
29343
+ }
29344
+ const xPow = x ** BigInt(i) % polynomial.fieldModulus;
29345
+ result = (result + xPow * coeff) % polynomial.fieldModulus;
29346
+ }
29347
+ return result;
29348
+ }
29349
+ function fieldDiv(numerator, denominator, fieldModulus) {
29350
+ if (denominator === 0n) {
29351
+ throw new ValidationError("Division by zero", {
29352
+ field: "denominator",
29353
+ value: "0",
29354
+ expected: "Non-zero value"
29355
+ });
29356
+ }
29357
+ const inverse = modInverse(denominator, fieldModulus);
29358
+ return numerator * inverse % fieldModulus;
29359
+ }
29360
+ function computerLagrangeCoefficients(index, points) {
29361
+ let numerator = 1n;
29362
+ let denominator = 1n;
29363
+ let fieldModulus = points[0]?.fieldModulus;
29364
+ if (!fieldModulus) {
29365
+ throw new ValidationError("Field modulus is undefined", {
29366
+ field: "fieldModulus",
29367
+ value: "undefined",
29368
+ expected: "A valid field modulus"
29369
+ });
29370
+ }
29371
+ for (const point of points) {
29372
+ if (point.index === index) {
29373
+ continue;
29374
+ }
29375
+ numerator = numerator * point.index;
29376
+ const value = point.index - index;
29377
+ denominator = denominator * value;
29378
+ }
29379
+ return fieldDiv(numerator, denominator, fieldModulus);
29380
+ }
29381
+ function generatePolynomialForSecretSharing(fieldModulus, secret, degree) {
29382
+ const coefficients = new Array(degree);
29383
+ const proofs = new Array(degree);
29384
+ coefficients[0] = secret;
29385
+ proofs[0] = import_secp256k18.secp256k1.Point.fromPrivateKey(secret).toBytes(true);
29386
+ for (let i = 1; i < degree; i++) {
29387
+ const coefficient = getRandomBigInt(fieldModulus);
29388
+ coefficients[i] = coefficient;
29389
+ proofs[i] = import_secp256k18.secp256k1.Point.fromPrivateKey(coefficient).toBytes(true);
29390
+ }
29391
+ return {
29392
+ fieldModulus,
29393
+ coefficients,
29394
+ proofs
29395
+ };
29396
+ }
29397
+ function splitSecret(fieldModulus, secret, threshold, numberOfShares) {
29398
+ const polynomial = generatePolynomialForSecretSharing(
29399
+ fieldModulus,
29400
+ secret,
29401
+ threshold
29402
+ );
29403
+ const shares = [];
29404
+ for (let i = 1; i <= numberOfShares; i++) {
29405
+ const share = evaluatePolynomial(polynomial, BigInt(i));
29406
+ shares.push({
29407
+ fieldModulus,
29408
+ threshold,
29409
+ index: BigInt(i),
29410
+ share
29411
+ });
29412
+ }
29413
+ return shares;
29414
+ }
29415
+ function splitSecretWithProofs(secret, fieldModulus, threshold, numberOfShares) {
29416
+ const polynomial = generatePolynomialForSecretSharing(
29417
+ fieldModulus,
29418
+ secret,
29419
+ threshold
29420
+ );
29421
+ const shares = [];
29422
+ for (let i = 1; i <= numberOfShares; i++) {
29423
+ const share = evaluatePolynomial(polynomial, BigInt(i));
29424
+ shares.push({
29425
+ fieldModulus,
29426
+ threshold,
29427
+ index: BigInt(i),
29428
+ share,
29429
+ proofs: polynomial.proofs
29430
+ });
29431
+ }
29432
+ return shares;
29433
+ }
29434
+ function recoverSecret(shares) {
29435
+ if (shares.length === 0) return 0n;
29436
+ const threshold = shares[0]?.threshold;
29437
+ const fieldModulus = shares[0]?.fieldModulus;
29438
+ if (!threshold || !fieldModulus) {
29439
+ throw new ValidationError("Shares are not valid", {
29440
+ field: "shares",
29441
+ value: "Missing threshold or fieldModulus",
29442
+ expected: "Valid shares with threshold and fieldModulus"
29443
+ });
29444
+ }
29445
+ if (shares.length < threshold) {
29446
+ throw new ValidationError("Not enough shares to recover secret", {
29447
+ field: "shares",
29448
+ value: shares.length,
29449
+ expected: `At least ${threshold} shares`
29450
+ });
29451
+ }
29452
+ let result = 0n;
29453
+ for (const share of shares) {
29454
+ const coeff = computerLagrangeCoefficients(share.index, shares);
29455
+ const item = share.share * coeff % fieldModulus;
29456
+ result = (result + item) % fieldModulus;
29457
+ }
29458
+ return result;
29459
+ }
29460
+ function validateShare(share) {
29461
+ const targetPubkey = import_secp256k18.secp256k1.Point.fromPrivateKey(share.share).toBytes(
29462
+ true
29463
+ );
29464
+ let resultPubkey = share.proofs[0];
29465
+ if (!resultPubkey) {
29466
+ throw new ValidationError("Result pubkey is not valid", {
29467
+ field: "resultPubkey",
29468
+ value: "null",
29469
+ expected: "Valid public key bytes"
29470
+ });
29471
+ }
29472
+ for (let i = 1; i < share.proofs.length; i++) {
29473
+ const pubkey = share.proofs[i];
29474
+ if (!pubkey) {
29475
+ throw new ValidationError("Pubkey is not valid", {
29476
+ field: "pubkey",
29477
+ value: "null",
29478
+ expected: "Valid public key bytes"
29479
+ });
29480
+ }
29481
+ const value = share.index ** BigInt(i) % share.fieldModulus;
29482
+ const scaledPoint = import_secp256k18.secp256k1.Point.fromHex(pubkey).multiply(value);
29483
+ resultPubkey = import_secp256k18.secp256k1.Point.fromHex(resultPubkey).add(scaledPoint).toBytes(true);
29484
+ }
29485
+ if (!(0, import_utils16.equalBytes)(resultPubkey, targetPubkey)) {
29486
+ throw new ValidationError("Share is not valid", {
29487
+ field: "share",
29488
+ value: "Invalid proof",
29489
+ expected: "Valid share with matching proofs"
29490
+ });
29491
+ }
29492
+ }
29493
+ function bigIntToPrivateKey(value) {
29494
+ const hex = value.toString(16).padStart(64, "0");
29495
+ const bytes2 = new Uint8Array(32);
29496
+ for (let i = 0; i < 32; i++) {
29497
+ bytes2[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
29498
+ }
29499
+ return bytes2;
29500
+ }
29501
+
29502
+ // src/utils/signing.ts
29503
+ init_buffer();
29504
+ var import_secp256k19 = require("@noble/curves/secp256k1");
29505
+ function getRandomSigningNonce() {
29506
+ const binding = import_secp256k19.secp256k1.utils.randomPrivateKey();
29507
+ const hiding = import_secp256k19.secp256k1.utils.randomPrivateKey();
29508
+ return createSigningNonce(binding, hiding);
29509
+ }
29510
+ function createSigningNonce(binding, hiding) {
29511
+ if (binding.length !== 32 || hiding.length !== 32) {
29512
+ throw new ValidationError("Invalid nonce length", {
29513
+ field: "nonce",
29514
+ value: `binding: ${binding.length}, hiding: ${hiding.length}`,
29515
+ expected: "Both binding and hiding should be 32 bytes"
29516
+ });
29517
+ }
29518
+ return {
29519
+ binding,
29520
+ hiding
29521
+ };
29522
+ }
29523
+ function getSigningCommitmentFromNonce(nonce) {
29524
+ const bindingPubKey = import_secp256k19.secp256k1.getPublicKey(nonce.binding, true);
29525
+ const hidingPubKey = import_secp256k19.secp256k1.getPublicKey(nonce.hiding, true);
29526
+ return {
29527
+ binding: bindingPubKey,
29528
+ hiding: hidingPubKey
29529
+ };
29530
+ }
29531
+ function encodeSigningNonceToBytes(nonce) {
29532
+ return new Uint8Array([...nonce.binding, ...nonce.hiding]);
29533
+ }
29534
+ function decodeBytesToSigningNonce(bytes2) {
29535
+ if (bytes2.length !== 64) {
29536
+ throw new ValidationError("Invalid nonce length", {
29537
+ field: "bytes",
29538
+ value: bytes2.length,
29539
+ expected: "64 bytes (32 bytes for binding + 32 bytes for hiding)"
29540
+ });
29541
+ }
29542
+ return {
29543
+ binding: bytes2.slice(32, 64),
29544
+ hiding: bytes2.slice(0, 32)
29545
+ };
29546
+ }
29547
+ function createSigningCommitment(binding, hiding) {
29548
+ if (binding.length !== 33 || hiding.length !== 33) {
29549
+ throw new ValidationError("Invalid nonce commitment length", {
29550
+ field: "commitment",
29551
+ value: `binding: ${binding.length}, hiding: ${hiding.length}`,
29552
+ expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
29553
+ });
29554
+ }
29555
+ return {
29556
+ binding,
29557
+ hiding
29558
+ };
29559
+ }
29560
+ function encodeSigningCommitmentToBytes(commitment) {
29561
+ if (commitment.binding.length !== 33 || commitment.hiding.length !== 33) {
29562
+ throw new ValidationError("Invalid nonce commitment length", {
29563
+ field: "commitment",
29564
+ value: `binding: ${commitment.binding.length}, hiding: ${commitment.hiding.length}`,
29565
+ expected: "Both binding and hiding should be 33 bytes (compressed public keys)"
29566
+ });
29567
+ }
29568
+ return new Uint8Array([...commitment.binding, ...commitment.hiding]);
29569
+ }
29570
+ function decodeBytesToSigningCommitment(bytes2) {
29571
+ if (bytes2.length !== 66) {
29572
+ throw new ValidationError("Invalid nonce commitment length", {
29573
+ field: "bytes",
29574
+ value: bytes2.length,
29575
+ expected: "66 bytes (33 bytes for binding + 33 bytes for hiding)"
29576
+ });
29577
+ }
29578
+ return {
29579
+ binding: bytes2.slice(33, 66),
29580
+ hiding: bytes2.slice(0, 33)
29581
+ };
29582
+ }
29583
+
29584
+ // src/signer/signer.ts
29585
+ var sparkFrostModule = void 0;
29586
+ var getSparkFrostModule = async () => {
29587
+ if (isReactNative) {
29588
+ return void 0;
29589
+ }
29590
+ if (!sparkFrostModule) {
29591
+ sparkFrostModule = await Promise.resolve().then(() => (init_wasm(), wasm_exports));
29592
+ }
29593
+ return sparkFrostModule;
29594
+ };
29595
+ var HARDENED_OFFSET = 2147483648;
29596
+ var DefaultSparkKeysGenerator = class {
29597
+ async deriveKeysFromSeed(seed, accountNumber) {
29598
+ const hdkey = import_bip32.HDKey.fromMasterSeed(seed);
29599
+ if (!hdkey.privateKey || !hdkey.publicKey) {
29600
+ throw new ValidationError("Failed to derive keys from seed", {
29601
+ field: "hdkey",
29602
+ value: seed
29603
+ });
29604
+ }
29605
+ const identityKey = hdkey.derive(`m/8797555'/${accountNumber}'/0'`);
29606
+ const signingKey = hdkey.derive(`m/8797555'/${accountNumber}'/1'`);
29607
+ const depositKey = hdkey.derive(`m/8797555'/${accountNumber}'/2'`);
29608
+ const staticDepositKey = hdkey.derive(`m/8797555'/${accountNumber}'/3'`);
29609
+ if (!identityKey.privateKey || !depositKey.privateKey || !signingKey.privateKey || !identityKey.publicKey || !depositKey.publicKey || !signingKey.publicKey || !staticDepositKey.privateKey || !staticDepositKey.publicKey) {
29610
+ throw new ValidationError(
29611
+ "Failed to derive all required keys from seed",
29612
+ {
29613
+ field: "derivedKeys"
29614
+ }
29615
+ );
29616
+ }
29617
+ return {
29618
+ identityKey: {
29619
+ privateKey: identityKey.privateKey,
29620
+ publicKey: identityKey.publicKey
29621
+ },
29622
+ signingHDKey: {
29623
+ hdKey: signingKey,
29624
+ privateKey: signingKey.privateKey,
29625
+ publicKey: signingKey.publicKey
29626
+ },
29627
+ depositKey: {
29628
+ privateKey: depositKey.privateKey,
29629
+ publicKey: depositKey.publicKey
29630
+ },
29631
+ staticDepositHDKey: {
29632
+ hdKey: staticDepositKey,
29633
+ privateKey: staticDepositKey.privateKey,
29634
+ publicKey: staticDepositKey.publicKey
29635
+ }
29636
+ };
29637
+ }
29638
+ };
29639
+ var DefaultSparkSigner = class {
29640
+ identityKey = null;
29641
+ signingKey = null;
29642
+ depositKey = null;
29643
+ staticDepositKey = null;
29644
+ commitmentToNonceMap = /* @__PURE__ */ new Map();
29645
+ keysGenerator;
29646
+ constructor({
29647
+ sparkKeysGenerator
29648
+ } = {}) {
29649
+ this.keysGenerator = sparkKeysGenerator ?? new DefaultSparkKeysGenerator();
29650
+ }
29651
+ deriveSigningKey(hash) {
29652
+ if (!this.signingKey) {
29653
+ throw new ValidationError("Private key not initialized", {
29654
+ field: "signingKey"
29655
+ });
29656
+ }
29657
+ const view = new DataView(hash.buffer);
29658
+ const amount = view.getUint32(0, false) % HARDENED_OFFSET + HARDENED_OFFSET;
29659
+ const newPrivateKey = this.signingKey?.deriveChild(amount).privateKey;
29660
+ if (!newPrivateKey) {
29661
+ throw new ValidationError("Failed to recover signing key", {
29662
+ field: "privateKey"
29663
+ });
29664
+ }
29665
+ return newPrivateKey;
29666
+ }
29667
+ async decryptEciesToPrivateKey(ciphertext) {
29668
+ if (!this.identityKey?.privateKey) {
29669
+ throw new ConfigurationError("Identity key not initialized", {
29670
+ configKey: "identityKey"
29640
29671
  });
29641
29672
  }
29642
- return inputTtxoSignaturesPerOperator;
29673
+ const receiverEciesPrivKey = ecies2.PrivateKey.fromHex(
29674
+ (0, import_utils18.bytesToHex)(this.identityKey.privateKey)
29675
+ );
29676
+ const privateKey = ecies2.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
29677
+ return privateKey;
29643
29678
  }
29644
- };
29645
-
29646
- // src/utils/adaptor-signature.ts
29647
- init_buffer();
29648
- var import_modular = require("@noble/curves/abstract/modular");
29649
- var import_secp256k111 = require("@noble/curves/secp256k1");
29650
- var import_utils18 = require("@noble/curves/utils");
29651
- function generateSignatureFromExistingAdaptor(signature, adaptorPrivateKeyBytes) {
29652
- const { r, s: s2 } = parseSignature(signature);
29653
- const sBigInt = (0, import_utils18.bytesToNumberBE)(s2);
29654
- const tBigInt = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKeyBytes);
29655
- const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k111.secp256k1.CURVE.n);
29656
- const newSignature = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
29657
- return newSignature;
29658
- }
29659
- function generateAdaptorFromSignature(signature) {
29660
- const adaptorPrivateKey = import_secp256k111.secp256k1.utils.randomPrivateKey();
29661
- const { r, s: s2 } = parseSignature(signature);
29662
- const sBigInt = (0, import_utils18.bytesToNumberBE)(s2);
29663
- const tBigInt = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKey);
29664
- const newS = (0, import_modular.mod)(sBigInt - tBigInt, import_secp256k111.secp256k1.CURVE.n);
29665
- const newSignature = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
29666
- return {
29667
- adaptorSignature: newSignature,
29668
- adaptorPrivateKey
29669
- };
29670
- }
29671
- function validateOutboundAdaptorSignature(pubkey, hash, signature, adaptorPubkey) {
29672
- return schnorrVerifyWithAdaptor(
29673
- signature,
29674
- hash,
29675
- pubkey,
29676
- adaptorPubkey,
29677
- false
29678
- );
29679
- }
29680
- function applyAdaptorToSignature(pubkey, hash, signature, adaptorPrivateKeyBytes) {
29681
- const { r, s: s2 } = parseSignature(signature);
29682
- const sBigInt = (0, import_utils18.bytesToNumberBE)(s2);
29683
- const adaptorPrivateKey = (0, import_utils18.bytesToNumberBE)(adaptorPrivateKeyBytes);
29684
- const newS = (0, import_modular.mod)(sBigInt + adaptorPrivateKey, import_secp256k111.secp256k1.CURVE.n);
29685
- const newSig = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(newS, 32)]);
29686
- try {
29687
- if (import_secp256k111.schnorr.verify(newSig, hash, pubkey)) {
29688
- return newSig;
29679
+ async getSigningPrivateKeyFromDerivation(keyDerivation) {
29680
+ switch (keyDerivation.type) {
29681
+ case "leaf" /* LEAF */:
29682
+ return this.deriveSigningKey((0, import_sha211.sha256)(keyDerivation.path));
29683
+ case "deposit" /* DEPOSIT */:
29684
+ return this.depositKey?.privateKey ?? new Uint8Array();
29685
+ case "static_deposit" /* STATIC_DEPOSIT */:
29686
+ return this.getStaticDepositSecretKey(keyDerivation.path);
29687
+ case "ecies" /* ECIES */:
29688
+ return this.decryptEciesToPrivateKey(keyDerivation.path);
29689
+ case "random" /* RANDOM */:
29690
+ return import_secp256k111.secp256k1.utils.randomPrivateKey();
29689
29691
  }
29690
- } catch (e) {
29691
- console.error("[applyAdaptorToSignature] Addition verification failed:", e);
29692
29692
  }
29693
- const altS = (0, import_modular.mod)(sBigInt - adaptorPrivateKey, import_secp256k111.secp256k1.CURVE.n);
29694
- const altSig = new Uint8Array([...r, ...(0, import_utils18.numberToBytesBE)(altS, 32)]);
29695
- try {
29696
- if (import_secp256k111.schnorr.verify(altSig, hash, pubkey)) {
29697
- return altSig;
29693
+ async signSchnorrWithIdentityKey(message) {
29694
+ if (!this.identityKey?.privateKey) {
29695
+ throw new ValidationError("Private key not set", {
29696
+ field: "identityKey"
29697
+ });
29698
29698
  }
29699
- } catch (e) {
29700
- console.error(
29701
- "[applyAdaptorToSignature] Subtraction verification failed:",
29702
- e
29703
- );
29699
+ const signature = import_secp256k111.schnorr.sign(message, this.identityKey.privateKey);
29700
+ return signature;
29704
29701
  }
29705
- throw new Error("Cannot apply adaptor to signature");
29706
- }
29707
- function schnorrVerifyWithAdaptor(signature, hash, pubKeyBytes, adaptorPubkey, inbound) {
29708
- if (hash.length !== 32) {
29709
- throw new Error(`wrong size for message (got ${hash.length}, want 32)`);
29702
+ async getIdentityPublicKey() {
29703
+ if (!this.identityKey?.publicKey) {
29704
+ throw new ValidationError("Private key is not set", {
29705
+ field: "identityKey"
29706
+ });
29707
+ }
29708
+ return this.identityKey.publicKey;
29710
29709
  }
29711
- const pubKey = import_secp256k111.schnorr.utils.lift_x((0, import_utils18.bytesToNumberBE)(pubKeyBytes));
29712
- pubKey.assertValidity();
29713
- const { r, s: s2 } = parseSignature(signature);
29714
- const commitmenet = import_secp256k111.schnorr.utils.taggedHash(
29715
- "BIP0340/challenge",
29716
- r,
29717
- pubKey.toBytes().slice(1),
29718
- hash
29719
- );
29720
- if (commitmenet.length > 32) {
29721
- throw new Error("hash of (r || P || m) too big");
29710
+ async getDepositSigningKey() {
29711
+ if (!this.depositKey?.publicKey) {
29712
+ throw new ValidationError("Deposit key is not set", {
29713
+ field: "depositKey"
29714
+ });
29715
+ }
29716
+ return this.depositKey.publicKey;
29722
29717
  }
29723
- const e = (0, import_modular.mod)((0, import_utils18.bytesToNumberBE)(commitmenet), import_secp256k111.secp256k1.CURVE.n);
29724
- const negE = (0, import_modular.mod)(-e, import_secp256k111.secp256k1.CURVE.n);
29725
- const sG = import_secp256k111.secp256k1.Point.BASE.multiplyUnsafe((0, import_utils18.bytesToNumberBE)(s2));
29726
- const eP = pubKey.multiplyUnsafe(negE);
29727
- const R = sG.add(eP);
29728
- if (R.is0()) {
29729
- throw new Error("R is zero");
29718
+ async getStaticDepositSigningKey(idx) {
29719
+ const staticDepositKey = await this.getStaticDepositSecretKey(idx);
29720
+ return import_secp256k111.secp256k1.getPublicKey(staticDepositKey);
29730
29721
  }
29731
- R.assertValidity();
29732
- const adaptorPoint = import_secp256k111.secp256k1.Point.fromHex(adaptorPubkey);
29733
- const newR = R.add(adaptorPoint);
29734
- if (!inbound && newR.equals(import_secp256k111.secp256k1.Point.ZERO)) {
29735
- throw new Error("calculated R point is the point at infinity");
29722
+ async getStaticDepositSecretKey(idx) {
29723
+ if (!this.staticDepositKey) {
29724
+ throw new ValidationError("Static deposit key is not set", {
29725
+ field: "staticDepositKey"
29726
+ });
29727
+ }
29728
+ const staticDepositKey = this.staticDepositKey.deriveChild(
29729
+ HARDENED_OFFSET + idx
29730
+ );
29731
+ if (!staticDepositKey?.privateKey) {
29732
+ throw new ValidationError("Static deposit key is not set", {
29733
+ field: "staticDepositKey"
29734
+ });
29735
+ }
29736
+ return staticDepositKey.privateKey;
29736
29737
  }
29737
- newR.assertValidity();
29738
- if (newR.y % 2n !== 0n) {
29739
- throw new Error("calculated R y-value is odd");
29738
+ async generateMnemonic() {
29739
+ return (0, import_bip39.generateMnemonic)(import_english.wordlist);
29740
29740
  }
29741
- const rNum = (0, import_utils18.bytesToNumberBE)(r);
29742
- if (newR.toAffine().x !== rNum) {
29743
- throw new Error("calculated R point was not given R");
29741
+ async mnemonicToSeed(mnemonic) {
29742
+ return await (0, import_bip39.mnemonicToSeed)(mnemonic);
29744
29743
  }
29745
- return true;
29746
- }
29747
- function parseSignature(signature) {
29748
- if (signature.length < 64) {
29749
- throw new ValidationError("Signature too short", {
29750
- expectedLength: 64,
29751
- actualLength: signature.length
29752
- });
29744
+ async getPublicKeyFromDerivation(keyDerivation) {
29745
+ const privateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
29746
+ return import_secp256k111.secp256k1.getPublicKey(privateKey);
29753
29747
  }
29754
- if (signature.length > 64) {
29755
- throw new ValidationError("Signature too long", {
29756
- expectedLength: 64,
29757
- actualLength: signature.length
29758
- });
29748
+ async subtractPrivateKeysGivenDerivationPaths(first, second) {
29749
+ const firstPrivateKey = this.deriveSigningKey((0, import_sha211.sha256)(first));
29750
+ const secondPrivateKey = this.deriveSigningKey((0, import_sha211.sha256)(second));
29751
+ const resultPrivKey = subtractPrivateKeys(
29752
+ firstPrivateKey,
29753
+ secondPrivateKey
29754
+ );
29755
+ const resultPubKey = import_secp256k111.secp256k1.getPublicKey(resultPrivKey);
29756
+ return resultPubKey;
29759
29757
  }
29760
- const r = signature.slice(0, 32);
29761
- const s2 = signature.slice(32, 64);
29762
- if ((0, import_utils18.bytesToNumberBE)(r) >= import_secp256k111.secp256k1.CURVE.Fp.ORDER) {
29763
- throw new ValidationError("Invalid signature: r >= field prime", {
29764
- rValue: (0, import_utils18.bytesToNumberBE)(r),
29765
- fieldPrime: import_secp256k111.secp256k1.CURVE.Fp.ORDER
29758
+ async subtractAndSplitSecretWithProofsGivenDerivations({
29759
+ first,
29760
+ second,
29761
+ curveOrder,
29762
+ threshold,
29763
+ numShares
29764
+ }) {
29765
+ const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
29766
+ const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
29767
+ const resultPrivKey = subtractPrivateKeys(
29768
+ firstPrivateKey,
29769
+ secondPrivateKey
29770
+ );
29771
+ return await this.splitSecretWithProofs({
29772
+ secret: resultPrivKey,
29773
+ curveOrder,
29774
+ threshold,
29775
+ numShares
29766
29776
  });
29767
29777
  }
29768
- if ((0, import_utils18.bytesToNumberBE)(s2) >= import_secp256k111.secp256k1.CURVE.n) {
29769
- throw new ValidationError("Invalid signature: s >= group order", {
29770
- sValue: (0, import_utils18.bytesToNumberBE)(s2),
29771
- groupOrder: import_secp256k111.secp256k1.CURVE.n
29772
- });
29778
+ async subtractSplitAndEncrypt({
29779
+ first,
29780
+ second,
29781
+ curveOrder,
29782
+ threshold,
29783
+ numShares,
29784
+ receiverPublicKey
29785
+ }) {
29786
+ const firstPrivateKey = await this.getSigningPrivateKeyFromDerivation(first);
29787
+ const secondPrivateKey = await this.getSigningPrivateKeyFromDerivation(second);
29788
+ const resultPrivKey = subtractPrivateKeys(
29789
+ firstPrivateKey,
29790
+ secondPrivateKey
29791
+ );
29792
+ return {
29793
+ shares: await this.splitSecretWithProofs({
29794
+ secret: resultPrivKey,
29795
+ curveOrder,
29796
+ threshold,
29797
+ numShares
29798
+ }),
29799
+ secretCipher: ecies2.encrypt(receiverPublicKey, secondPrivateKey)
29800
+ };
29773
29801
  }
29774
- return { r, s: s2 };
29775
- }
29776
-
29777
- // src/spark-wallet/spark-wallet.ts
29778
- var import_sha212 = require("@noble/hashes/sha2");
29779
- var import_api = require("@opentelemetry/api");
29780
- var import_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
29781
- var import_eventemitter3 = require("eventemitter3");
29782
- var import_nice_grpc_common = require("nice-grpc-common");
29783
-
29784
- // src/services/signing.ts
29785
- init_buffer();
29786
- var import_utils19 = require("@noble/curves/utils");
29787
- var SigningService = class {
29788
- config;
29789
- constructor(config) {
29790
- this.config = config;
29802
+ async splitSecretWithProofs({
29803
+ secret,
29804
+ curveOrder,
29805
+ threshold,
29806
+ numShares
29807
+ }) {
29808
+ const secretAsInt = (0, import_utils18.bytesToNumberBE)(secret);
29809
+ return splitSecretWithProofs(secretAsInt, curveOrder, threshold, numShares);
29791
29810
  }
29792
- async signRefundsInternal(refundTx, sighash, leaf, signingCommitments) {
29793
- const leafSigningJobs = [];
29794
- const signingCommitment = await this.config.signer.getRandomSigningCommitment();
29795
- if (!signingCommitments) {
29796
- throw new ValidationError("Invalid signing commitments", {
29797
- field: "signingNonceCommitments",
29798
- value: signingCommitments,
29799
- expected: "Non-null signing commitments"
29811
+ async signFrost({
29812
+ message,
29813
+ keyDerivation,
29814
+ publicKey,
29815
+ verifyingKey,
29816
+ selfCommitment,
29817
+ statechainCommitments,
29818
+ adaptorPubKey
29819
+ }) {
29820
+ const SparkFrost = await getSparkFrostModule();
29821
+ if (!SparkFrost) {
29822
+ throw new ValidationError("SparkFrost module not found", {
29823
+ field: "SparkFrost"
29800
29824
  });
29801
29825
  }
29802
- const signingResult = await this.config.signer.signFrost({
29803
- message: sighash,
29804
- keyDerivation: leaf.keyDerivation,
29805
- publicKey: await this.config.signer.getPublicKeyFromDerivation(
29806
- leaf.keyDerivation
29807
- ),
29808
- selfCommitment: signingCommitment,
29809
- statechainCommitments: signingCommitments,
29810
- adaptorPubKey: new Uint8Array(),
29811
- verifyingKey: leaf.leaf.verifyingPublicKey
29826
+ const signingPrivateKey = await this.getSigningPrivateKeyFromDerivation(keyDerivation);
29827
+ if (!signingPrivateKey) {
29828
+ throw new ValidationError("Private key not found for public key", {
29829
+ field: "privateKey"
29830
+ });
29831
+ }
29832
+ const commitment = selfCommitment.commitment;
29833
+ const nonce = this.commitmentToNonceMap.get(commitment);
29834
+ if (!nonce) {
29835
+ throw new ValidationError("Nonce not found for commitment", {
29836
+ field: "nonce"
29837
+ });
29838
+ }
29839
+ const keyPackage = {
29840
+ secretKey: signingPrivateKey,
29841
+ publicKey,
29842
+ verifyingKey
29843
+ };
29844
+ const logMessage = (0, import_utils18.bytesToHex)(message);
29845
+ const result = await SparkFrost.signFrost({
29846
+ message,
29847
+ keyPackage,
29848
+ nonce,
29849
+ selfCommitment: commitment,
29850
+ statechainCommitments,
29851
+ adaptorPubKey
29812
29852
  });
29813
- leafSigningJobs.push({
29814
- leafId: leaf.leaf.id,
29815
- signingPublicKey: await this.config.signer.getPublicKeyFromDerivation(
29816
- leaf.keyDerivation
29817
- ),
29818
- rawTx: refundTx.toBytes(),
29819
- signingNonceCommitment: signingCommitment.commitment,
29820
- userSignature: signingResult,
29821
- signingCommitments: {
29822
- signingCommitments
29823
- }
29853
+ return result;
29854
+ }
29855
+ async aggregateFrost({
29856
+ message,
29857
+ publicKey,
29858
+ verifyingKey,
29859
+ selfCommitment,
29860
+ statechainCommitments,
29861
+ adaptorPubKey,
29862
+ selfSignature,
29863
+ statechainSignatures,
29864
+ statechainPublicKeys
29865
+ }) {
29866
+ const SparkFrost = await getSparkFrostModule();
29867
+ if (!SparkFrost) {
29868
+ throw new ValidationError("SparkFrost module not found", {
29869
+ field: "SparkFrost"
29870
+ });
29871
+ }
29872
+ return SparkFrost.aggregateFrost({
29873
+ message,
29874
+ statechainSignatures,
29875
+ statechainPublicKeys,
29876
+ verifyingKey,
29877
+ statechainCommitments,
29878
+ selfCommitment: selfCommitment.commitment,
29879
+ selfPublicKey: publicKey,
29880
+ selfSignature,
29881
+ adaptorPubKey
29824
29882
  });
29825
- return leafSigningJobs;
29826
29883
  }
29827
- async signRefunds(leaves, receiverIdentityPubkey, cpfpSigningCommitments, directSigningCommitments, directFromCpfpSigningCommitments) {
29828
- const cpfpLeafSigningJobs = [];
29829
- const directLeafSigningJobs = [];
29830
- const directFromCpfpLeafSigningJobs = [];
29831
- for (let i = 0; i < leaves.length; i++) {
29832
- const leaf = leaves[i];
29833
- if (!leaf?.leaf) {
29834
- throw new ValidationError("Leaf not found in signRefunds", {
29835
- field: "leaf",
29836
- value: leaf,
29837
- expected: "Non-null leaf"
29838
- });
29839
- }
29840
- const nodeTx = getTxFromRawTxBytes(leaf.leaf.nodeTx);
29841
- const cpfpNodeOutPoint = {
29842
- txid: (0, import_utils19.hexToBytes)(getTxId(nodeTx)),
29843
- index: 0
29844
- };
29845
- const currRefundTx = getTxFromRawTxBytes(leaf.leaf.refundTx);
29846
- const sequence = currRefundTx.getInput(0).sequence;
29847
- if (!sequence) {
29848
- throw new ValidationError("Invalid refund transaction", {
29849
- field: "sequence",
29850
- value: currRefundTx.getInput(0),
29851
- expected: "Non-null sequence"
29852
- });
29853
- }
29854
- const { nextSequence, nextDirectSequence } = getNextTransactionSequence(sequence);
29855
- const amountSats = currRefundTx.getOutput(0).amount;
29856
- if (amountSats === void 0) {
29857
- throw new ValidationError("Invalid refund transaction", {
29858
- field: "amount",
29859
- value: currRefundTx.getOutput(0),
29860
- expected: "Non-null amount"
29861
- });
29862
- }
29863
- let directNodeTx;
29864
- let directNodeOutPoint;
29865
- if (leaf.leaf.directTx.length > 0) {
29866
- directNodeTx = getTxFromRawTxBytes(leaf.leaf.directTx);
29867
- directNodeOutPoint = {
29868
- txid: (0, import_utils19.hexToBytes)(getTxId(directNodeTx)),
29869
- index: 0
29870
- };
29871
- }
29872
- const { cpfpRefundTx, directRefundTx, directFromCpfpRefundTx } = createRefundTxs({
29873
- sequence: nextSequence,
29874
- directSequence: nextDirectSequence,
29875
- input: cpfpNodeOutPoint,
29876
- directInput: directNodeOutPoint,
29877
- amountSats,
29878
- receivingPubkey: receiverIdentityPubkey,
29879
- network: this.config.getNetwork()
29884
+ async createSparkWalletFromSeed(seed, accountNumber) {
29885
+ if (typeof seed === "string") {
29886
+ seed = (0, import_utils18.hexToBytes)(seed);
29887
+ }
29888
+ const {
29889
+ identityKey,
29890
+ signingHDKey: signingKey,
29891
+ depositKey,
29892
+ staticDepositHDKey: staticDepositKey
29893
+ } = await this.keysGenerator.deriveKeysFromSeed(seed, accountNumber ?? 0);
29894
+ this.identityKey = identityKey;
29895
+ this.depositKey = depositKey;
29896
+ this.signingKey = signingKey.hdKey;
29897
+ this.staticDepositKey = staticDepositKey.hdKey;
29898
+ return (0, import_utils18.bytesToHex)(identityKey.publicKey);
29899
+ }
29900
+ async signMessageWithIdentityKey(message, compact) {
29901
+ if (!this.identityKey?.privateKey) {
29902
+ throw new ConfigurationError("Identity key not initialized", {
29903
+ configKey: "identityKey"
29904
+ });
29905
+ }
29906
+ const signature = import_secp256k111.secp256k1.sign(message, this.identityKey.privateKey);
29907
+ if (compact) {
29908
+ return signature.toCompactRawBytes();
29909
+ }
29910
+ return signature.toDERRawBytes();
29911
+ }
29912
+ async decryptEcies(ciphertext) {
29913
+ if (!this.identityKey?.privateKey) {
29914
+ throw new ConfigurationError("Identity key not initialized", {
29915
+ configKey: "identityKey"
29880
29916
  });
29881
- const refundSighash = getSigHashFromTx(
29882
- cpfpRefundTx,
29883
- 0,
29884
- nodeTx.getOutput(0)
29885
- );
29886
- const signingJobs = await this.signRefundsInternal(
29887
- cpfpRefundTx,
29888
- refundSighash,
29889
- leaf,
29890
- cpfpSigningCommitments[i]?.signingNonceCommitments
29891
- );
29892
- cpfpLeafSigningJobs.push(...signingJobs);
29893
- if (directRefundTx) {
29894
- if (!directNodeTx) {
29895
- throw new ValidationError(
29896
- "Direct node transaction undefined while direct refund transaction is defined",
29897
- {
29898
- field: "directNodeTx",
29899
- value: directNodeTx,
29900
- expected: "Non-null direct node transaction"
29901
- }
29902
- );
29903
- }
29904
- const refundSighash2 = getSigHashFromTx(
29905
- directRefundTx,
29906
- 0,
29907
- directNodeTx.getOutput(0)
29908
- );
29909
- const signingJobs2 = await this.signRefundsInternal(
29910
- directRefundTx,
29911
- refundSighash2,
29912
- leaf,
29913
- directSigningCommitments[i]?.signingNonceCommitments
29914
- );
29915
- directLeafSigningJobs.push(...signingJobs2);
29916
- }
29917
- if (directFromCpfpRefundTx) {
29918
- if (!directNodeTx) {
29919
- throw new ValidationError(
29920
- "Direct node transaction undefined while direct from CPFP refund transaction is defined",
29921
- {
29922
- field: "directNodeTx",
29923
- value: directNodeTx,
29924
- expected: "Non-null direct node transaction"
29925
- }
29926
- );
29927
- }
29928
- const refundSighash2 = getSigHashFromTx(
29929
- directFromCpfpRefundTx,
29930
- 0,
29931
- nodeTx.getOutput(0)
29932
- );
29933
- const signingJobs2 = await this.signRefundsInternal(
29934
- directFromCpfpRefundTx,
29935
- refundSighash2,
29936
- leaf,
29937
- directFromCpfpSigningCommitments[i]?.signingNonceCommitments
29938
- );
29939
- directFromCpfpLeafSigningJobs.push(...signingJobs2);
29940
- }
29941
29917
  }
29918
+ const receiverEciesPrivKey = ecies2.PrivateKey.fromHex(
29919
+ (0, import_utils18.bytesToHex)(this.identityKey.privateKey)
29920
+ );
29921
+ const privateKey = ecies2.decrypt(receiverEciesPrivKey.toHex(), ciphertext);
29922
+ const publicKey = import_secp256k111.secp256k1.getPublicKey(privateKey);
29923
+ return publicKey;
29924
+ }
29925
+ async getRandomSigningCommitment() {
29926
+ const nonce = getRandomSigningNonce();
29927
+ const commitment = getSigningCommitmentFromNonce(nonce);
29928
+ this.commitmentToNonceMap.set(commitment, nonce);
29942
29929
  return {
29943
- cpfpLeafSigningJobs,
29944
- directLeafSigningJobs,
29945
- directFromCpfpLeafSigningJobs
29930
+ commitment
29946
29931
  };
29947
29932
  }
29933
+ async validateMessageWithIdentityKey(message, signature) {
29934
+ if (!this.identityKey?.publicKey) {
29935
+ throw new ConfigurationError("Identity key not initialized", {
29936
+ configKey: "identityKey"
29937
+ });
29938
+ }
29939
+ return import_secp256k111.secp256k1.verify(signature, message, this.identityKey.publicKey);
29940
+ }
29941
+ signTransactionIndex(tx, index, publicKey) {
29942
+ let privateKey;
29943
+ if ((0, import_utils18.equalBytes)(publicKey, this.identityKey?.publicKey ?? new Uint8Array())) {
29944
+ privateKey = this.identityKey?.privateKey;
29945
+ } else if ((0, import_utils18.equalBytes)(publicKey, this.depositKey?.publicKey ?? new Uint8Array())) {
29946
+ privateKey = this.depositKey?.privateKey;
29947
+ }
29948
+ if (!privateKey) {
29949
+ throw new ValidationError("Private key not found for public key", {
29950
+ field: "privateKey",
29951
+ value: (0, import_utils18.bytesToHex)(publicKey)
29952
+ });
29953
+ }
29954
+ tx.signIdx(privateKey, index);
29955
+ }
29948
29956
  };
29949
29957
 
29950
29958
  // src/tests/utils/test-faucet.ts
@@ -29965,7 +29973,7 @@ var COIN_AMOUNT = 10000000n;
29965
29973
  var FEE_AMOUNT = 1000n;
29966
29974
  var TARGET_NUM_COINS = 20;
29967
29975
  var BitcoinFaucet = class _BitcoinFaucet {
29968
- constructor(url = "http://127.0.0.1:8332", username = "testutil", password = "testutilpassword") {
29976
+ constructor(url, username, password) {
29969
29977
  this.url = url;
29970
29978
  this.username = username;
29971
29979
  this.password = password;
@@ -29978,8 +29986,11 @@ var BitcoinFaucet = class _BitcoinFaucet {
29978
29986
  static instance = null;
29979
29987
  miningAddress;
29980
29988
  lock = Promise.resolve();
29981
- static getInstance(url = "http://127.0.0.1:8332", username = "testutil", password = "testutilpassword") {
29989
+ static getInstance() {
29982
29990
  if (!_BitcoinFaucet.instance) {
29991
+ const url = process.env.BITCOIN_RPC_URL || (process.env.MINIKUBE_IP ? `http://${process.env.MINIKUBE_IP}:8332` : "http://127.0.0.1:8332");
29992
+ const username = process.env.BITCOIN_RPC_USER || "testutil";
29993
+ const password = process.env.BITCOIN_RPC_PASSWORD || "testutilpassword";
29983
29994
  _BitcoinFaucet.instance = new _BitcoinFaucet(url, username, password);
29984
29995
  }
29985
29996
  return _BitcoinFaucet.instance;
@@ -30308,6 +30319,76 @@ function chunkArray(arr, size) {
30308
30319
  return chunks;
30309
30320
  }
30310
30321
 
30322
+ // src/utils/optimize.ts
30323
+ init_buffer();
30324
+ var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
30325
+ function assert(condition, message) {
30326
+ if (!condition) {
30327
+ throw new InternalValidationError(message || "Assertion failed");
30328
+ }
30329
+ }
30330
+ function sum(arr) {
30331
+ return arr.reduce((a, b) => a + b, 0);
30332
+ }
30333
+ function sorted(arr) {
30334
+ return [...arr].sort((a, b) => a - b);
30335
+ }
30336
+ function equals(a, b) {
30337
+ return a.length === b.length && a.every((val, index) => val === b[index]);
30338
+ }
30339
+ function greedyLeaves(amount) {
30340
+ const leaves = [];
30341
+ let remaining = amount;
30342
+ for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
30343
+ const leaf = DENOMINATIONS[i];
30344
+ if (typeof leaf === "number" && leaf > 0) {
30345
+ while (remaining >= leaf) {
30346
+ remaining -= leaf;
30347
+ leaves.push(leaf);
30348
+ }
30349
+ }
30350
+ }
30351
+ assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
30352
+ return sorted(leaves);
30353
+ }
30354
+ var Swap = class {
30355
+ inLeaves;
30356
+ outLeaves;
30357
+ constructor(inLeaves, outLeaves) {
30358
+ this.inLeaves = [...inLeaves];
30359
+ this.outLeaves = [...outLeaves];
30360
+ assert(
30361
+ sum(this.inLeaves) === sum(this.outLeaves),
30362
+ "Swap in/out leaves must sum to same value for swap: " + this.toString()
30363
+ );
30364
+ }
30365
+ toString() {
30366
+ return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
30367
+ }
30368
+ };
30369
+ function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
30370
+ const swaps = [];
30371
+ let batch = [];
30372
+ let leaves = sorted(inputLeaves);
30373
+ while (leaves.length > 0) {
30374
+ batch.push(leaves.shift());
30375
+ const target = greedyLeaves(sum(batch));
30376
+ if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
30377
+ if (!equals(target, batch)) {
30378
+ swaps.push(new Swap([...batch], target));
30379
+ }
30380
+ batch = [];
30381
+ }
30382
+ }
30383
+ if (batch.length > 0) {
30384
+ const target = greedyLeaves(sum(batch));
30385
+ if (!equals(target, batch)) {
30386
+ swaps.push(new Swap([...batch], target));
30387
+ }
30388
+ }
30389
+ return swaps;
30390
+ }
30391
+
30311
30392
  // src/utils/retry.ts
30312
30393
  init_buffer();
30313
30394
  var DEFAULT_RETRY_CONFIG = {
@@ -30411,8 +30492,9 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
30411
30492
  // Add this property near the top of the class with other private properties
30412
30493
  claimTransfersInterval = null;
30413
30494
  tracer = null;
30414
- constructor(options, signer) {
30495
+ constructor(options, signerArg) {
30415
30496
  super();
30497
+ const signer = signerArg || this.buildSigner();
30416
30498
  this.config = new WalletConfigService(options, signer);
30417
30499
  this.connectionManager = this.buildConnectionManager(this.config);
30418
30500
  this.signingService = new SigningService(this.config);
@@ -30470,6 +30552,9 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
30470
30552
  }
30471
30553
  return this.sspClient;
30472
30554
  }
30555
+ buildSigner() {
30556
+ return new DefaultSparkSigner();
30557
+ }
30473
30558
  buildConnectionManager(config) {
30474
30559
  return new ConnectionManager(config);
30475
30560
  }
@@ -30831,8 +30916,34 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
30831
30916
  await this.withLeaves(async () => {
30832
30917
  this.optimizationInProgress = true;
30833
30918
  try {
30834
- if (this.leaves.length > 0) {
30835
- await this.requestLeavesSwap({ leaves: this.leaves });
30919
+ this.leaves = await this.getLeaves();
30920
+ const swaps = maximizeUnilateralExit(
30921
+ this.leaves.map((leaf) => leaf.value)
30922
+ );
30923
+ const valueToNodes = /* @__PURE__ */ new Map();
30924
+ this.leaves.forEach((leaf) => {
30925
+ if (!valueToNodes.has(leaf.value)) {
30926
+ valueToNodes.set(leaf.value, []);
30927
+ }
30928
+ valueToNodes.get(leaf.value).push(leaf);
30929
+ });
30930
+ for (const swap of swaps) {
30931
+ const leavesToSend = [];
30932
+ for (const leafValue of swap.inLeaves) {
30933
+ const nodes = valueToNodes.get(leafValue);
30934
+ if (nodes && nodes.length > 0) {
30935
+ const node = nodes.shift();
30936
+ leavesToSend.push(node);
30937
+ } else {
30938
+ throw new InternalValidationError(
30939
+ `No unused leaf with value ${leafValue} found in leaves`
30940
+ );
30941
+ }
30942
+ }
30943
+ await this.requestLeavesSwap({
30944
+ leaves: leavesToSend,
30945
+ targetAmounts: swap.outLeaves
30946
+ });
30836
30947
  }
30837
30948
  this.leaves = await this.getLeaves();
30838
30949
  } finally {
@@ -31403,6 +31514,10 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
31403
31514
  directSignatureMap,
31404
31515
  directFromCpfpSignatureMap
31405
31516
  );
31517
+ const leavesToRemove = new Set(leavesBatch.map((leaf) => leaf.id));
31518
+ this.leaves = [
31519
+ ...this.leaves.filter((leaf) => !leavesToRemove.has(leaf.id))
31520
+ ];
31406
31521
  const completeResponse = await sspClient.completeLeaveSwap({
31407
31522
  adaptorSecretKey: (0, import_utils23.bytesToHex)(cpfpAdaptorPrivateKey),
31408
31523
  directAdaptorSecretKey: (0, import_utils23.bytesToHex)(directAdaptorPrivateKey),
@@ -31991,7 +32106,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
31991
32106
  creditAmountView.setUint32(4, upperHalf, true);
31992
32107
  parts.push(new Uint8Array(creditAmountBuffer));
31993
32108
  parts.push((0, import_utils23.hexToBytes)(sspSignature));
31994
- const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
32109
+ const totalLength = parts.reduce((sum2, part) => sum2 + part.length, 0);
31995
32110
  const payload = new Uint8Array(totalLength);
31996
32111
  let offset = 0;
31997
32112
  for (const part of parts) {
@@ -33087,8 +33202,8 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
33087
33202
  );
33088
33203
  const sspResponse = await sspClient.requestLightningSend({
33089
33204
  encodedInvoice: invoice,
33090
- idempotencyKey: (0, import_uuidv75.uuidv7)(),
33091
- amountSats: isZeroAmountInvoice ? amountSatsToSend : void 0
33205
+ amountSats: isZeroAmountInvoice ? amountSatsToSend : void 0,
33206
+ userOutboundTransferExternalId: swapResponse.transfer.id
33092
33207
  });
33093
33208
  if (!sspResponse) {
33094
33209
  throw new Error("Failed to contact SSP");
@@ -33394,12 +33509,13 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
33394
33509
  }
33395
33510
  }))
33396
33511
  );
33512
+ const transferId = (0, import_uuidv75.uuidv7)();
33397
33513
  const requestCoopExitParams = {
33398
33514
  leafExternalIds: leavesToSendToSsp.map((leaf) => leaf.id),
33399
33515
  withdrawalAddress: onchainAddress,
33400
- idempotencyKey: (0, import_uuidv75.uuidv7)(),
33401
33516
  exitSpeed,
33402
- withdrawAll: deductFeeFromWithdrawalAmount
33517
+ withdrawAll: deductFeeFromWithdrawalAmount,
33518
+ userOutboundTransferExternalId: transferId
33403
33519
  };
33404
33520
  if (!deductFeeFromWithdrawalAmount) {
33405
33521
  requestCoopExitParams.feeQuoteId = feeEstimate.id;
@@ -33434,11 +33550,11 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
33434
33550
  leaves: leafKeyTweaks,
33435
33551
  exitTxId: coopExitTxId,
33436
33552
  connectorOutputs,
33437
- receiverPubKey: sspPubIdentityKey
33553
+ receiverPubKey: sspPubIdentityKey,
33554
+ transferId
33438
33555
  });
33439
33556
  const completeResponse = await sspClient.completeCoopExit({
33440
- userOutboundTransferExternalId: transfer.transfer.id,
33441
- coopExitRequestId: coopExitRequest.id
33557
+ userOutboundTransferExternalId: transfer.transfer.id
33442
33558
  });
33443
33559
  return completeResponse;
33444
33560
  }
@@ -34160,7 +34276,6 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
34160
34276
  const consoleOptions = wallet.config.getConsoleOptions();
34161
34277
  const spanProcessors = [];
34162
34278
  if (consoleOptions.otel) {
34163
- console.log("OpenTelemetry client logging enabled.");
34164
34279
  spanProcessors.push(new import_sdk_trace_base.SimpleSpanProcessor(new import_sdk_trace_base.ConsoleSpanExporter()));
34165
34280
  }
34166
34281
  const traceUrls = this.getOtelTraceUrls();
@@ -34353,7 +34468,6 @@ var SparkWalletBrowser = class extends SparkWallet {
34353
34468
  spanProcessors,
34354
34469
  traceUrls
34355
34470
  }) {
34356
- console.log("initializeTracerEnvBrowser");
34357
34471
  initializeTracerEnvBrowser({ spanProcessors, traceUrls });
34358
34472
  }
34359
34473
  };