@unicitylabs/sphere-sdk 0.5.3 → 0.5.5

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 (50) hide show
  1. package/README.md +2 -0
  2. package/dist/connect/index.cjs +145 -23
  3. package/dist/connect/index.cjs.map +1 -1
  4. package/dist/connect/index.d.cts +15 -2
  5. package/dist/connect/index.d.ts +15 -2
  6. package/dist/connect/index.js +145 -23
  7. package/dist/connect/index.js.map +1 -1
  8. package/dist/core/index.cjs +670 -473
  9. package/dist/core/index.cjs.map +1 -1
  10. package/dist/core/index.d.cts +123 -2
  11. package/dist/core/index.d.ts +123 -2
  12. package/dist/core/index.js +667 -473
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/impl/browser/connect/index.cjs +119 -1
  15. package/dist/impl/browser/connect/index.cjs.map +1 -1
  16. package/dist/impl/browser/connect/index.d.cts +53 -1
  17. package/dist/impl/browser/connect/index.d.ts +53 -1
  18. package/dist/impl/browser/connect/index.js +119 -1
  19. package/dist/impl/browser/connect/index.js.map +1 -1
  20. package/dist/impl/browser/index.cjs +306 -193
  21. package/dist/impl/browser/index.cjs.map +1 -1
  22. package/dist/impl/browser/index.js +306 -193
  23. package/dist/impl/browser/index.js.map +1 -1
  24. package/dist/impl/browser/ipfs.cjs +134 -19
  25. package/dist/impl/browser/ipfs.cjs.map +1 -1
  26. package/dist/impl/browser/ipfs.js +134 -19
  27. package/dist/impl/browser/ipfs.js.map +1 -1
  28. package/dist/impl/nodejs/connect/index.cjs +101 -6
  29. package/dist/impl/nodejs/connect/index.cjs.map +1 -1
  30. package/dist/impl/nodejs/connect/index.d.cts +2 -0
  31. package/dist/impl/nodejs/connect/index.d.ts +2 -0
  32. package/dist/impl/nodejs/connect/index.js +101 -6
  33. package/dist/impl/nodejs/connect/index.js.map +1 -1
  34. package/dist/impl/nodejs/index.cjs +267 -152
  35. package/dist/impl/nodejs/index.cjs.map +1 -1
  36. package/dist/impl/nodejs/index.d.cts +2 -1
  37. package/dist/impl/nodejs/index.d.ts +2 -1
  38. package/dist/impl/nodejs/index.js +267 -152
  39. package/dist/impl/nodejs/index.js.map +1 -1
  40. package/dist/index.cjs +682 -493
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +124 -8
  43. package/dist/index.d.ts +124 -8
  44. package/dist/index.js +680 -493
  45. package/dist/index.js.map +1 -1
  46. package/dist/l1/index.cjs +139 -32
  47. package/dist/l1/index.cjs.map +1 -1
  48. package/dist/l1/index.js +139 -32
  49. package/dist/l1/index.js.map +1 -1
  50. package/package.json +1 -16
@@ -14,6 +14,125 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
+ // core/logger.ts
18
+ function getState() {
19
+ const g = globalThis;
20
+ if (!g[LOGGER_KEY]) {
21
+ g[LOGGER_KEY] = { debug: false, tags: {}, handler: null };
22
+ }
23
+ return g[LOGGER_KEY];
24
+ }
25
+ function isEnabled(tag) {
26
+ const state = getState();
27
+ if (tag in state.tags) return state.tags[tag];
28
+ return state.debug;
29
+ }
30
+ var LOGGER_KEY, logger;
31
+ var init_logger = __esm({
32
+ "core/logger.ts"() {
33
+ "use strict";
34
+ LOGGER_KEY = "__sphere_sdk_logger__";
35
+ logger = {
36
+ /**
37
+ * Configure the logger. Can be called multiple times (last write wins).
38
+ * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().
39
+ */
40
+ configure(config) {
41
+ const state = getState();
42
+ if (config.debug !== void 0) state.debug = config.debug;
43
+ if (config.handler !== void 0) state.handler = config.handler;
44
+ },
45
+ /**
46
+ * Enable/disable debug logging for a specific tag.
47
+ * Per-tag setting overrides the global debug flag.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * logger.setTagDebug('Nostr', true); // enable only Nostr logs
52
+ * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true
53
+ * ```
54
+ */
55
+ setTagDebug(tag, enabled) {
56
+ getState().tags[tag] = enabled;
57
+ },
58
+ /**
59
+ * Clear per-tag override, falling back to global debug flag.
60
+ */
61
+ clearTagDebug(tag) {
62
+ delete getState().tags[tag];
63
+ },
64
+ /** Returns true if debug mode is enabled for the given tag (or globally). */
65
+ isDebugEnabled(tag) {
66
+ if (tag) return isEnabled(tag);
67
+ return getState().debug;
68
+ },
69
+ /**
70
+ * Debug-level log. Only shown when debug is enabled (globally or for this tag).
71
+ * Use for detailed operational information.
72
+ */
73
+ debug(tag, message, ...args) {
74
+ if (!isEnabled(tag)) return;
75
+ const state = getState();
76
+ if (state.handler) {
77
+ state.handler("debug", tag, message, ...args);
78
+ } else {
79
+ console.log(`[${tag}]`, message, ...args);
80
+ }
81
+ },
82
+ /**
83
+ * Warning-level log. ALWAYS shown regardless of debug flag.
84
+ * Use for important but non-critical issues (timeouts, retries, degraded state).
85
+ */
86
+ warn(tag, message, ...args) {
87
+ const state = getState();
88
+ if (state.handler) {
89
+ state.handler("warn", tag, message, ...args);
90
+ } else {
91
+ console.warn(`[${tag}]`, message, ...args);
92
+ }
93
+ },
94
+ /**
95
+ * Error-level log. ALWAYS shown regardless of debug flag.
96
+ * Use for critical failures that should never be silenced.
97
+ */
98
+ error(tag, message, ...args) {
99
+ const state = getState();
100
+ if (state.handler) {
101
+ state.handler("error", tag, message, ...args);
102
+ } else {
103
+ console.error(`[${tag}]`, message, ...args);
104
+ }
105
+ },
106
+ /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */
107
+ reset() {
108
+ const g = globalThis;
109
+ delete g[LOGGER_KEY];
110
+ }
111
+ };
112
+ }
113
+ });
114
+
115
+ // core/errors.ts
116
+ function isSphereError(err) {
117
+ return err instanceof SphereError;
118
+ }
119
+ var SphereError;
120
+ var init_errors = __esm({
121
+ "core/errors.ts"() {
122
+ "use strict";
123
+ SphereError = class extends Error {
124
+ code;
125
+ cause;
126
+ constructor(message, code, cause) {
127
+ super(message);
128
+ this.name = "SphereError";
129
+ this.code = code;
130
+ this.cause = cause;
131
+ }
132
+ };
133
+ }
134
+ });
135
+
17
136
  // constants.ts
18
137
  function getAddressId(directAddress) {
19
138
  let hash = directAddress;
@@ -241,11 +360,11 @@ function bech32Checksum(hrp, data) {
241
360
  }
242
361
  function encodeBech32(hrp, version, program) {
243
362
  if (version < 0 || version > 16) {
244
- throw new Error("Invalid witness version");
363
+ throw new SphereError("Invalid witness version", "VALIDATION_ERROR");
245
364
  }
246
365
  const converted = convertBits(Array.from(program), 8, 5, true);
247
366
  if (!converted) {
248
- throw new Error("Failed to convert bits");
367
+ throw new SphereError("Failed to convert bits", "VALIDATION_ERROR");
249
368
  }
250
369
  const data = [version].concat(converted);
251
370
  const checksum = bech32Checksum(hrp, data);
@@ -298,6 +417,7 @@ var CHARSET, GENERATOR, createBech32;
298
417
  var init_bech32 = __esm({
299
418
  "core/bech32.ts"() {
300
419
  "use strict";
420
+ init_errors();
301
421
  CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
302
422
  GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
303
423
  createBech32 = encodeBech32;
@@ -311,7 +431,7 @@ function bytesToHex(buf) {
311
431
  }
312
432
  function addressToScriptHash(address) {
313
433
  const decoded = decodeBech32(address);
314
- if (!decoded) throw new Error("Invalid bech32 address: " + address);
434
+ if (!decoded) throw new SphereError("Invalid bech32 address: " + address, "VALIDATION_ERROR");
315
435
  const scriptHex = "0014" + bytesToHex(decoded.data);
316
436
  const sha = CryptoJS.SHA256(CryptoJS.enc.Hex.parse(scriptHex)).toString();
317
437
  return sha.match(/../g).reverse().join("");
@@ -320,6 +440,7 @@ var init_addressToScriptHash = __esm({
320
440
  "l1/addressToScriptHash.ts"() {
321
441
  "use strict";
322
442
  init_bech32();
443
+ init_errors();
323
444
  }
324
445
  });
325
446
 
@@ -379,7 +500,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
379
500
  try {
380
501
  ws = new WebSocket(endpoint);
381
502
  } catch (err) {
382
- console.error("[L1] WebSocket constructor threw exception:", err);
503
+ logger.error("L1", "WebSocket constructor threw exception:", err);
383
504
  isConnecting = false;
384
505
  reject(err);
385
506
  return;
@@ -415,7 +536,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
415
536
  return;
416
537
  }
417
538
  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
418
- console.error("[L1] Max reconnect attempts reached. Giving up.");
539
+ logger.error("L1", "Max reconnect attempts reached. Giving up.");
419
540
  isConnecting = false;
420
541
  const error = new Error("Max reconnect attempts reached");
421
542
  connectionCallbacks.forEach((cb) => {
@@ -431,8 +552,9 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
431
552
  }
432
553
  const delay = Math.min(BASE_DELAY * Math.pow(2, reconnectAttempts), MAX_DELAY);
433
554
  reconnectAttempts++;
434
- console.warn(
435
- `[L1] WebSocket closed unexpectedly. Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`
555
+ logger.warn(
556
+ "L1",
557
+ `WebSocket closed unexpectedly. Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`
436
558
  );
437
559
  setTimeout(() => {
438
560
  connect(endpoint).then(() => {
@@ -449,7 +571,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
449
571
  }, delay);
450
572
  };
451
573
  ws.onerror = (err) => {
452
- console.error("[L1] WebSocket error:", err);
574
+ logger.error("L1", "WebSocket error:", err);
453
575
  };
454
576
  ws.onmessage = (msg) => handleMessage(msg);
455
577
  });
@@ -507,7 +629,7 @@ async function getUtxo(address) {
507
629
  const scripthash = addressToScriptHash(address);
508
630
  const result = await rpc("blockchain.scripthash.listunspent", [scripthash]);
509
631
  if (!Array.isArray(result)) {
510
- console.warn("listunspent returned non-array:", result);
632
+ logger.warn("L1", "listunspent returned non-array:", result);
511
633
  return [];
512
634
  }
513
635
  return result.map((u) => ({
@@ -559,7 +681,7 @@ async function getTransactionHistory(address) {
559
681
  const scriptHash = addressToScriptHash(address);
560
682
  const result = await rpc("blockchain.scripthash.get_history", [scriptHash]);
561
683
  if (!Array.isArray(result)) {
562
- console.warn("get_history returned non-array:", result);
684
+ logger.warn("L1", "get_history returned non-array:", result);
563
685
  return [];
564
686
  }
565
687
  return result;
@@ -575,7 +697,7 @@ async function getCurrentBlockHeight() {
575
697
  const header = await rpc("blockchain.headers.subscribe", []);
576
698
  return header?.height || 0;
577
699
  } catch (err) {
578
- console.error("Error getting current block height:", err);
700
+ logger.error("L1", "Error getting current block height:", err);
579
701
  return 0;
580
702
  }
581
703
  }
@@ -604,6 +726,7 @@ var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose
604
726
  var init_network = __esm({
605
727
  "l1/network.ts"() {
606
728
  "use strict";
729
+ init_logger();
607
730
  init_addressToScriptHash();
608
731
  init_constants();
609
732
  DEFAULT_ENDPOINT = DEFAULT_ELECTRUM_URL;
@@ -626,7 +749,12 @@ var init_network = __esm({
626
749
  }
627
750
  });
628
751
 
752
+ // core/Sphere.ts
753
+ init_logger();
754
+ init_errors();
755
+
629
756
  // modules/payments/L1PaymentsModule.ts
757
+ init_errors();
630
758
  init_constants();
631
759
 
632
760
  // l1/index.ts
@@ -635,6 +763,7 @@ init_addressToScriptHash();
635
763
 
636
764
  // core/crypto.ts
637
765
  init_bech32();
766
+ init_errors();
638
767
  import * as bip39 from "bip39";
639
768
  import CryptoJS2 from "crypto-js";
640
769
  import elliptic from "elliptic";
@@ -672,7 +801,7 @@ function generateMasterKey(seedHex) {
672
801
  const IR = I.substring(64);
673
802
  const masterKeyBigInt = BigInt("0x" + IL);
674
803
  if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {
675
- throw new Error("Invalid master key generated");
804
+ throw new SphereError("Invalid master key generated", "VALIDATION_ERROR");
676
805
  }
677
806
  return {
678
807
  privateKey: IL,
@@ -700,11 +829,11 @@ function deriveChildKey(parentPrivKey, parentChainCode, index) {
700
829
  const ilBigInt = BigInt("0x" + IL);
701
830
  const parentKeyBigInt = BigInt("0x" + parentPrivKey);
702
831
  if (ilBigInt >= CURVE_ORDER) {
703
- throw new Error("Invalid key: IL >= curve order");
832
+ throw new SphereError("Invalid key: IL >= curve order", "VALIDATION_ERROR");
704
833
  }
705
834
  const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;
706
835
  if (childKeyBigInt === 0n) {
707
- throw new Error("Invalid key: child key is zero");
836
+ throw new SphereError("Invalid key: child key is zero", "VALIDATION_ERROR");
708
837
  }
709
838
  const childPrivKey = childKeyBigInt.toString(16).padStart(64, "0");
710
839
  return {
@@ -790,14 +919,14 @@ function randomBytes(length) {
790
919
  }
791
920
  async function identityFromMnemonic(mnemonic, passphrase = "") {
792
921
  if (!validateMnemonic2(mnemonic)) {
793
- throw new Error("Invalid mnemonic phrase");
922
+ throw new SphereError("Invalid mnemonic phrase", "INVALID_IDENTITY");
794
923
  }
795
924
  const seedHex = await mnemonicToSeed2(mnemonic, passphrase);
796
925
  return generateMasterKey(seedHex);
797
926
  }
798
927
  function identityFromMnemonicSync(mnemonic, passphrase = "") {
799
928
  if (!validateMnemonic2(mnemonic)) {
800
- throw new Error("Invalid mnemonic phrase");
929
+ throw new SphereError("Invalid mnemonic phrase", "INVALID_IDENTITY");
801
930
  }
802
931
  const seedHex = mnemonicToSeedSync2(mnemonic, passphrase);
803
932
  return generateMasterKey(seedHex);
@@ -845,12 +974,19 @@ function generateAddressFromMasterKey(masterPrivateKey, index) {
845
974
  init_network();
846
975
 
847
976
  // l1/tx.ts
977
+ init_logger();
978
+ init_errors();
848
979
  init_network();
849
980
  init_bech32();
850
981
  import CryptoJS5 from "crypto-js";
851
982
  import elliptic2 from "elliptic";
852
983
 
984
+ // l1/vestingState.ts
985
+ init_logger();
986
+ init_errors();
987
+
853
988
  // l1/vesting.ts
989
+ init_logger();
854
990
  init_network();
855
991
  var VESTING_THRESHOLD = 28e4;
856
992
  var currentBlockHeight = null;
@@ -1093,7 +1229,7 @@ var VestingClassifier = class {
1093
1229
  await new Promise((resolve) => {
1094
1230
  const req = indexedDB.deleteDatabase(this.dbName);
1095
1231
  const timer = setTimeout(() => {
1096
- console.warn(`[VestingClassifier] destroy: deleteDatabase timed out for ${this.dbName}`);
1232
+ logger.warn("L1", ` destroy: deleteDatabase timed out for ${this.dbName}`);
1097
1233
  resolve();
1098
1234
  }, 3e3);
1099
1235
  req.onsuccess = () => {
@@ -1105,7 +1241,7 @@ var VestingClassifier = class {
1105
1241
  resolve();
1106
1242
  };
1107
1243
  req.onblocked = () => {
1108
- console.warn(`[VestingClassifier] destroy: deleteDatabase blocked for ${this.dbName}, waiting...`);
1244
+ logger.warn("L1", ` destroy: deleteDatabase blocked for ${this.dbName}, waiting...`);
1109
1245
  };
1110
1246
  });
1111
1247
  }
@@ -1123,7 +1259,7 @@ var VestingStateManager = class {
1123
1259
  */
1124
1260
  setMode(mode) {
1125
1261
  if (!["all", "vested", "unvested"].includes(mode)) {
1126
- throw new Error(`Invalid vesting mode: ${mode}`);
1262
+ throw new SphereError(`Invalid vesting mode: ${mode}`, "VALIDATION_ERROR");
1127
1263
  }
1128
1264
  this.currentMode = mode;
1129
1265
  }
@@ -1160,10 +1296,10 @@ var VestingStateManager = class {
1160
1296
  }
1161
1297
  });
1162
1298
  if (result.errors.length > 0) {
1163
- console.warn(`Vesting classification errors: ${result.errors.length}`);
1299
+ logger.warn("L1", `Vesting classification errors: ${result.errors.length}`);
1164
1300
  result.errors.slice(0, 5).forEach((err) => {
1165
1301
  const txHash = err.utxo.tx_hash || err.utxo.txid;
1166
- console.warn(` ${txHash}: ${err.error}`);
1302
+ logger.warn("L1", ` ${txHash}: ${err.error}`);
1167
1303
  });
1168
1304
  }
1169
1305
  } finally {
@@ -1240,6 +1376,7 @@ var VestingStateManager = class {
1240
1376
  var vestingState = new VestingStateManager();
1241
1377
 
1242
1378
  // l1/addressHelpers.ts
1379
+ init_errors();
1243
1380
  var WalletAddressHelper = class {
1244
1381
  /**
1245
1382
  * Find address by BIP32 derivation path
@@ -1285,16 +1422,17 @@ var WalletAddressHelper = class {
1285
1422
  */
1286
1423
  static add(wallet, newAddress) {
1287
1424
  if (!newAddress.path) {
1288
- throw new Error("Cannot add address without a path");
1425
+ throw new SphereError("Cannot add address without a path", "INVALID_CONFIG");
1289
1426
  }
1290
1427
  const existing = this.findByPath(wallet, newAddress.path);
1291
1428
  if (existing) {
1292
1429
  if (existing.address !== newAddress.address) {
1293
- throw new Error(
1430
+ throw new SphereError(
1294
1431
  `CRITICAL: Attempted to overwrite address for path ${newAddress.path}
1295
1432
  Existing: ${existing.address}
1296
1433
  New: ${newAddress.address}
1297
- This indicates master key corruption or derivation logic error.`
1434
+ This indicates master key corruption or derivation logic error.`,
1435
+ "INVALID_CONFIG"
1298
1436
  );
1299
1437
  }
1300
1438
  return wallet;
@@ -1353,9 +1491,10 @@ This indicates master key corruption or derivation logic error.`
1353
1491
  const uniquePaths = new Set(paths);
1354
1492
  if (paths.length !== uniquePaths.size) {
1355
1493
  const duplicates = paths.filter((p, i) => paths.indexOf(p) !== i);
1356
- throw new Error(
1494
+ throw new SphereError(
1357
1495
  `CRITICAL: Wallet has duplicate paths: ${duplicates.join(", ")}
1358
- This indicates data corruption. Please restore from backup.`
1496
+ This indicates data corruption. Please restore from backup.`,
1497
+ "INVALID_CONFIG"
1359
1498
  );
1360
1499
  }
1361
1500
  }
@@ -1387,11 +1526,11 @@ var DUST = 546;
1387
1526
  var SAT = 1e8;
1388
1527
  function createScriptPubKey(address) {
1389
1528
  if (!address || typeof address !== "string") {
1390
- throw new Error("Invalid address: must be a string");
1529
+ throw new SphereError("Invalid address: must be a string", "VALIDATION_ERROR");
1391
1530
  }
1392
1531
  const decoded = decodeBech32(address);
1393
1532
  if (!decoded) {
1394
- throw new Error("Invalid bech32 address: " + address);
1533
+ throw new SphereError("Invalid bech32 address: " + address, "VALIDATION_ERROR");
1395
1534
  }
1396
1535
  const dataHex = Array.from(decoded.data).map((byte) => byte.toString(16).padStart(2, "0")).join("");
1397
1536
  return "0014" + dataHex;
@@ -1515,7 +1654,7 @@ function createAndSignTransaction(wallet, txPlan) {
1515
1654
  privateKeyHex = wallet.masterPrivateKey;
1516
1655
  }
1517
1656
  if (!privateKeyHex) {
1518
- throw new Error("No private key available for address: " + fromAddress);
1657
+ throw new SphereError("No private key available for address: " + fromAddress, "INVALID_CONFIG");
1519
1658
  }
1520
1659
  const keyPair = ec2.keyFromPrivate(privateKeyHex, "hex");
1521
1660
  const publicKey = keyPair.getPublic(true, "hex");
@@ -1614,7 +1753,7 @@ function collectUtxosForAmount(utxoList, amountSats, recipientAddress, senderAdd
1614
1753
  }
1615
1754
  async function createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress) {
1616
1755
  if (!decodeBech32(toAddress)) {
1617
- throw new Error("Invalid recipient address");
1756
+ throw new SphereError("Invalid recipient address", "INVALID_RECIPIENT");
1618
1757
  }
1619
1758
  const defaultAddr = WalletAddressHelper.getDefault(wallet);
1620
1759
  const senderAddress = fromAddress || defaultAddr.address;
@@ -1623,21 +1762,21 @@ async function createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress
1623
1762
  const currentMode = vestingState.getMode();
1624
1763
  if (vestingState.hasClassifiedData(senderAddress)) {
1625
1764
  utxos = vestingState.getFilteredUtxos(senderAddress);
1626
- console.log(`Using ${utxos.length} ${currentMode} UTXOs`);
1765
+ logger.debug("L1", `Using ${utxos.length} ${currentMode} UTXOs`);
1627
1766
  } else {
1628
1767
  utxos = await getUtxo(senderAddress);
1629
- console.log(`Using ${utxos.length} UTXOs (vesting not classified yet)`);
1768
+ logger.debug("L1", `Using ${utxos.length} UTXOs (vesting not classified yet)`);
1630
1769
  }
1631
1770
  if (!Array.isArray(utxos) || utxos.length === 0) {
1632
1771
  const modeText = currentMode !== "all" ? ` (${currentMode} coins)` : "";
1633
- throw new Error(`No UTXOs available${modeText} for address: ` + senderAddress);
1772
+ throw new SphereError(`No UTXOs available${modeText} for address: ` + senderAddress, "INSUFFICIENT_BALANCE");
1634
1773
  }
1635
1774
  return collectUtxosForAmount(utxos, amountSats, toAddress, senderAddress);
1636
1775
  }
1637
1776
  async function sendAlpha(wallet, toAddress, amountAlpha, fromAddress) {
1638
1777
  const plan = await createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress);
1639
1778
  if (!plan.success) {
1640
- throw new Error(plan.error || "Transaction planning failed");
1779
+ throw new SphereError(plan.error || "Transaction planning failed", "TRANSFER_FAILED");
1641
1780
  }
1642
1781
  const results = [];
1643
1782
  for (const tx of plan.transactions) {
@@ -1704,7 +1843,7 @@ var L1PaymentsModule = class {
1704
1843
  */
1705
1844
  async ensureConnected() {
1706
1845
  if (this._disabled) {
1707
- throw new Error("L1 provider is disabled");
1846
+ throw new SphereError("L1 provider is disabled", "NOT_INITIALIZED");
1708
1847
  }
1709
1848
  if (!isWebSocketConnected() && this._config.electrumUrl) {
1710
1849
  await connect(this._config.electrumUrl);
@@ -1759,8 +1898,9 @@ var L1PaymentsModule = class {
1759
1898
  const l1Address = await this.resolveNametagToL1Address(recipient);
1760
1899
  return l1Address;
1761
1900
  } catch {
1762
- throw new Error(
1763
- `Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
1901
+ throw new SphereError(
1902
+ `Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`,
1903
+ "INVALID_RECIPIENT"
1764
1904
  );
1765
1905
  }
1766
1906
  }
@@ -1769,15 +1909,16 @@ var L1PaymentsModule = class {
1769
1909
  */
1770
1910
  async resolveNametagToL1Address(nametag) {
1771
1911
  if (!this._transport?.resolve) {
1772
- throw new Error("Transport provider does not support resolution");
1912
+ throw new SphereError("Transport provider does not support resolution", "TRANSPORT_ERROR");
1773
1913
  }
1774
1914
  const info = await this._transport.resolve(nametag);
1775
1915
  if (!info) {
1776
- throw new Error(`Nametag not found: ${nametag}`);
1916
+ throw new SphereError(`Nametag not found: ${nametag}`, "INVALID_RECIPIENT");
1777
1917
  }
1778
1918
  if (!info.l1Address) {
1779
- throw new Error(
1780
- `Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
1919
+ throw new SphereError(
1920
+ `Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`,
1921
+ "INVALID_RECIPIENT"
1781
1922
  );
1782
1923
  }
1783
1924
  return info.l1Address;
@@ -2047,7 +2188,7 @@ var L1PaymentsModule = class {
2047
2188
  }
2048
2189
  ensureInitialized() {
2049
2190
  if (!this._initialized) {
2050
- throw new Error("L1PaymentsModule not initialized");
2191
+ throw new SphereError("L1PaymentsModule not initialized", "NOT_INITIALIZED");
2051
2192
  }
2052
2193
  }
2053
2194
  _getWatchedAddresses() {
@@ -2069,6 +2210,7 @@ var L1PaymentsModule = class {
2069
2210
  };
2070
2211
 
2071
2212
  // modules/payments/TokenSplitCalculator.ts
2213
+ init_logger();
2072
2214
  import { Token as SdkToken } from "@unicitylabs/state-transition-sdk/lib/token/Token";
2073
2215
  import { CoinId } from "@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId";
2074
2216
  var TokenSplitCalculator = class {
@@ -2091,7 +2233,7 @@ var TokenSplitCalculator = class {
2091
2233
  const sdkToken = await SdkToken.fromJSON(parsed);
2092
2234
  const realAmount = this.getTokenBalance(sdkToken, targetCoinIdHex);
2093
2235
  if (realAmount <= 0n) {
2094
- console.warn(`[SplitCalculator] Token ${t.id} has 0 balance for coinId ${targetCoinIdHex}`);
2236
+ logger.warn("TokenSplit", `Token ${t.id} has 0 balance for coinId ${targetCoinIdHex}`);
2095
2237
  continue;
2096
2238
  }
2097
2239
  candidates.push({
@@ -2100,14 +2242,15 @@ var TokenSplitCalculator = class {
2100
2242
  uiToken: t
2101
2243
  });
2102
2244
  } catch (e) {
2103
- console.warn("[SplitCalculator] Failed to parse token", t.id, e);
2245
+ logger.warn("TokenSplit", "Failed to parse token", t.id, e);
2104
2246
  }
2105
2247
  }
2106
2248
  candidates.sort((a, b) => a.amount < b.amount ? -1 : 1);
2107
2249
  const totalAvailable = candidates.reduce((sum, t) => sum + t.amount, 0n);
2108
2250
  if (totalAvailable < targetAmount) {
2109
- console.error(
2110
- `[SplitCalculator] Insufficient funds. Available: ${totalAvailable}, Required: ${targetAmount}`
2251
+ logger.error(
2252
+ "TokenSplit",
2253
+ `Insufficient funds. Available: ${totalAvailable}, Required: ${targetAmount}`
2111
2254
  );
2112
2255
  return null;
2113
2256
  }
@@ -2205,6 +2348,8 @@ var TokenSplitCalculator = class {
2205
2348
  };
2206
2349
 
2207
2350
  // modules/payments/TokenSplitExecutor.ts
2351
+ init_logger();
2352
+ init_errors();
2208
2353
  import { Token } from "@unicitylabs/state-transition-sdk/lib/token/Token";
2209
2354
  import { TokenId } from "@unicitylabs/state-transition-sdk/lib/token/TokenId";
2210
2355
  import { TokenState } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
@@ -2244,7 +2389,7 @@ var TokenSplitExecutor = class {
2244
2389
  }
2245
2390
  async executeSplit(tokenToSplit, splitAmount, remainderAmount, coinIdHex, recipientAddress) {
2246
2391
  const tokenIdHex = toHex(tokenToSplit.id.bytes);
2247
- console.log(`[TokenSplitExecutor] Splitting token ${tokenIdHex.slice(0, 8)}...`);
2392
+ logger.debug("TokenSplit", `Splitting token ${tokenIdHex.slice(0, 8)}...`);
2248
2393
  const coinId = new CoinId2(fromHex(coinIdHex));
2249
2394
  const seedString = `${tokenIdHex}_${splitAmount.toString()}_${remainderAmount.toString()}`;
2250
2395
  const recipientTokenId = new TokenId(await sha2562(seedString));
@@ -2264,23 +2409,23 @@ var TokenSplitExecutor = class {
2264
2409
  const coinDataB = TokenCoinData.create([[coinId, remainderAmount]]);
2265
2410
  builder.createToken(senderTokenId, tokenToSplit.type, new Uint8Array(0), coinDataB, senderAddress, senderSalt, null);
2266
2411
  const split = await builder.build(tokenToSplit);
2267
- console.log("[TokenSplitExecutor] Step 1: Burning original token...");
2412
+ logger.debug("TokenSplit", "Step 1: Burning original token...");
2268
2413
  const burnSalt = await sha2562(seedString + "_burn_salt");
2269
2414
  const burnCommitment = await split.createBurnCommitment(burnSalt, this.signingService);
2270
2415
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
2271
2416
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
2272
- throw new Error(`Burn failed: ${burnResponse.status}`);
2417
+ throw new SphereError(`Burn failed: ${burnResponse.status}`, "TRANSFER_FAILED");
2273
2418
  }
2274
2419
  const burnInclusionProof = await waitInclusionProof(this.trustBase, this.client, burnCommitment);
2275
2420
  const burnTransaction = burnCommitment.toTransaction(burnInclusionProof);
2276
- console.log("[TokenSplitExecutor] Original token burned.");
2277
- console.log("[TokenSplitExecutor] Step 2: Minting split tokens...");
2421
+ logger.debug("TokenSplit", "Original token burned.");
2422
+ logger.debug("TokenSplit", "Step 2: Minting split tokens...");
2278
2423
  const mintCommitments = await split.createSplitMintCommitments(this.trustBase, burnTransaction);
2279
2424
  const mintedTokensInfo = [];
2280
2425
  for (const commitment of mintCommitments) {
2281
2426
  const res = await this.client.submitMintCommitment(commitment);
2282
2427
  if (res.status !== "SUCCESS" && res.status !== "REQUEST_ID_EXISTS") {
2283
- throw new Error(`Mint split token failed: ${res.status}`);
2428
+ throw new SphereError(`Mint split token failed: ${res.status}`, "TRANSFER_FAILED");
2284
2429
  }
2285
2430
  const proof = await waitInclusionProof(this.trustBase, this.client, commitment);
2286
2431
  const commTokenIdHex = toHex(commitment.transactionData.tokenId.bytes);
@@ -2293,7 +2438,7 @@ var TokenSplitExecutor = class {
2293
2438
  salt: commitment.transactionData.salt
2294
2439
  });
2295
2440
  }
2296
- console.log("[TokenSplitExecutor] Split tokens minted.");
2441
+ logger.debug("TokenSplit", "Split tokens minted.");
2297
2442
  const recipientInfo = mintedTokensInfo.find((t) => t.isForRecipient);
2298
2443
  const senderInfo = mintedTokensInfo.find((t) => !t.isForRecipient);
2299
2444
  const createToken = async (info, label) => {
@@ -2301,12 +2446,12 @@ var TokenSplitExecutor = class {
2301
2446
  const state = new TokenState(predicate, null);
2302
2447
  const token = await Token.mint(this.trustBase, state, info.commitment.toTransaction(info.inclusionProof));
2303
2448
  const verification = await token.verify(this.trustBase);
2304
- if (!verification.isSuccessful) throw new Error(`Token verification failed: ${label}`);
2449
+ if (!verification.isSuccessful) throw new SphereError(`Token verification failed: ${label}`, "TRANSFER_FAILED");
2305
2450
  return token;
2306
2451
  };
2307
2452
  const recipientTokenBeforeTransfer = await createToken(recipientInfo, "Recipient");
2308
2453
  const senderToken = await createToken(senderInfo, "Sender");
2309
- console.log("[TokenSplitExecutor] Step 3: Transferring to recipient...");
2454
+ logger.debug("TokenSplit", "Step 3: Transferring to recipient...");
2310
2455
  const transferSalt = await sha2562(seedString + "_transfer_salt");
2311
2456
  const transferCommitment = await TransferCommitment.create(
2312
2457
  recipientTokenBeforeTransfer,
@@ -2318,11 +2463,11 @@ var TokenSplitExecutor = class {
2318
2463
  );
2319
2464
  const transferRes = await this.client.submitTransferCommitment(transferCommitment);
2320
2465
  if (transferRes.status !== "SUCCESS" && transferRes.status !== "REQUEST_ID_EXISTS") {
2321
- throw new Error(`Transfer failed: ${transferRes.status}`);
2466
+ throw new SphereError(`Transfer failed: ${transferRes.status}`, "TRANSFER_FAILED");
2322
2467
  }
2323
2468
  const transferProof = await waitInclusionProof(this.trustBase, this.client, transferCommitment);
2324
2469
  const transferTx = transferCommitment.toTransaction(transferProof);
2325
- console.log("[TokenSplitExecutor] Split transfer complete!");
2470
+ logger.debug("TokenSplit", "Split transfer complete!");
2326
2471
  return {
2327
2472
  tokenForRecipient: recipientTokenBeforeTransfer,
2328
2473
  tokenForSender: senderToken,
@@ -2332,6 +2477,7 @@ var TokenSplitExecutor = class {
2332
2477
  };
2333
2478
 
2334
2479
  // modules/payments/NametagMinter.ts
2480
+ init_logger();
2335
2481
  import { Token as Token2 } from "@unicitylabs/state-transition-sdk/lib/token/Token";
2336
2482
  import { TokenId as TokenId2 } from "@unicitylabs/state-transition-sdk/lib/token/TokenId";
2337
2483
  import { TokenType } from "@unicitylabs/state-transition-sdk/lib/token/TokenType";
@@ -2356,10 +2502,8 @@ var NametagMinter = class {
2356
2502
  this.skipVerification = config.skipVerification ?? false;
2357
2503
  this.debug = config.debug ?? false;
2358
2504
  }
2359
- log(...args) {
2360
- if (this.debug) {
2361
- console.log("[NametagMinter]", ...args);
2362
- }
2505
+ log(message, ...args) {
2506
+ logger.debug("NametagMinter", message, ...args);
2363
2507
  }
2364
2508
  /**
2365
2509
  * Check if a nametag is available (not already minted)
@@ -2543,6 +2687,7 @@ function parseForkedKey(key) {
2543
2687
  }
2544
2688
 
2545
2689
  // registry/TokenRegistry.ts
2690
+ init_logger();
2546
2691
  init_constants();
2547
2692
  var FETCH_TIMEOUT_MS = 1e4;
2548
2693
  var TokenRegistry = class _TokenRegistry {
@@ -2764,14 +2909,12 @@ var TokenRegistry = class _TokenRegistry {
2764
2909
  clearTimeout(timer);
2765
2910
  }
2766
2911
  if (!response.ok) {
2767
- console.warn(
2768
- `[TokenRegistry] Remote fetch failed: HTTP ${response.status} ${response.statusText}`
2769
- );
2912
+ logger.warn("TokenRegistry", `Remote fetch failed: HTTP ${response.status} ${response.statusText}`);
2770
2913
  return false;
2771
2914
  }
2772
2915
  const data = await response.json();
2773
2916
  if (!this.isValidDefinitionsArray(data)) {
2774
- console.warn("[TokenRegistry] Remote data is not a valid token definitions array");
2917
+ logger.warn("TokenRegistry", "Remote data is not a valid token definitions array");
2775
2918
  return false;
2776
2919
  }
2777
2920
  const definitions = data;
@@ -2781,7 +2924,7 @@ var TokenRegistry = class _TokenRegistry {
2781
2924
  return true;
2782
2925
  } catch (error) {
2783
2926
  const message = error instanceof Error ? error.message : String(error);
2784
- console.warn(`[TokenRegistry] Remote refresh failed: ${message}`);
2927
+ logger.warn("TokenRegistry", `Remote refresh failed: ${message}`);
2785
2928
  return false;
2786
2929
  }
2787
2930
  }
@@ -3258,7 +3401,13 @@ function getCurrentStateHash(txf) {
3258
3401
  return void 0;
3259
3402
  }
3260
3403
 
3404
+ // modules/payments/PaymentsModule.ts
3405
+ init_logger();
3406
+ init_errors();
3407
+
3261
3408
  // modules/payments/InstantSplitExecutor.ts
3409
+ init_logger();
3410
+ init_errors();
3262
3411
  import { Token as Token3 } from "@unicitylabs/state-transition-sdk/lib/token/Token";
3263
3412
  import { TokenId as TokenId3 } from "@unicitylabs/state-transition-sdk/lib/token/TokenId";
3264
3413
  import { TokenState as TokenState3 } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
@@ -3314,7 +3463,7 @@ var InstantSplitExecutor = class {
3314
3463
  async buildSplitBundle(tokenToSplit, splitAmount, remainderAmount, coinIdHex, recipientAddress, options) {
3315
3464
  const splitGroupId = crypto.randomUUID();
3316
3465
  const tokenIdHex = toHex2(tokenToSplit.id.bytes);
3317
- console.log(`[InstantSplit] Building V5 bundle for token ${tokenIdHex.slice(0, 8)}...`);
3466
+ logger.debug("InstantSplit", `Building V5 bundle for token ${tokenIdHex.slice(0, 8)}...`);
3318
3467
  const coinId = new CoinId3(fromHex2(coinIdHex));
3319
3468
  const seedString = `${tokenIdHex}_${splitAmount.toString()}_${remainderAmount.toString()}_${Date.now()}`;
3320
3469
  const recipientTokenId = new TokenId3(await sha2563(seedString));
@@ -3351,19 +3500,19 @@ var InstantSplitExecutor = class {
3351
3500
  null
3352
3501
  );
3353
3502
  const split = await builder.build(tokenToSplit);
3354
- console.log("[InstantSplit] Step 1: Creating and submitting burn...");
3503
+ logger.debug("InstantSplit", "Step 1: Creating and submitting burn...");
3355
3504
  const burnSalt = await sha2563(seedString + "_burn_salt");
3356
3505
  const burnCommitment = await split.createBurnCommitment(burnSalt, this.signingService);
3357
3506
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
3358
3507
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
3359
- throw new Error(`Burn submission failed: ${burnResponse.status}`);
3508
+ throw new SphereError(`Burn submission failed: ${burnResponse.status}`, "TRANSFER_FAILED");
3360
3509
  }
3361
- console.log("[InstantSplit] Step 2: Waiting for burn proof...");
3510
+ logger.debug("InstantSplit", "Step 2: Waiting for burn proof...");
3362
3511
  const burnProof = this.devMode ? await this.waitInclusionProofWithDevBypass(burnCommitment, options?.burnProofTimeoutMs) : await waitInclusionProof3(this.trustBase, this.client, burnCommitment);
3363
3512
  const burnTransaction = burnCommitment.toTransaction(burnProof);
3364
- console.log(`[InstantSplit] Burn proof received`);
3513
+ logger.debug("InstantSplit", "Burn proof received");
3365
3514
  options?.onBurnCompleted?.(JSON.stringify(burnTransaction.toJSON()));
3366
- console.log("[InstantSplit] Step 3: Creating mint commitments...");
3515
+ logger.debug("InstantSplit", "Step 3: Creating mint commitments...");
3367
3516
  const mintCommitments = await split.createSplitMintCommitments(this.trustBase, burnTransaction);
3368
3517
  const recipientIdHex = toHex2(recipientTokenId.bytes);
3369
3518
  const senderIdHex = toHex2(senderTokenId.bytes);
@@ -3374,9 +3523,9 @@ var InstantSplitExecutor = class {
3374
3523
  (c) => toHex2(c.transactionData.tokenId.bytes) === senderIdHex
3375
3524
  );
3376
3525
  if (!recipientMintCommitment || !senderMintCommitment) {
3377
- throw new Error("Failed to find expected mint commitments");
3526
+ throw new SphereError("Failed to find expected mint commitments", "TRANSFER_FAILED");
3378
3527
  }
3379
- console.log("[InstantSplit] Step 4: Creating transfer commitment...");
3528
+ logger.debug("InstantSplit", "Step 4: Creating transfer commitment...");
3380
3529
  const transferSalt = await sha2563(seedString + "_transfer_salt");
3381
3530
  const transferCommitment = await this.createTransferCommitmentFromMintData(
3382
3531
  recipientMintCommitment.transactionData,
@@ -3392,7 +3541,7 @@ var InstantSplitExecutor = class {
3392
3541
  recipientSalt
3393
3542
  );
3394
3543
  const mintedState = new TokenState3(mintedPredicate, null);
3395
- console.log("[InstantSplit] Step 5: Packaging V5 bundle...");
3544
+ logger.debug("InstantSplit", "Step 5: Packaging V5 bundle...");
3396
3545
  const senderPubkey = toHex2(this.signingService.publicKey);
3397
3546
  let nametagTokenJson;
3398
3547
  const recipientAddressStr = recipientAddress.toString();
@@ -3464,7 +3613,7 @@ var InstantSplitExecutor = class {
3464
3613
  recipientAddress,
3465
3614
  options
3466
3615
  );
3467
- console.log("[InstantSplit] Sending via transport...");
3616
+ logger.debug("InstantSplit", "Sending via transport...");
3468
3617
  const senderPubkey = toHex2(this.signingService.publicKey);
3469
3618
  const nostrEventId = await transport.sendTokenTransfer(recipientPubkey, {
3470
3619
  token: JSON.stringify(buildResult.bundle),
@@ -3476,7 +3625,7 @@ var InstantSplitExecutor = class {
3476
3625
  }
3477
3626
  });
3478
3627
  const criticalPathDuration = performance.now() - startTime;
3479
- console.log(`[InstantSplit] V5 complete in ${criticalPathDuration.toFixed(0)}ms`);
3628
+ logger.debug("InstantSplit", `V5 complete in ${criticalPathDuration.toFixed(0)}ms`);
3480
3629
  options?.onNostrDelivered?.(nostrEventId);
3481
3630
  const backgroundPromise = buildResult.startBackground();
3482
3631
  return {
@@ -3490,7 +3639,7 @@ var InstantSplitExecutor = class {
3490
3639
  } catch (error) {
3491
3640
  const duration = performance.now() - startTime;
3492
3641
  const errorMessage = error instanceof Error ? error.message : String(error);
3493
- console.error(`[InstantSplit] Failed after ${duration.toFixed(0)}ms:`, error);
3642
+ logger.error("InstantSplit", `Failed after ${duration.toFixed(0)}ms:`, error);
3494
3643
  return {
3495
3644
  success: false,
3496
3645
  criticalPathDurationMs: duration,
@@ -3539,7 +3688,7 @@ var InstantSplitExecutor = class {
3539
3688
  * Then waits for sender's mint proof, reconstructs change token, and saves it.
3540
3689
  */
3541
3690
  submitBackgroundV5(senderMintCommitment, recipientMintCommitment, transferCommitment, context) {
3542
- console.log("[InstantSplit] Background: Starting parallel mint submission...");
3691
+ logger.debug("InstantSplit", "Background: Starting parallel mint submission...");
3543
3692
  const startTime = performance.now();
3544
3693
  const submissions = Promise.all([
3545
3694
  this.client.submitMintCommitment(senderMintCommitment).then((res) => ({ type: "senderMint", status: res.status })).catch((err) => ({ type: "senderMint", status: "ERROR", error: err })),
@@ -3548,14 +3697,14 @@ var InstantSplitExecutor = class {
3548
3697
  ]);
3549
3698
  return submissions.then(async (results) => {
3550
3699
  const submitDuration = performance.now() - startTime;
3551
- console.log(`[InstantSplit] Background: Submissions complete in ${submitDuration.toFixed(0)}ms`);
3700
+ logger.debug("InstantSplit", `Background: Submissions complete in ${submitDuration.toFixed(0)}ms`);
3552
3701
  context.onProgress?.({
3553
3702
  stage: "MINTS_SUBMITTED",
3554
3703
  message: `All commitments submitted in ${submitDuration.toFixed(0)}ms`
3555
3704
  });
3556
3705
  const senderMintResult = results.find((r) => r.type === "senderMint");
3557
3706
  if (senderMintResult?.status !== "SUCCESS" && senderMintResult?.status !== "REQUEST_ID_EXISTS") {
3558
- console.error("[InstantSplit] Background: Sender mint failed - cannot save change token");
3707
+ logger.error("InstantSplit", "Background: Sender mint failed - cannot save change token");
3559
3708
  context.onProgress?.({
3560
3709
  stage: "FAILED",
3561
3710
  message: "Sender mint submission failed",
@@ -3563,12 +3712,12 @@ var InstantSplitExecutor = class {
3563
3712
  });
3564
3713
  return;
3565
3714
  }
3566
- console.log("[InstantSplit] Background: Waiting for sender mint proof...");
3715
+ logger.debug("InstantSplit", "Background: Waiting for sender mint proof...");
3567
3716
  const proofStartTime = performance.now();
3568
3717
  try {
3569
3718
  const senderMintProof = this.devMode ? await this.waitInclusionProofWithDevBypass(senderMintCommitment) : await waitInclusionProof3(this.trustBase, this.client, senderMintCommitment);
3570
3719
  const proofDuration = performance.now() - proofStartTime;
3571
- console.log(`[InstantSplit] Background: Sender mint proof received in ${proofDuration.toFixed(0)}ms`);
3720
+ logger.debug("InstantSplit", `Background: Sender mint proof received in ${proofDuration.toFixed(0)}ms`);
3572
3721
  context.onProgress?.({
3573
3722
  stage: "MINTS_PROVEN",
3574
3723
  message: `Mint proof received in ${proofDuration.toFixed(0)}ms`
@@ -3586,38 +3735,38 @@ var InstantSplitExecutor = class {
3586
3735
  if (!this.devMode) {
3587
3736
  const verification = await changeToken.verify(this.trustBase);
3588
3737
  if (!verification.isSuccessful) {
3589
- throw new Error(`Change token verification failed`);
3738
+ throw new SphereError("Change token verification failed", "TRANSFER_FAILED");
3590
3739
  }
3591
3740
  }
3592
- console.log("[InstantSplit] Background: Change token created");
3741
+ logger.debug("InstantSplit", "Background: Change token created");
3593
3742
  context.onProgress?.({
3594
3743
  stage: "CHANGE_TOKEN_SAVED",
3595
3744
  message: "Change token created and verified"
3596
3745
  });
3597
3746
  if (context.onChangeTokenCreated) {
3598
3747
  await context.onChangeTokenCreated(changeToken);
3599
- console.log("[InstantSplit] Background: Change token saved");
3748
+ logger.debug("InstantSplit", "Background: Change token saved");
3600
3749
  }
3601
3750
  if (context.onStorageSync) {
3602
3751
  try {
3603
3752
  const syncSuccess = await context.onStorageSync();
3604
- console.log(`[InstantSplit] Background: Storage sync ${syncSuccess ? "completed" : "deferred"}`);
3753
+ logger.debug("InstantSplit", `Background: Storage sync ${syncSuccess ? "completed" : "deferred"}`);
3605
3754
  context.onProgress?.({
3606
3755
  stage: "STORAGE_SYNCED",
3607
3756
  message: syncSuccess ? "Storage synchronized" : "Sync deferred"
3608
3757
  });
3609
3758
  } catch (syncError) {
3610
- console.warn("[InstantSplit] Background: Storage sync error:", syncError);
3759
+ logger.warn("InstantSplit", "Background: Storage sync error:", syncError);
3611
3760
  }
3612
3761
  }
3613
3762
  const totalDuration = performance.now() - startTime;
3614
- console.log(`[InstantSplit] Background: Complete in ${totalDuration.toFixed(0)}ms`);
3763
+ logger.debug("InstantSplit", `Background: Complete in ${totalDuration.toFixed(0)}ms`);
3615
3764
  context.onProgress?.({
3616
3765
  stage: "COMPLETED",
3617
3766
  message: `Background processing complete in ${totalDuration.toFixed(0)}ms`
3618
3767
  });
3619
3768
  } catch (proofError) {
3620
- console.error("[InstantSplit] Background: Failed to get sender mint proof:", proofError);
3769
+ logger.error("InstantSplit", "Background: Failed to get sender mint proof:", proofError);
3621
3770
  context.onProgress?.({
3622
3771
  stage: "FAILED",
3623
3772
  message: "Failed to get mint proof",
@@ -3625,7 +3774,7 @@ var InstantSplitExecutor = class {
3625
3774
  });
3626
3775
  }
3627
3776
  }).catch((err) => {
3628
- console.error("[InstantSplit] Background: Submission batch failed:", err);
3777
+ logger.error("InstantSplit", "Background: Submission batch failed:", err);
3629
3778
  context.onProgress?.({
3630
3779
  stage: "FAILED",
3631
3780
  message: "Background submission failed",
@@ -3647,7 +3796,7 @@ var InstantSplitExecutor = class {
3647
3796
  )
3648
3797
  ]);
3649
3798
  } catch {
3650
- console.log("[InstantSplit] Dev mode: Using mock proof");
3799
+ logger.debug("InstantSplit", "Dev mode: Using mock proof");
3651
3800
  return {
3652
3801
  toJSON: () => ({ mock: true })
3653
3802
  };
@@ -3658,6 +3807,8 @@ var InstantSplitExecutor = class {
3658
3807
  };
3659
3808
 
3660
3809
  // modules/payments/InstantSplitProcessor.ts
3810
+ init_logger();
3811
+ init_errors();
3661
3812
  import { Token as Token4 } from "@unicitylabs/state-transition-sdk/lib/token/Token";
3662
3813
  import { TokenState as TokenState4 } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
3663
3814
  import { TokenType as TokenType2 } from "@unicitylabs/state-transition-sdk/lib/token/TokenType";
@@ -3752,27 +3903,27 @@ var InstantSplitProcessor = class {
3752
3903
  * 5. Create recipient's final state and finalize token
3753
3904
  */
3754
3905
  async processV5Bundle(bundle, signingService, senderPubkey, options) {
3755
- console.log("[InstantSplitProcessor] Processing V5 bundle...");
3906
+ logger.debug("InstantSplit", "Processing V5 bundle...");
3756
3907
  const startTime = performance.now();
3757
3908
  try {
3758
3909
  if (bundle.senderPubkey !== senderPubkey) {
3759
- console.warn("[InstantSplitProcessor] Sender pubkey mismatch (non-fatal)");
3910
+ logger.warn("InstantSplit", "Sender pubkey mismatch (non-fatal)");
3760
3911
  }
3761
3912
  const burnTxJson = JSON.parse(bundle.burnTransaction);
3762
3913
  const _burnTransaction = await TransferTransaction.fromJSON(burnTxJson);
3763
- console.log("[InstantSplitProcessor] Burn transaction validated");
3914
+ logger.debug("InstantSplit", "Burn transaction validated");
3764
3915
  const mintDataJson = JSON.parse(bundle.recipientMintData);
3765
3916
  const mintData = await MintTransactionData2.fromJSON(mintDataJson);
3766
3917
  const mintCommitment = await MintCommitment2.create(mintData);
3767
- console.log("[InstantSplitProcessor] Mint commitment recreated");
3918
+ logger.debug("InstantSplit", "Mint commitment recreated");
3768
3919
  const mintResponse = await this.client.submitMintCommitment(mintCommitment);
3769
3920
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
3770
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
3921
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
3771
3922
  }
3772
- console.log(`[InstantSplitProcessor] Mint submitted: ${mintResponse.status}`);
3923
+ logger.debug("InstantSplit", `Mint submitted: ${mintResponse.status}`);
3773
3924
  const mintProof = this.devMode ? await this.waitInclusionProofWithDevBypass(mintCommitment, options?.proofTimeoutMs) : await waitInclusionProof4(this.trustBase, this.client, mintCommitment);
3774
3925
  const mintTransaction = mintCommitment.toTransaction(mintProof);
3775
- console.log("[InstantSplitProcessor] Mint proof received");
3926
+ logger.debug("InstantSplit", "Mint proof received");
3776
3927
  const tokenType = new TokenType2(fromHex3(bundle.tokenTypeHex));
3777
3928
  const senderMintedStateJson = JSON.parse(bundle.mintedTokenStateJson);
3778
3929
  const tokenJson = {
@@ -3783,17 +3934,17 @@ var InstantSplitProcessor = class {
3783
3934
  nametags: []
3784
3935
  };
3785
3936
  const mintedToken = await Token4.fromJSON(tokenJson);
3786
- console.log("[InstantSplitProcessor] Minted token reconstructed from sender state");
3937
+ logger.debug("InstantSplit", "Minted token reconstructed from sender state");
3787
3938
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
3788
3939
  const transferCommitment = await TransferCommitment3.fromJSON(transferCommitmentJson);
3789
3940
  const transferResponse = await this.client.submitTransferCommitment(transferCommitment);
3790
3941
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
3791
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
3942
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
3792
3943
  }
3793
- console.log(`[InstantSplitProcessor] Transfer submitted: ${transferResponse.status}`);
3944
+ logger.debug("InstantSplit", `Transfer submitted: ${transferResponse.status}`);
3794
3945
  const transferProof = this.devMode ? await this.waitInclusionProofWithDevBypass(transferCommitment, options?.proofTimeoutMs) : await waitInclusionProof4(this.trustBase, this.client, transferCommitment);
3795
3946
  const transferTransaction = transferCommitment.toTransaction(transferProof);
3796
- console.log("[InstantSplitProcessor] Transfer proof received");
3947
+ logger.debug("InstantSplit", "Transfer proof received");
3797
3948
  const transferSalt = fromHex3(bundle.transferSaltHex);
3798
3949
  const finalRecipientPredicate = await UnmaskedPredicate4.create(
3799
3950
  mintData.tokenId,
@@ -3803,42 +3954,43 @@ var InstantSplitProcessor = class {
3803
3954
  transferSalt
3804
3955
  );
3805
3956
  const finalRecipientState = new TokenState4(finalRecipientPredicate, null);
3806
- console.log("[InstantSplitProcessor] Final recipient state created");
3957
+ logger.debug("InstantSplit", "Final recipient state created");
3807
3958
  let nametagTokens = [];
3808
3959
  const recipientAddressStr = bundle.recipientAddressJson;
3809
3960
  if (recipientAddressStr.startsWith("PROXY://")) {
3810
- console.log("[InstantSplitProcessor] PROXY address detected, finding nametag token...");
3961
+ logger.debug("InstantSplit", "PROXY address detected, finding nametag token...");
3811
3962
  if (bundle.nametagTokenJson) {
3812
3963
  try {
3813
3964
  const nametagToken = await Token4.fromJSON(JSON.parse(bundle.nametagTokenJson));
3814
3965
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
3815
3966
  const proxy = await ProxyAddress.fromTokenId(nametagToken.id);
3816
3967
  if (proxy.address !== recipientAddressStr) {
3817
- console.warn("[InstantSplitProcessor] Nametag PROXY address mismatch, ignoring bundle token");
3968
+ logger.warn("InstantSplit", "Nametag PROXY address mismatch, ignoring bundle token");
3818
3969
  } else {
3819
3970
  nametagTokens = [nametagToken];
3820
- console.log("[InstantSplitProcessor] Using nametag token from bundle (address validated)");
3971
+ logger.debug("InstantSplit", "Using nametag token from bundle (address validated)");
3821
3972
  }
3822
3973
  } catch (err) {
3823
- console.warn("[InstantSplitProcessor] Failed to parse nametag token from bundle:", err);
3974
+ logger.warn("InstantSplit", "Failed to parse nametag token from bundle:", err);
3824
3975
  }
3825
3976
  }
3826
3977
  if (nametagTokens.length === 0 && options?.findNametagToken) {
3827
3978
  const token = await options.findNametagToken(recipientAddressStr);
3828
3979
  if (token) {
3829
3980
  nametagTokens = [token];
3830
- console.log("[InstantSplitProcessor] Found nametag token via callback");
3981
+ logger.debug("InstantSplit", "Found nametag token via callback");
3831
3982
  }
3832
3983
  }
3833
3984
  if (nametagTokens.length === 0 && !this.devMode) {
3834
- throw new Error(
3835
- `PROXY address transfer requires nametag token for verification. Address: ${recipientAddressStr}`
3985
+ throw new SphereError(
3986
+ `PROXY address transfer requires nametag token for verification. Address: ${recipientAddressStr}`,
3987
+ "TRANSFER_FAILED"
3836
3988
  );
3837
3989
  }
3838
3990
  }
3839
3991
  let finalToken;
3840
3992
  if (this.devMode) {
3841
- console.log("[InstantSplitProcessor] Dev mode: finalizing without verification");
3993
+ logger.debug("InstantSplit", "Dev mode: finalizing without verification");
3842
3994
  const tokenJson2 = mintedToken.toJSON();
3843
3995
  tokenJson2.state = finalRecipientState.toJSON();
3844
3996
  tokenJson2.transactions = [transferTransaction.toJSON()];
@@ -3852,16 +4004,16 @@ var InstantSplitProcessor = class {
3852
4004
  nametagTokens
3853
4005
  );
3854
4006
  }
3855
- console.log("[InstantSplitProcessor] Token finalized");
4007
+ logger.debug("InstantSplit", "Token finalized");
3856
4008
  if (!this.devMode) {
3857
4009
  const verification = await finalToken.verify(this.trustBase);
3858
4010
  if (!verification.isSuccessful) {
3859
- throw new Error(`Token verification failed`);
4011
+ throw new SphereError(`Token verification failed`, "TRANSFER_FAILED");
3860
4012
  }
3861
- console.log("[InstantSplitProcessor] Token verified");
4013
+ logger.debug("InstantSplit", "Token verified");
3862
4014
  }
3863
4015
  const duration = performance.now() - startTime;
3864
- console.log(`[InstantSplitProcessor] V5 bundle processed in ${duration.toFixed(0)}ms`);
4016
+ logger.debug("InstantSplit", `V5 bundle processed in ${duration.toFixed(0)}ms`);
3865
4017
  return {
3866
4018
  success: true,
3867
4019
  token: finalToken,
@@ -3870,7 +4022,7 @@ var InstantSplitProcessor = class {
3870
4022
  } catch (error) {
3871
4023
  const duration = performance.now() - startTime;
3872
4024
  const errorMessage = error instanceof Error ? error.message : String(error);
3873
- console.error(`[InstantSplitProcessor] V5 processing failed:`, error);
4025
+ logger.error("InstantSplit", "V5 processing failed:", error);
3874
4026
  return {
3875
4027
  success: false,
3876
4028
  error: errorMessage,
@@ -3896,30 +4048,30 @@ var InstantSplitProcessor = class {
3896
4048
  durationMs: 0
3897
4049
  };
3898
4050
  }
3899
- console.log("[InstantSplitProcessor] Processing V4 bundle (dev mode)...");
4051
+ logger.debug("InstantSplit", "Processing V4 bundle (dev mode)...");
3900
4052
  const startTime = performance.now();
3901
4053
  try {
3902
4054
  const burnCommitmentJson = JSON.parse(bundle.burnCommitment);
3903
4055
  const burnCommitment = await TransferCommitment3.fromJSON(burnCommitmentJson);
3904
4056
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
3905
4057
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
3906
- throw new Error(`Burn submission failed: ${burnResponse.status}`);
4058
+ throw new SphereError(`Burn submission failed: ${burnResponse.status}`, "TRANSFER_FAILED");
3907
4059
  }
3908
4060
  await this.waitInclusionProofWithDevBypass(burnCommitment, options?.proofTimeoutMs);
3909
- console.log("[InstantSplitProcessor] V4: Burn proof received");
4061
+ logger.debug("InstantSplit", "V4: Burn proof received");
3910
4062
  const mintDataJson = JSON.parse(bundle.recipientMintData);
3911
4063
  const mintData = await MintTransactionData2.fromJSON(mintDataJson);
3912
4064
  const mintCommitment = await MintCommitment2.create(mintData);
3913
4065
  const mintResponse = await this.client.submitMintCommitment(mintCommitment);
3914
4066
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
3915
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
4067
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
3916
4068
  }
3917
4069
  const mintProof = await this.waitInclusionProofWithDevBypass(
3918
4070
  mintCommitment,
3919
4071
  options?.proofTimeoutMs
3920
4072
  );
3921
4073
  const mintTransaction = mintCommitment.toTransaction(mintProof);
3922
- console.log("[InstantSplitProcessor] V4: Mint proof received");
4074
+ logger.debug("InstantSplit", "V4: Mint proof received");
3923
4075
  const tokenType = new TokenType2(fromHex3(bundle.tokenTypeHex));
3924
4076
  const recipientSalt = fromHex3(bundle.recipientSaltHex);
3925
4077
  const recipientPredicate = await UnmaskedPredicate4.create(
@@ -3938,19 +4090,19 @@ var InstantSplitProcessor = class {
3938
4090
  nametags: []
3939
4091
  };
3940
4092
  const mintedToken = await Token4.fromJSON(tokenJson);
3941
- console.log("[InstantSplitProcessor] V4: Minted token reconstructed");
4093
+ logger.debug("InstantSplit", "V4: Minted token reconstructed");
3942
4094
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
3943
4095
  const transferCommitment = await TransferCommitment3.fromJSON(transferCommitmentJson);
3944
4096
  const transferResponse = await this.client.submitTransferCommitment(transferCommitment);
3945
4097
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
3946
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
4098
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
3947
4099
  }
3948
4100
  const transferProof = await this.waitInclusionProofWithDevBypass(
3949
4101
  transferCommitment,
3950
4102
  options?.proofTimeoutMs
3951
4103
  );
3952
4104
  const transferTransaction = transferCommitment.toTransaction(transferProof);
3953
- console.log("[InstantSplitProcessor] V4: Transfer proof received");
4105
+ logger.debug("InstantSplit", "V4: Transfer proof received");
3954
4106
  const transferSalt = fromHex3(bundle.transferSaltHex);
3955
4107
  const finalPredicate = await UnmaskedPredicate4.create(
3956
4108
  mintData.tokenId,
@@ -3964,9 +4116,9 @@ var InstantSplitProcessor = class {
3964
4116
  finalTokenJson.state = finalState.toJSON();
3965
4117
  finalTokenJson.transactions = [transferTransaction.toJSON()];
3966
4118
  const finalToken = await Token4.fromJSON(finalTokenJson);
3967
- console.log("[InstantSplitProcessor] V4: Token finalized");
4119
+ logger.debug("InstantSplit", "V4: Token finalized");
3968
4120
  const duration = performance.now() - startTime;
3969
- console.log(`[InstantSplitProcessor] V4 bundle processed in ${duration.toFixed(0)}ms`);
4121
+ logger.debug("InstantSplit", `V4 bundle processed in ${duration.toFixed(0)}ms`);
3970
4122
  return {
3971
4123
  success: true,
3972
4124
  token: finalToken,
@@ -3975,7 +4127,7 @@ var InstantSplitProcessor = class {
3975
4127
  } catch (error) {
3976
4128
  const duration = performance.now() - startTime;
3977
4129
  const errorMessage = error instanceof Error ? error.message : String(error);
3978
- console.error(`[InstantSplitProcessor] V4 processing failed:`, error);
4130
+ logger.error("InstantSplit", "V4 processing failed:", error);
3979
4131
  return {
3980
4132
  success: false,
3981
4133
  error: errorMessage,
@@ -3996,7 +4148,7 @@ var InstantSplitProcessor = class {
3996
4148
  )
3997
4149
  ]);
3998
4150
  } catch {
3999
- console.log("[InstantSplitProcessor] Dev mode: Using mock proof");
4151
+ logger.debug("InstantSplit", "Dev mode: Using mock proof");
4000
4152
  return {
4001
4153
  toJSON: () => ({ mock: true })
4002
4154
  };
@@ -4181,7 +4333,7 @@ async function parseTokenInfo(tokenData) {
4181
4333
  }
4182
4334
  }
4183
4335
  } catch (error) {
4184
- console.warn("[Payments] Failed to parse token info:", error);
4336
+ logger.warn("Payments", "Failed to parse token info:", error);
4185
4337
  }
4186
4338
  return defaultInfo;
4187
4339
  }
@@ -4384,11 +4536,6 @@ var PaymentsModule = class _PaymentsModule {
4384
4536
  }
4385
4537
  /** Price provider (optional) */
4386
4538
  priceProvider = null;
4387
- log(...args) {
4388
- if (this.moduleConfig.debug) {
4389
- console.log("[PaymentsModule]", ...args);
4390
- }
4391
- }
4392
4539
  // ===========================================================================
4393
4540
  // Lifecycle
4394
4541
  // ===========================================================================
@@ -4455,11 +4602,11 @@ var PaymentsModule = class _PaymentsModule {
4455
4602
  if (txfData._history && txfData._history.length > 0) {
4456
4603
  await this.importRemoteHistoryEntries(txfData._history);
4457
4604
  }
4458
- this.log(`Loaded metadata from provider ${id}`);
4605
+ logger.debug("Payments", `Loaded metadata from provider ${id}`);
4459
4606
  break;
4460
4607
  }
4461
4608
  } catch (err) {
4462
- console.error(`[Payments] Failed to load from provider ${id}:`, err);
4609
+ logger.error("Payments", `Failed to load from provider ${id}:`, err);
4463
4610
  }
4464
4611
  }
4465
4612
  for (const [id, token] of this.tokens) {
@@ -4468,14 +4615,14 @@ var PaymentsModule = class _PaymentsModule {
4468
4615
  const data = JSON.parse(token.sdkData);
4469
4616
  if (data?._placeholder) {
4470
4617
  this.tokens.delete(id);
4471
- console.log(`[Payments] Removed stale placeholder token: ${id}`);
4618
+ logger.debug("Payments", `Removed stale placeholder token: ${id}`);
4472
4619
  }
4473
4620
  }
4474
4621
  } catch {
4475
4622
  }
4476
4623
  }
4477
4624
  const loadedTokens = Array.from(this.tokens.values()).map((t) => `${t.id.slice(0, 12)}(${t.status})`);
4478
- console.log(`[Payments][DEBUG] load(): from TXF providers: ${this.tokens.size} tokens [${loadedTokens.join(", ")}]`);
4625
+ logger.debug("Payments", `load(): from TXF providers: ${this.tokens.size} tokens [${loadedTokens.join(", ")}]`);
4479
4626
  await this.loadPendingV5Tokens();
4480
4627
  await this.loadProcessedSplitGroupIds();
4481
4628
  await this.loadProcessedCombinedTransferIds();
@@ -4491,8 +4638,7 @@ var PaymentsModule = class _PaymentsModule {
4491
4638
  };
4492
4639
  this.loadedPromise = doLoad();
4493
4640
  await this.loadedPromise;
4494
- this.resolveUnconfirmed().catch(() => {
4495
- });
4641
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
4496
4642
  this.scheduleResolveUnconfirmed();
4497
4643
  }
4498
4644
  /**
@@ -4545,11 +4691,11 @@ var PaymentsModule = class _PaymentsModule {
4545
4691
  const signingService = await this.createSigningService();
4546
4692
  const stClient = this.deps.oracle.getStateTransitionClient?.();
4547
4693
  if (!stClient) {
4548
- throw new Error("State transition client not available. Oracle provider must implement getStateTransitionClient()");
4694
+ throw new SphereError("State transition client not available. Oracle provider must implement getStateTransitionClient()", "AGGREGATOR_ERROR");
4549
4695
  }
4550
4696
  const trustBase = this.deps.oracle.getTrustBase?.();
4551
4697
  if (!trustBase) {
4552
- throw new Error("Trust base not available. Oracle provider must implement getTrustBase()");
4698
+ throw new SphereError("Trust base not available. Oracle provider must implement getTrustBase()", "AGGREGATOR_ERROR");
4553
4699
  }
4554
4700
  const calculator = new TokenSplitCalculator();
4555
4701
  const availableTokens = Array.from(this.tokens.values());
@@ -4559,7 +4705,7 @@ var PaymentsModule = class _PaymentsModule {
4559
4705
  request.coinId
4560
4706
  );
4561
4707
  if (!splitPlan) {
4562
- throw new Error("Insufficient balance");
4708
+ throw new SphereError("Insufficient balance", "INSUFFICIENT_BALANCE");
4563
4709
  }
4564
4710
  const tokensToSend = splitPlan.tokensToTransferDirectly.map((t) => t.uiToken);
4565
4711
  if (splitPlan.tokenToSplit) {
@@ -4577,7 +4723,7 @@ var PaymentsModule = class _PaymentsModule {
4577
4723
  const transferMode = request.transferMode ?? "instant";
4578
4724
  if (transferMode === "conservative") {
4579
4725
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
4580
- this.log("Executing conservative split...");
4726
+ logger.debug("Payments", "Executing conservative split...");
4581
4727
  const splitExecutor = new TokenSplitExecutor({
4582
4728
  stateTransitionClient: stClient,
4583
4729
  trustBase,
@@ -4605,7 +4751,7 @@ var PaymentsModule = class _PaymentsModule {
4605
4751
  sdkData: JSON.stringify(changeTokenData)
4606
4752
  };
4607
4753
  await this.addToken(changeUiToken);
4608
- this.log(`Conservative split: change token saved: ${changeUiToken.id}`);
4754
+ logger.debug("Payments", `Conservative split: change token saved: ${changeUiToken.id}`);
4609
4755
  await this.deps.transport.sendTokenTransfer(recipientPubkey, {
4610
4756
  sourceToken: JSON.stringify(splitResult.tokenForRecipient.toJSON()),
4611
4757
  transferTx: JSON.stringify(splitResult.recipientTransferTx.toJSON()),
@@ -4619,15 +4765,15 @@ var PaymentsModule = class _PaymentsModule {
4619
4765
  method: "split",
4620
4766
  requestIdHex: splitRequestIdHex
4621
4767
  });
4622
- this.log(`Conservative split transfer completed`);
4768
+ logger.debug("Payments", "Conservative split transfer completed");
4623
4769
  }
4624
4770
  for (const tokenWithAmount of splitPlan.tokensToTransferDirectly) {
4625
4771
  const token = tokenWithAmount.uiToken;
4626
4772
  const commitment = await this.createSdkCommitment(token, recipientAddress, signingService);
4627
- console.log(`[Payments] CONSERVATIVE: Sending direct token ${token.id.slice(0, 8)}... to ${recipientPubkey.slice(0, 8)}...`);
4773
+ logger.debug("Payments", `CONSERVATIVE: Sending direct token ${token.id.slice(0, 8)}... to ${recipientPubkey.slice(0, 8)}...`);
4628
4774
  const submitResponse = await stClient.submitTransferCommitment(commitment);
4629
4775
  if (submitResponse.status !== "SUCCESS" && submitResponse.status !== "REQUEST_ID_EXISTS") {
4630
- throw new Error(`Transfer commitment failed: ${submitResponse.status}`);
4776
+ throw new SphereError(`Transfer commitment failed: ${submitResponse.status}`, "TRANSFER_FAILED");
4631
4777
  }
4632
4778
  const inclusionProof = await waitInclusionProof5(trustBase, stClient, commitment);
4633
4779
  const transferTx = commitment.toTransaction(inclusionProof);
@@ -4636,7 +4782,7 @@ var PaymentsModule = class _PaymentsModule {
4636
4782
  transferTx: JSON.stringify(transferTx.toJSON()),
4637
4783
  memo: request.memo
4638
4784
  });
4639
- console.log(`[Payments] CONSERVATIVE: Direct token sent successfully`);
4785
+ logger.debug("Payments", "CONSERVATIVE: Direct token sent successfully");
4640
4786
  const requestIdBytes = commitment.requestId;
4641
4787
  const requestIdHex = requestIdBytes instanceof Uint8Array ? Array.from(requestIdBytes).map((b) => b.toString(16).padStart(2, "0")).join("") : String(requestIdBytes);
4642
4788
  result.tokenTransfers.push({
@@ -4644,7 +4790,7 @@ var PaymentsModule = class _PaymentsModule {
4644
4790
  method: "direct",
4645
4791
  requestIdHex
4646
4792
  });
4647
- this.log(`Token ${token.id} sent via CONSERVATIVE, requestId: ${requestIdHex}`);
4793
+ logger.debug("Payments", `Token ${token.id} sent via CONSERVATIVE, requestId: ${requestIdHex}`);
4648
4794
  await this.removeToken(token.id);
4649
4795
  }
4650
4796
  } else {
@@ -4653,7 +4799,7 @@ var PaymentsModule = class _PaymentsModule {
4653
4799
  let changeTokenPlaceholderId = null;
4654
4800
  let builtSplit = null;
4655
4801
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
4656
- this.log("Building instant split bundle...");
4802
+ logger.debug("Payments", "Building instant split bundle...");
4657
4803
  const executor = new InstantSplitExecutor({
4658
4804
  stateTransitionClient: stClient,
4659
4805
  trustBase,
@@ -4687,7 +4833,7 @@ var PaymentsModule = class _PaymentsModule {
4687
4833
  sdkData: JSON.stringify(changeTokenData)
4688
4834
  };
4689
4835
  await this.addToken(uiToken);
4690
- this.log(`Change token saved via background: ${uiToken.id}`);
4836
+ logger.debug("Payments", `Change token saved via background: ${uiToken.id}`);
4691
4837
  },
4692
4838
  onStorageSync: async () => {
4693
4839
  await this.save();
@@ -4695,7 +4841,7 @@ var PaymentsModule = class _PaymentsModule {
4695
4841
  }
4696
4842
  }
4697
4843
  );
4698
- this.log(`Split bundle built: splitGroupId=${builtSplit.splitGroupId}`);
4844
+ logger.debug("Payments", `Split bundle built: splitGroupId=${builtSplit.splitGroupId}`);
4699
4845
  }
4700
4846
  const directCommitments = await Promise.all(
4701
4847
  splitPlan.tokensToTransferDirectly.map(
@@ -4722,8 +4868,9 @@ var PaymentsModule = class _PaymentsModule {
4722
4868
  senderPubkey,
4723
4869
  memo: request.memo
4724
4870
  };
4725
- console.log(
4726
- `[Payments] Sending V6 combined bundle: transfer=${result.id.slice(0, 8)}... split=${!!builtSplit} direct=${directTokenEntries.length}`
4871
+ logger.debug(
4872
+ "Payments",
4873
+ `Sending V6 combined bundle: transfer=${result.id.slice(0, 8)}... split=${!!builtSplit} direct=${directTokenEntries.length}`
4727
4874
  );
4728
4875
  await this.deps.transport.sendTokenTransfer(recipientPubkey, {
4729
4876
  token: JSON.stringify(combinedBundle),
@@ -4731,7 +4878,7 @@ var PaymentsModule = class _PaymentsModule {
4731
4878
  memo: request.memo,
4732
4879
  sender: { transportPubkey: senderPubkey }
4733
4880
  });
4734
- console.log(`[Payments] V6 combined bundle sent successfully`);
4881
+ logger.debug("Payments", "V6 combined bundle sent successfully");
4735
4882
  if (builtSplit) {
4736
4883
  const bgPromise = builtSplit.startBackground();
4737
4884
  this.pendingBackgroundTasks.push(bgPromise);
@@ -4752,11 +4899,11 @@ var PaymentsModule = class _PaymentsModule {
4752
4899
  sdkData: JSON.stringify({ _placeholder: true })
4753
4900
  };
4754
4901
  this.tokens.set(placeholder.id, placeholder);
4755
- this.log(`Placeholder change token created: ${placeholder.id} (${placeholder.amount})`);
4902
+ logger.debug("Payments", `Placeholder change token created: ${placeholder.id} (${placeholder.amount})`);
4756
4903
  }
4757
4904
  for (const commitment of directCommitments) {
4758
4905
  stClient.submitTransferCommitment(commitment).catch(
4759
- (err) => console.error("[Payments] Background commitment submit failed:", err)
4906
+ (err) => logger.error("Payments", "Background commitment submit failed:", err)
4760
4907
  );
4761
4908
  }
4762
4909
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
@@ -4779,7 +4926,7 @@ var PaymentsModule = class _PaymentsModule {
4779
4926
  });
4780
4927
  await this.removeToken(token.id);
4781
4928
  }
4782
- this.log(`V6 combined transfer completed`);
4929
+ logger.debug("Payments", "V6 combined transfer completed");
4783
4930
  }
4784
4931
  result.status = "delivered";
4785
4932
  await this.save();
@@ -4870,11 +5017,11 @@ var PaymentsModule = class _PaymentsModule {
4870
5017
  const signingService = await this.createSigningService();
4871
5018
  const stClient = this.deps.oracle.getStateTransitionClient?.();
4872
5019
  if (!stClient) {
4873
- throw new Error("State transition client not available");
5020
+ throw new SphereError("State transition client not available", "AGGREGATOR_ERROR");
4874
5021
  }
4875
5022
  const trustBase = this.deps.oracle.getTrustBase?.();
4876
5023
  if (!trustBase) {
4877
- throw new Error("Trust base not available");
5024
+ throw new SphereError("Trust base not available", "AGGREGATOR_ERROR");
4878
5025
  }
4879
5026
  const calculator = new TokenSplitCalculator();
4880
5027
  const availableTokens = Array.from(this.tokens.values());
@@ -4884,10 +5031,10 @@ var PaymentsModule = class _PaymentsModule {
4884
5031
  request.coinId
4885
5032
  );
4886
5033
  if (!splitPlan) {
4887
- throw new Error("Insufficient balance");
5034
+ throw new SphereError("Insufficient balance", "INSUFFICIENT_BALANCE");
4888
5035
  }
4889
5036
  if (!splitPlan.requiresSplit || !splitPlan.tokenToSplit) {
4890
- this.log("No split required, falling back to standard send()");
5037
+ logger.debug("Payments", "No split required, falling back to standard send()");
4891
5038
  const result2 = await this.send(request);
4892
5039
  return {
4893
5040
  success: result2.status === "completed",
@@ -4895,7 +5042,7 @@ var PaymentsModule = class _PaymentsModule {
4895
5042
  error: result2.error
4896
5043
  };
4897
5044
  }
4898
- this.log(`InstantSplit: amount=${splitPlan.splitAmount}, remainder=${splitPlan.remainderAmount}`);
5045
+ logger.debug("Payments", `InstantSplit: amount=${splitPlan.splitAmount}, remainder=${splitPlan.remainderAmount}`);
4899
5046
  const tokenToSplit = splitPlan.tokenToSplit.uiToken;
4900
5047
  tokenToSplit.status = "transferring";
4901
5048
  this.tokens.set(tokenToSplit.id, tokenToSplit);
@@ -4933,7 +5080,7 @@ var PaymentsModule = class _PaymentsModule {
4933
5080
  sdkData: JSON.stringify(changeTokenData)
4934
5081
  };
4935
5082
  await this.addToken(uiToken);
4936
- this.log(`Change token saved via background: ${uiToken.id}`);
5083
+ logger.debug("Payments", `Change token saved via background: ${uiToken.id}`);
4937
5084
  },
4938
5085
  onStorageSync: async () => {
4939
5086
  await this.save();
@@ -4988,7 +5135,7 @@ var PaymentsModule = class _PaymentsModule {
4988
5135
  async saveUnconfirmedV5Token(bundle, senderPubkey, deferPersistence = false) {
4989
5136
  const deterministicId = `v5split_${bundle.splitGroupId}`;
4990
5137
  if (this.tokens.has(deterministicId) || this.processedSplitGroupIds.has(bundle.splitGroupId)) {
4991
- console.log(`[Payments] V5 bundle ${bundle.splitGroupId.slice(0, 12)}... already processed, skipping`);
5138
+ logger.debug("Payments", `V5 bundle ${bundle.splitGroupId.slice(0, 12)}... already processed, skipping`);
4992
5139
  return null;
4993
5140
  }
4994
5141
  const registry = TokenRegistry.getInstance();
@@ -5038,7 +5185,7 @@ var PaymentsModule = class _PaymentsModule {
5038
5185
  const nostrTokenId = extractTokenIdFromSdkData(sdkData);
5039
5186
  const nostrStateHash = extractStateHashFromSdkData(sdkData);
5040
5187
  if (nostrTokenId && nostrStateHash && this.isStateTombstoned(nostrTokenId, nostrStateHash)) {
5041
- this.log(`NOSTR-FIRST: Rejecting tombstoned token ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`);
5188
+ logger.debug("Payments", `NOSTR-FIRST: Rejecting tombstoned token ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`);
5042
5189
  return null;
5043
5190
  }
5044
5191
  if (nostrTokenId) {
@@ -5047,14 +5194,16 @@ var PaymentsModule = class _PaymentsModule {
5047
5194
  if (existingTokenId !== nostrTokenId) continue;
5048
5195
  const existingStateHash = extractStateHashFromSdkData(existing.sdkData);
5049
5196
  if (nostrStateHash && existingStateHash === nostrStateHash) {
5050
- console.log(
5051
- `[Payments] NOSTR-FIRST: Skipping duplicate token state ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`
5197
+ logger.debug(
5198
+ "Payments",
5199
+ `NOSTR-FIRST: Skipping duplicate token state ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`
5052
5200
  );
5053
5201
  return null;
5054
5202
  }
5055
5203
  if (!skipGenesisDedup) {
5056
- console.log(
5057
- `[Payments] NOSTR-FIRST: Skipping replay of finalized token ${nostrTokenId.slice(0, 8)}...`
5204
+ logger.debug(
5205
+ "Payments",
5206
+ `NOSTR-FIRST: Skipping replay of finalized token ${nostrTokenId.slice(0, 8)}...`
5058
5207
  );
5059
5208
  return null;
5060
5209
  }
@@ -5086,7 +5235,7 @@ var PaymentsModule = class _PaymentsModule {
5086
5235
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5087
5236
  if (stClient) {
5088
5237
  const response = await stClient.submitTransferCommitment(commitment);
5089
- this.log(`NOSTR-FIRST recipient commitment submit: ${response.status}`);
5238
+ logger.debug("Payments", `NOSTR-FIRST recipient commitment submit: ${response.status}`);
5090
5239
  }
5091
5240
  }
5092
5241
  this.addProofPollingJob({
@@ -5101,7 +5250,7 @@ var PaymentsModule = class _PaymentsModule {
5101
5250
  }
5102
5251
  });
5103
5252
  } catch (err) {
5104
- console.error("[Payments] Failed to parse commitment for proof polling:", err);
5253
+ logger.error("Payments", "Failed to parse commitment for proof polling:", err);
5105
5254
  }
5106
5255
  return token;
5107
5256
  }
@@ -5123,11 +5272,12 @@ var PaymentsModule = class _PaymentsModule {
5123
5272
  await this.loadedPromise;
5124
5273
  }
5125
5274
  if (this.processedCombinedTransferIds.has(bundle.transferId)) {
5126
- console.log(`[Payments] V6 combined transfer ${bundle.transferId.slice(0, 12)}... already processed, skipping`);
5275
+ logger.debug("Payments", `V6 combined transfer ${bundle.transferId.slice(0, 12)}... already processed, skipping`);
5127
5276
  return;
5128
5277
  }
5129
- console.log(
5130
- `[Payments] Processing V6 combined transfer ${bundle.transferId.slice(0, 12)}... (split=${!!bundle.splitBundle}, direct=${bundle.directTokens.length})`
5278
+ logger.debug(
5279
+ "Payments",
5280
+ `Processing V6 combined transfer ${bundle.transferId.slice(0, 12)}... (split=${!!bundle.splitBundle}, direct=${bundle.directTokens.length})`
5131
5281
  );
5132
5282
  const allTokens = [];
5133
5283
  const tokenBreakdown = [];
@@ -5141,7 +5291,7 @@ var PaymentsModule = class _PaymentsModule {
5141
5291
  allTokens.push(splitToken);
5142
5292
  tokenBreakdown.push({ id: splitToken.id, amount: splitToken.amount, source: "split" });
5143
5293
  } else {
5144
- console.warn(`[Payments] V6: split token was deduped/failed \u2014 amount=${bundle.splitBundle.amount}`);
5294
+ logger.warn("Payments", `V6: split token was deduped/failed \u2014 amount=${bundle.splitBundle.amount}`);
5145
5295
  }
5146
5296
  }
5147
5297
  const directResults = await Promise.all(
@@ -5156,13 +5306,14 @@ var PaymentsModule = class _PaymentsModule {
5156
5306
  tokenBreakdown.push({ id: token.id, amount: token.amount, source: "direct" });
5157
5307
  } else {
5158
5308
  const entry = bundle.directTokens[i];
5159
- console.warn(
5160
- `[Payments] V6: direct token #${i} dropped (amount=${entry.amount}, tokenId=${entry.tokenId?.slice(0, 12) ?? "N/A"})`
5309
+ logger.warn(
5310
+ "Payments",
5311
+ `V6: direct token #${i} dropped (amount=${entry.amount}, tokenId=${entry.tokenId?.slice(0, 12) ?? "N/A"})`
5161
5312
  );
5162
5313
  }
5163
5314
  }
5164
5315
  if (allTokens.length === 0) {
5165
- console.log(`[Payments] V6 combined transfer: all tokens deduped, nothing to save`);
5316
+ logger.debug("Payments", "V6 combined transfer: all tokens deduped, nothing to save");
5166
5317
  return;
5167
5318
  }
5168
5319
  this.processedCombinedTransferIds.add(bundle.transferId);
@@ -5178,7 +5329,7 @@ var PaymentsModule = class _PaymentsModule {
5178
5329
  TransferCommitment4.fromJSON(commitment).then(
5179
5330
  (c) => stClient.submitTransferCommitment(c)
5180
5331
  ).catch(
5181
- (err) => console.error("[Payments] V6 background commitment submit failed:", err)
5332
+ (err) => logger.error("Payments", "V6 background commitment submit failed:", err)
5182
5333
  );
5183
5334
  }
5184
5335
  }
@@ -5205,8 +5356,7 @@ var PaymentsModule = class _PaymentsModule {
5205
5356
  tokenIds: tokenBreakdown
5206
5357
  });
5207
5358
  if (bundle.splitBundle) {
5208
- this.resolveUnconfirmed().catch(() => {
5209
- });
5359
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
5210
5360
  this.scheduleResolveUnconfirmed();
5211
5361
  }
5212
5362
  }
@@ -5284,8 +5434,7 @@ var PaymentsModule = class _PaymentsModule {
5284
5434
  receivedAt: Date.now()
5285
5435
  });
5286
5436
  await this.save();
5287
- this.resolveUnconfirmed().catch(() => {
5288
- });
5437
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
5289
5438
  this.scheduleResolveUnconfirmed();
5290
5439
  return { success: true, durationMs: 0 };
5291
5440
  } catch (error) {
@@ -5306,11 +5455,11 @@ var PaymentsModule = class _PaymentsModule {
5306
5455
  const signingService = await this.createSigningService();
5307
5456
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5308
5457
  if (!stClient) {
5309
- throw new Error("State transition client not available");
5458
+ throw new SphereError("State transition client not available", "AGGREGATOR_ERROR");
5310
5459
  }
5311
5460
  const trustBase = this.deps.oracle.getTrustBase?.();
5312
5461
  if (!trustBase) {
5313
- throw new Error("Trust base not available");
5462
+ throw new SphereError("Trust base not available", "AGGREGATOR_ERROR");
5314
5463
  }
5315
5464
  const devMode = this.deps.oracle.isDevMode?.() ?? false;
5316
5465
  const processor = new InstantSplitProcessor({
@@ -5333,10 +5482,10 @@ var PaymentsModule = class _PaymentsModule {
5333
5482
  if (proxy.address === proxyAddress) {
5334
5483
  return nametagToken;
5335
5484
  }
5336
- this.log(`Nametag PROXY address mismatch: ${proxy.address} !== ${proxyAddress}`);
5485
+ logger.debug("Payments", `Nametag PROXY address mismatch: ${proxy.address} !== ${proxyAddress}`);
5337
5486
  return null;
5338
5487
  } catch (err) {
5339
- this.log("Failed to parse nametag token:", err);
5488
+ logger.debug("Payments", "Failed to parse nametag token:", err);
5340
5489
  return null;
5341
5490
  }
5342
5491
  }
@@ -5444,7 +5593,7 @@ var PaymentsModule = class _PaymentsModule {
5444
5593
  status: "pending"
5445
5594
  };
5446
5595
  this.outgoingPaymentRequests.set(requestId2, outgoingRequest);
5447
- this.log(`Payment request sent: ${eventId}`);
5596
+ logger.debug("Payments", `Payment request sent: ${eventId}`);
5448
5597
  return {
5449
5598
  success: true,
5450
5599
  requestId: requestId2,
@@ -5452,7 +5601,7 @@ var PaymentsModule = class _PaymentsModule {
5452
5601
  };
5453
5602
  } catch (error) {
5454
5603
  const errorMsg = error instanceof Error ? error.message : String(error);
5455
- this.log(`Failed to send payment request: ${errorMsg}`);
5604
+ logger.debug("Payments", `Failed to send payment request: ${errorMsg}`);
5456
5605
  return {
5457
5606
  success: false,
5458
5607
  error: errorMsg
@@ -5541,10 +5690,10 @@ var PaymentsModule = class _PaymentsModule {
5541
5690
  async payPaymentRequest(requestId2, memo) {
5542
5691
  const request = this.paymentRequests.find((r) => r.id === requestId2);
5543
5692
  if (!request) {
5544
- throw new Error(`Payment request not found: ${requestId2}`);
5693
+ throw new SphereError(`Payment request not found: ${requestId2}`, "VALIDATION_ERROR");
5545
5694
  }
5546
5695
  if (request.status !== "pending" && request.status !== "accepted") {
5547
- throw new Error(`Payment request is not pending or accepted: ${request.status}`);
5696
+ throw new SphereError(`Payment request is not pending or accepted: ${request.status}`, "VALIDATION_ERROR");
5548
5697
  }
5549
5698
  this.updatePaymentRequestStatus(requestId2, "accepted");
5550
5699
  try {
@@ -5599,10 +5748,10 @@ var PaymentsModule = class _PaymentsModule {
5599
5748
  try {
5600
5749
  handler(request);
5601
5750
  } catch (error) {
5602
- this.log("Payment request handler error:", error);
5751
+ logger.debug("Payments", "Payment request handler error:", error);
5603
5752
  }
5604
5753
  }
5605
- this.log(`Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
5754
+ logger.debug("Payments", `Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
5606
5755
  }
5607
5756
  // ===========================================================================
5608
5757
  // Public API - Outgoing Payment Requests
@@ -5721,10 +5870,10 @@ var PaymentsModule = class _PaymentsModule {
5721
5870
  try {
5722
5871
  handler(response);
5723
5872
  } catch (error) {
5724
- this.log("Payment request response handler error:", error);
5873
+ logger.debug("Payments", "Payment request response handler error:", error);
5725
5874
  }
5726
5875
  }
5727
- this.log(`Received payment request response: ${response.id} type: ${response.responseType}`);
5876
+ logger.debug("Payments", `Received payment request response: ${response.id} type: ${response.responseType}`);
5728
5877
  }
5729
5878
  /**
5730
5879
  * Send a response to a payment request (used internally by accept/reject/pay methods)
@@ -5733,7 +5882,7 @@ var PaymentsModule = class _PaymentsModule {
5733
5882
  const request = this.paymentRequests.find((r) => r.id === requestId2);
5734
5883
  if (!request) return;
5735
5884
  if (!this.deps?.transport.sendPaymentRequestResponse) {
5736
- this.log("Transport does not support sendPaymentRequestResponse");
5885
+ logger.debug("Payments", "Transport does not support sendPaymentRequestResponse");
5737
5886
  return;
5738
5887
  }
5739
5888
  try {
@@ -5744,9 +5893,9 @@ var PaymentsModule = class _PaymentsModule {
5744
5893
  transferId
5745
5894
  };
5746
5895
  await this.deps.transport.sendPaymentRequestResponse(request.senderPubkey, payload);
5747
- this.log(`Sent payment request response: ${responseType} for ${requestId2}`);
5896
+ logger.debug("Payments", `Sent payment request response: ${responseType} for ${requestId2}`);
5748
5897
  } catch (error) {
5749
- this.log("Failed to send payment request response:", error);
5898
+ logger.debug("Payments", "Failed to send payment request response:", error);
5750
5899
  }
5751
5900
  }
5752
5901
  // ===========================================================================
@@ -5770,7 +5919,7 @@ var PaymentsModule = class _PaymentsModule {
5770
5919
  async receive(options, callback) {
5771
5920
  this.ensureInitialized();
5772
5921
  if (!this.deps.transport.fetchPendingEvents) {
5773
- throw new Error("Transport provider does not support fetchPendingEvents");
5922
+ throw new SphereError("Transport provider does not support fetchPendingEvents", "TRANSPORT_ERROR");
5774
5923
  }
5775
5924
  const opts = options ?? {};
5776
5925
  const tokensBefore = new Set(this.tokens.keys());
@@ -5917,7 +6066,7 @@ var PaymentsModule = class _PaymentsModule {
5917
6066
  });
5918
6067
  }
5919
6068
  } catch (error) {
5920
- console.warn("[Payments] Failed to fetch prices, returning assets without price data:", error);
6069
+ logger.warn("Payments", "Failed to fetch prices, returning assets without price data:", error);
5921
6070
  }
5922
6071
  return rawAssets;
5923
6072
  }
@@ -6039,24 +6188,24 @@ var PaymentsModule = class _PaymentsModule {
6039
6188
  const stClient = this.deps.oracle.getStateTransitionClient?.();
6040
6189
  const trustBase = this.deps.oracle.getTrustBase?.();
6041
6190
  if (!stClient || !trustBase) {
6042
- console.log(`[V5-RESOLVE] resolveUnconfirmed: EARLY EXIT \u2014 stClient=${!!stClient} trustBase=${!!trustBase}`);
6191
+ logger.debug("Payments", `[V5-RESOLVE] resolveUnconfirmed: EARLY EXIT \u2014 stClient=${!!stClient} trustBase=${!!trustBase}`);
6043
6192
  return result;
6044
6193
  }
6045
6194
  const signingService = await this.createSigningService();
6046
6195
  const submittedCount = Array.from(this.tokens.values()).filter((t) => t.status === "submitted").length;
6047
- console.log(`[V5-RESOLVE] resolveUnconfirmed: ${submittedCount} submitted token(s) to process`);
6196
+ logger.debug("Payments", `[V5-RESOLVE] resolveUnconfirmed: ${submittedCount} submitted token(s) to process`);
6048
6197
  for (const [tokenId, token] of this.tokens) {
6049
6198
  if (token.status !== "submitted") continue;
6050
6199
  const pending2 = this.parsePendingFinalization(token.sdkData);
6051
6200
  if (!pending2) {
6052
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 16)}: no pending finalization metadata, skipping`);
6201
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 16)}: no pending finalization metadata, skipping`);
6053
6202
  result.stillPending++;
6054
6203
  continue;
6055
6204
  }
6056
6205
  if (pending2.type === "v5_bundle") {
6057
- console.log(`[V5-RESOLVE] Processing ${tokenId.slice(0, 16)}... stage=${pending2.stage} attempt=${pending2.attemptCount}`);
6206
+ logger.debug("Payments", `[V5-RESOLVE] Processing ${tokenId.slice(0, 16)}... stage=${pending2.stage} attempt=${pending2.attemptCount}`);
6058
6207
  const progress = await this.resolveV5Token(tokenId, token, pending2, stClient, trustBase, signingService);
6059
- console.log(`[V5-RESOLVE] Result for ${tokenId.slice(0, 16)}...: ${progress} (stage now: ${pending2.stage})`);
6208
+ logger.debug("Payments", `[V5-RESOLVE] Result for ${tokenId.slice(0, 16)}...: ${progress} (stage now: ${pending2.stage})`);
6060
6209
  result.details.push({ tokenId, stage: pending2.stage, status: progress });
6061
6210
  if (progress === "resolved") result.resolved++;
6062
6211
  else if (progress === "failed") result.failed++;
@@ -6064,7 +6213,7 @@ var PaymentsModule = class _PaymentsModule {
6064
6213
  }
6065
6214
  }
6066
6215
  if (result.resolved > 0 || result.failed > 0 || result.stillPending > 0) {
6067
- console.log(`[V5-RESOLVE] Saving: resolved=${result.resolved} failed=${result.failed} stillPending=${result.stillPending}`);
6216
+ logger.debug("Payments", `[V5-RESOLVE] Saving: resolved=${result.resolved} failed=${result.failed} stillPending=${result.stillPending}`);
6068
6217
  await this.save();
6069
6218
  }
6070
6219
  return result;
@@ -6080,19 +6229,19 @@ var PaymentsModule = class _PaymentsModule {
6080
6229
  (t) => t.status === "submitted"
6081
6230
  );
6082
6231
  if (!hasUnconfirmed) {
6083
- console.log(`[V5-RESOLVE] scheduleResolveUnconfirmed: no submitted tokens, not starting timer`);
6232
+ logger.debug("Payments", "[V5-RESOLVE] scheduleResolveUnconfirmed: no submitted tokens, not starting timer");
6084
6233
  return;
6085
6234
  }
6086
- console.log(`[V5-RESOLVE] scheduleResolveUnconfirmed: starting periodic retry (every ${_PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS}ms)`);
6235
+ logger.debug("Payments", `[V5-RESOLVE] scheduleResolveUnconfirmed: starting periodic retry (every ${_PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS}ms)`);
6087
6236
  this.resolveUnconfirmedTimer = setInterval(async () => {
6088
6237
  try {
6089
6238
  const result = await this.resolveUnconfirmed();
6090
6239
  if (result.stillPending === 0) {
6091
- console.log(`[V5-RESOLVE] All tokens resolved, stopping periodic retry`);
6240
+ logger.debug("Payments", "[V5-RESOLVE] All tokens resolved, stopping periodic retry");
6092
6241
  this.stopResolveUnconfirmedPolling();
6093
6242
  }
6094
6243
  } catch (err) {
6095
- console.log(`[V5-RESOLVE] Periodic retry error:`, err);
6244
+ logger.debug("Payments", "[V5-RESOLVE] Periodic retry error:", err);
6096
6245
  }
6097
6246
  }, _PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS);
6098
6247
  }
@@ -6114,57 +6263,57 @@ var PaymentsModule = class _PaymentsModule {
6114
6263
  pending2.lastAttemptAt = Date.now();
6115
6264
  try {
6116
6265
  if (pending2.stage === "RECEIVED") {
6117
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: RECEIVED \u2192 submitting mint commitment...`);
6266
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: RECEIVED \u2192 submitting mint commitment...`);
6118
6267
  const mintDataJson = JSON.parse(bundle.recipientMintData);
6119
6268
  const mintData = await MintTransactionData3.fromJSON(mintDataJson);
6120
6269
  const mintCommitment = await MintCommitment3.create(mintData);
6121
6270
  const mintResponse = await stClient.submitMintCommitment(mintCommitment);
6122
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint response status=${mintResponse.status}`);
6271
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint response status=${mintResponse.status}`);
6123
6272
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
6124
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
6273
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
6125
6274
  }
6126
6275
  pending2.stage = "MINT_SUBMITTED";
6127
6276
  this.updatePendingFinalization(token, pending2);
6128
6277
  }
6129
6278
  if (pending2.stage === "MINT_SUBMITTED") {
6130
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_SUBMITTED \u2192 checking mint proof...`);
6279
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_SUBMITTED \u2192 checking mint proof...`);
6131
6280
  const mintDataJson = JSON.parse(bundle.recipientMintData);
6132
6281
  const mintData = await MintTransactionData3.fromJSON(mintDataJson);
6133
6282
  const mintCommitment = await MintCommitment3.create(mintData);
6134
6283
  const proof = await this.quickProofCheck(stClient, trustBase, mintCommitment);
6135
6284
  if (!proof) {
6136
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof not yet available, staying MINT_SUBMITTED`);
6285
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof not yet available, staying MINT_SUBMITTED`);
6137
6286
  this.updatePendingFinalization(token, pending2);
6138
6287
  return "pending";
6139
6288
  }
6140
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof obtained!`);
6289
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof obtained!`);
6141
6290
  pending2.mintProofJson = JSON.stringify(proof);
6142
6291
  pending2.stage = "MINT_PROVEN";
6143
6292
  this.updatePendingFinalization(token, pending2);
6144
6293
  }
6145
6294
  if (pending2.stage === "MINT_PROVEN") {
6146
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_PROVEN \u2192 submitting transfer commitment...`);
6295
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_PROVEN \u2192 submitting transfer commitment...`);
6147
6296
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
6148
6297
  const transferCommitment = await TransferCommitment4.fromJSON(transferCommitmentJson);
6149
6298
  const transferResponse = await stClient.submitTransferCommitment(transferCommitment);
6150
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer response status=${transferResponse.status}`);
6299
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer response status=${transferResponse.status}`);
6151
6300
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
6152
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
6301
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
6153
6302
  }
6154
6303
  pending2.stage = "TRANSFER_SUBMITTED";
6155
6304
  this.updatePendingFinalization(token, pending2);
6156
6305
  }
6157
6306
  if (pending2.stage === "TRANSFER_SUBMITTED") {
6158
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: TRANSFER_SUBMITTED \u2192 checking transfer proof...`);
6307
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: TRANSFER_SUBMITTED \u2192 checking transfer proof...`);
6159
6308
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
6160
6309
  const transferCommitment = await TransferCommitment4.fromJSON(transferCommitmentJson);
6161
6310
  const proof = await this.quickProofCheck(stClient, trustBase, transferCommitment);
6162
6311
  if (!proof) {
6163
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof not yet available, staying TRANSFER_SUBMITTED`);
6312
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof not yet available, staying TRANSFER_SUBMITTED`);
6164
6313
  this.updatePendingFinalization(token, pending2);
6165
6314
  return "pending";
6166
6315
  }
6167
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof obtained! Finalizing...`);
6316
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof obtained! Finalizing...`);
6168
6317
  const finalizedToken = await this.finalizeFromV5Bundle(bundle, pending2, signingService, stClient, trustBase);
6169
6318
  const confirmedToken = {
6170
6319
  id: token.id,
@@ -6186,12 +6335,12 @@ var PaymentsModule = class _PaymentsModule {
6186
6335
  tokens: [confirmedToken],
6187
6336
  tokenTransfers: []
6188
6337
  });
6189
- this.log(`V5 token resolved: ${tokenId.slice(0, 8)}...`);
6338
+ logger.debug("Payments", `V5 token resolved: ${tokenId.slice(0, 8)}...`);
6190
6339
  return "resolved";
6191
6340
  }
6192
6341
  return "pending";
6193
6342
  } catch (error) {
6194
- console.error(`[Payments] resolveV5Token failed for ${tokenId.slice(0, 8)}:`, error);
6343
+ logger.error("Payments", `resolveV5Token failed for ${tokenId.slice(0, 8)}:`, error);
6195
6344
  if (pending2.attemptCount > 50) {
6196
6345
  token.status = "invalid";
6197
6346
  token.updatedAt = Date.now();
@@ -6328,19 +6477,19 @@ var PaymentsModule = class _PaymentsModule {
6328
6477
  }
6329
6478
  if (pendingTokens.length > 0) {
6330
6479
  const json = JSON.stringify(pendingTokens);
6331
- this.log(`[V5-PERSIST] Saving ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")} (${json.length} bytes)`);
6480
+ logger.debug("Payments", `[V5-PERSIST] Saving ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")} (${json.length} bytes)`);
6332
6481
  await this.deps.storage.set(
6333
6482
  STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS,
6334
6483
  json
6335
6484
  );
6336
6485
  const verify = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS);
6337
6486
  if (!verify) {
6338
- console.error("[Payments][V5-PERSIST] CRITICAL: KV write succeeded but read-back is empty!");
6487
+ logger.error("Payments", "[V5-PERSIST] CRITICAL: KV write succeeded but read-back is empty!");
6339
6488
  } else {
6340
- this.log(`[V5-PERSIST] Verified: read-back ${verify.length} bytes`);
6489
+ logger.debug("Payments", `[V5-PERSIST] Verified: read-back ${verify.length} bytes`);
6341
6490
  }
6342
6491
  } else {
6343
- this.log(`[V5-PERSIST] No pending V5 tokens to save (total tokens: ${this.tokens.size}), clearing KV`);
6492
+ logger.debug("Payments", `[V5-PERSIST] No pending V5 tokens to save (total tokens: ${this.tokens.size}), clearing KV`);
6344
6493
  await this.deps.storage.set(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS, "");
6345
6494
  }
6346
6495
  }
@@ -6350,21 +6499,21 @@ var PaymentsModule = class _PaymentsModule {
6350
6499
  */
6351
6500
  async loadPendingV5Tokens() {
6352
6501
  const data = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS);
6353
- this.log(`[V5-PERSIST] loadPendingV5Tokens: KV data = ${data ? `${data.length} bytes` : "null/empty"}`);
6502
+ logger.debug("Payments", `[V5-PERSIST] loadPendingV5Tokens: KV data = ${data ? `${data.length} bytes` : "null/empty"}`);
6354
6503
  if (!data) return;
6355
6504
  try {
6356
6505
  const pendingTokens = JSON.parse(data);
6357
- this.log(`[V5-PERSIST] Parsed ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")}`);
6506
+ logger.debug("Payments", `[V5-PERSIST] Parsed ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")}`);
6358
6507
  for (const token of pendingTokens) {
6359
6508
  if (!this.tokens.has(token.id)) {
6360
6509
  this.tokens.set(token.id, token);
6361
- this.log(`[V5-PERSIST] Restored token ${token.id.slice(0, 16)} (status=${token.status})`);
6510
+ logger.debug("Payments", `[V5-PERSIST] Restored token ${token.id.slice(0, 16)} (status=${token.status})`);
6362
6511
  } else {
6363
- this.log(`[V5-PERSIST] Token ${token.id.slice(0, 16)} already in map, skipping`);
6512
+ logger.debug("Payments", `[V5-PERSIST] Token ${token.id.slice(0, 16)} already in map, skipping`);
6364
6513
  }
6365
6514
  }
6366
6515
  } catch (err) {
6367
- console.error("[Payments][V5-PERSIST] Failed to parse pending V5 tokens:", err);
6516
+ logger.error("Payments", "[V5-PERSIST] Failed to parse pending V5 tokens:", err);
6368
6517
  }
6369
6518
  }
6370
6519
  /**
@@ -6417,13 +6566,13 @@ var PaymentsModule = class _PaymentsModule {
6417
6566
  const incomingStateHash = extractStateHashFromSdkData(token.sdkData);
6418
6567
  const incomingStateKey = incomingTokenId && incomingStateHash ? createTokenStateKey(incomingTokenId, incomingStateHash) : null;
6419
6568
  if (incomingTokenId && incomingStateHash && this.isStateTombstoned(incomingTokenId, incomingStateHash)) {
6420
- this.log(`Rejecting tombstoned token: ${incomingTokenId.slice(0, 8)}..._${incomingStateHash.slice(0, 8)}...`);
6569
+ logger.debug("Payments", `Rejecting tombstoned token: ${incomingTokenId.slice(0, 8)}..._${incomingStateHash.slice(0, 8)}...`);
6421
6570
  return false;
6422
6571
  }
6423
6572
  if (incomingStateKey) {
6424
6573
  for (const [_existingId, existing] of this.tokens) {
6425
6574
  if (isSameTokenState(existing, token)) {
6426
- this.log(`Duplicate token state ignored: ${incomingTokenId?.slice(0, 8)}..._${incomingStateHash?.slice(0, 8)}...`);
6575
+ logger.debug("Payments", `Duplicate token state ignored: ${incomingTokenId?.slice(0, 8)}..._${incomingStateHash?.slice(0, 8)}...`);
6427
6576
  return false;
6428
6577
  }
6429
6578
  }
@@ -6435,19 +6584,19 @@ var PaymentsModule = class _PaymentsModule {
6435
6584
  continue;
6436
6585
  }
6437
6586
  if (existing.status === "spent" || existing.status === "invalid") {
6438
- this.log(`Replacing spent/invalid token ${incomingTokenId?.slice(0, 8)}...`);
6587
+ logger.debug("Payments", `Replacing spent/invalid token ${incomingTokenId?.slice(0, 8)}...`);
6439
6588
  this.tokens.delete(existingId);
6440
6589
  break;
6441
6590
  }
6442
6591
  if (incomingStateHash && existingStateHash && incomingStateHash !== existingStateHash) {
6443
- this.log(`Token ${incomingTokenId?.slice(0, 8)}... state updated: ${existingStateHash.slice(0, 8)}... -> ${incomingStateHash.slice(0, 8)}...`);
6592
+ logger.debug("Payments", `Token ${incomingTokenId?.slice(0, 8)}... state updated: ${existingStateHash.slice(0, 8)}... -> ${incomingStateHash.slice(0, 8)}...`);
6444
6593
  await this.archiveToken(existing);
6445
6594
  this.tokens.delete(existingId);
6446
6595
  break;
6447
6596
  }
6448
6597
  if (!incomingStateHash || !existingStateHash) {
6449
6598
  if (existingId !== token.id) {
6450
- this.log(`Token ${incomingTokenId?.slice(0, 8)}... .id changed, replacing`);
6599
+ logger.debug("Payments", `Token ${incomingTokenId?.slice(0, 8)}... .id changed, replacing`);
6451
6600
  await this.archiveToken(existing);
6452
6601
  this.tokens.delete(existingId);
6453
6602
  break;
@@ -6458,7 +6607,7 @@ var PaymentsModule = class _PaymentsModule {
6458
6607
  this.tokens.set(token.id, token);
6459
6608
  await this.archiveToken(token);
6460
6609
  await this.save();
6461
- this.log(`Added token ${token.id}, total: ${this.tokens.size}`);
6610
+ logger.debug("Payments", `Added token ${token.id}, total: ${this.tokens.size}`);
6462
6611
  return true;
6463
6612
  }
6464
6613
  /**
@@ -6488,7 +6637,7 @@ var PaymentsModule = class _PaymentsModule {
6488
6637
  }
6489
6638
  await this.archiveToken(token);
6490
6639
  await this.save();
6491
- this.log(`Updated token ${token.id}`);
6640
+ logger.debug("Payments", `Updated token ${token.id}`);
6492
6641
  }
6493
6642
  /**
6494
6643
  * Remove a token from the wallet.
@@ -6511,10 +6660,10 @@ var PaymentsModule = class _PaymentsModule {
6511
6660
  );
6512
6661
  if (!alreadyTombstoned) {
6513
6662
  this.tombstones.push(tombstone);
6514
- this.log(`Created tombstone for ${tombstone.tokenId.slice(0, 8)}..._${tombstone.stateHash.slice(0, 8)}...`);
6663
+ logger.debug("Payments", `Created tombstone for ${tombstone.tokenId.slice(0, 8)}..._${tombstone.stateHash.slice(0, 8)}...`);
6515
6664
  }
6516
6665
  } else {
6517
- this.log(`Warning: Could not create tombstone for token ${tokenId.slice(0, 8)}... (missing tokenId or stateHash)`);
6666
+ logger.debug("Payments", `Warning: Could not create tombstone for token ${tokenId.slice(0, 8)}... (missing tokenId or stateHash)`);
6518
6667
  }
6519
6668
  this.tokens.delete(tokenId);
6520
6669
  await this.save();
@@ -6571,7 +6720,7 @@ var PaymentsModule = class _PaymentsModule {
6571
6720
  }
6572
6721
  for (const token of tokensToRemove) {
6573
6722
  this.tokens.delete(token.id);
6574
- this.log(`Removed tombstoned token ${token.id.slice(0, 8)}...`);
6723
+ logger.debug("Payments", `Removed tombstoned token ${token.id.slice(0, 8)}...`);
6575
6724
  removedCount++;
6576
6725
  }
6577
6726
  for (const remoteTombstone of remoteTombstones) {
@@ -6597,7 +6746,7 @@ var PaymentsModule = class _PaymentsModule {
6597
6746
  this.tombstones = pruneTombstonesByAge(this.tombstones, maxAge);
6598
6747
  if (this.tombstones.length < originalCount) {
6599
6748
  await this.save();
6600
- this.log(`Pruned tombstones from ${originalCount} to ${this.tombstones.length}`);
6749
+ logger.debug("Payments", `Pruned tombstones from ${originalCount} to ${this.tombstones.length}`);
6601
6750
  }
6602
6751
  }
6603
6752
  // ===========================================================================
@@ -6669,7 +6818,7 @@ var PaymentsModule = class _PaymentsModule {
6669
6818
  const originalCount = this.archivedTokens.size;
6670
6819
  this.archivedTokens = pruneMapByCount(this.archivedTokens, maxCount);
6671
6820
  await this.save();
6672
- this.log(`Pruned archived tokens from ${originalCount} to ${this.archivedTokens.size}`);
6821
+ logger.debug("Payments", `Pruned archived tokens from ${originalCount} to ${this.archivedTokens.size}`);
6673
6822
  }
6674
6823
  // ===========================================================================
6675
6824
  // Public API - Forked Tokens
@@ -6698,7 +6847,7 @@ var PaymentsModule = class _PaymentsModule {
6698
6847
  const key = `${tokenId}_${stateHash}`;
6699
6848
  if (this.forkedTokens.has(key)) return;
6700
6849
  this.forkedTokens.set(key, txfToken);
6701
- this.log(`Stored forked token ${tokenId.slice(0, 8)}... state ${stateHash.slice(0, 12)}...`);
6850
+ logger.debug("Payments", `Stored forked token ${tokenId.slice(0, 8)}... state ${stateHash.slice(0, 12)}...`);
6702
6851
  await this.save();
6703
6852
  }
6704
6853
  /**
@@ -6730,7 +6879,7 @@ var PaymentsModule = class _PaymentsModule {
6730
6879
  const originalCount = this.forkedTokens.size;
6731
6880
  this.forkedTokens = pruneMapByCount(this.forkedTokens, maxCount);
6732
6881
  await this.save();
6733
- this.log(`Pruned forked tokens from ${originalCount} to ${this.forkedTokens.size}`);
6882
+ logger.debug("Payments", `Pruned forked tokens from ${originalCount} to ${this.forkedTokens.size}`);
6734
6883
  }
6735
6884
  // ===========================================================================
6736
6885
  // Public API - Transaction History
@@ -6810,7 +6959,7 @@ var PaymentsModule = class _PaymentsModule {
6810
6959
  const imported = await provider.importHistoryEntries?.(records) ?? 0;
6811
6960
  if (imported > 0) {
6812
6961
  this._historyCache = await provider.getHistoryEntries();
6813
- this.log(`Migrated ${imported} history entries from KV to history store`);
6962
+ logger.debug("Payments", `Migrated ${imported} history entries from KV to history store`);
6814
6963
  }
6815
6964
  await this.deps.storage.remove(STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY);
6816
6965
  } catch {
@@ -6886,7 +7035,7 @@ var PaymentsModule = class _PaymentsModule {
6886
7035
  this.nametags.push(nametag);
6887
7036
  }
6888
7037
  await this.save();
6889
- this.log(`Nametag set: ${nametag.name}`);
7038
+ logger.debug("Payments", `Nametag set: ${nametag.name}`);
6890
7039
  }
6891
7040
  /**
6892
7041
  * Get the current (first) nametag data.
@@ -6935,7 +7084,7 @@ var PaymentsModule = class _PaymentsModule {
6935
7084
  const parsed = parseTxfStorageData(result.data);
6936
7085
  if (parsed.nametags.length > 0) {
6937
7086
  this.nametags = parsed.nametags;
6938
- this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
7087
+ logger.debug("Payments", `Reloaded ${parsed.nametags.length} nametag(s) from storage`);
6939
7088
  return;
6940
7089
  }
6941
7090
  }
@@ -6988,7 +7137,7 @@ var PaymentsModule = class _PaymentsModule {
6988
7137
  const result = await minter.mintNametag(nametag, ownerAddress);
6989
7138
  if (result.success && result.nametagData) {
6990
7139
  await this.setNametag(result.nametagData);
6991
- this.log(`Nametag minted and saved: ${result.nametagData.name}`);
7140
+ logger.debug("Payments", `Nametag minted and saved: ${result.nametagData.name}`);
6992
7141
  this.deps.emitEvent("nametag:registered", {
6993
7142
  nametag: result.nametagData.name,
6994
7143
  addressIndex: 0
@@ -6998,7 +7147,7 @@ var PaymentsModule = class _PaymentsModule {
6998
7147
  return result;
6999
7148
  } catch (error) {
7000
7149
  const errorMsg = error instanceof Error ? error.message : String(error);
7001
- this.log("mintNametag failed:", errorMsg);
7150
+ logger.debug("Payments", "mintNametag failed:", errorMsg);
7002
7151
  return {
7003
7152
  success: false,
7004
7153
  error: errorMsg
@@ -7096,7 +7245,7 @@ var PaymentsModule = class _PaymentsModule {
7096
7245
  restoredCount++;
7097
7246
  }
7098
7247
  if (restoredCount > 0) {
7099
- console.log(`[Payments] Sync: restored ${restoredCount} token(s) lost by loadFromStorageData`);
7248
+ logger.debug("Payments", `Sync: restored ${restoredCount} token(s) lost by loadFromStorageData`);
7100
7249
  }
7101
7250
  if (this.nametags.length === 0 && savedNametags.length > 0) {
7102
7251
  this.nametags = savedNametags;
@@ -7105,7 +7254,7 @@ var PaymentsModule = class _PaymentsModule {
7105
7254
  if (txfData._history && txfData._history.length > 0) {
7106
7255
  const imported = await this.importRemoteHistoryEntries(txfData._history);
7107
7256
  if (imported > 0) {
7108
- this.log(`Imported ${imported} history entries from IPFS sync`);
7257
+ logger.debug("Payments", `Imported ${imported} history entries from IPFS sync`);
7109
7258
  }
7110
7259
  }
7111
7260
  totalAdded += result.added;
@@ -7118,7 +7267,7 @@ var PaymentsModule = class _PaymentsModule {
7118
7267
  removed: result.removed
7119
7268
  });
7120
7269
  } catch (providerError) {
7121
- console.warn(`[PaymentsModule] Sync failed for provider ${providerId}:`, providerError);
7270
+ logger.warn("Payments", `Sync failed for provider ${providerId}:`, providerError);
7122
7271
  this.deps.emitEvent("sync:provider", {
7123
7272
  providerId,
7124
7273
  success: false,
@@ -7156,7 +7305,7 @@ var PaymentsModule = class _PaymentsModule {
7156
7305
  if (provider.onEvent) {
7157
7306
  const unsub = provider.onEvent((event) => {
7158
7307
  if (event.type === "storage:remote-updated") {
7159
- this.log("Remote update detected from provider", providerId, event.data);
7308
+ logger.debug("Payments", "Remote update detected from provider", providerId, event.data);
7160
7309
  this.debouncedSyncFromRemoteUpdate(providerId, event.data);
7161
7310
  }
7162
7311
  });
@@ -7198,7 +7347,7 @@ var PaymentsModule = class _PaymentsModule {
7198
7347
  removed: result.removed
7199
7348
  });
7200
7349
  }).catch((err) => {
7201
- this.log("Auto-sync from remote update failed:", err);
7350
+ logger.debug("Payments", "Auto-sync from remote update failed:", err);
7202
7351
  });
7203
7352
  }, _PaymentsModule.SYNC_DEBOUNCE_MS);
7204
7353
  }
@@ -7303,8 +7452,9 @@ var PaymentsModule = class _PaymentsModule {
7303
7452
  }
7304
7453
  return recipient;
7305
7454
  }
7306
- throw new Error(
7307
- `Cannot resolve transport pubkey for "${recipient}". No binding event found. The recipient must publish their identity first.`
7455
+ throw new SphereError(
7456
+ `Cannot resolve transport pubkey for "${recipient}". No binding event found. The recipient must publish their identity first.`,
7457
+ "INVALID_RECIPIENT"
7308
7458
  );
7309
7459
  }
7310
7460
  /**
@@ -7375,32 +7525,33 @@ var PaymentsModule = class _PaymentsModule {
7375
7525
  return AddressFactory.createAddress(recipient);
7376
7526
  }
7377
7527
  if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
7378
- this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
7528
+ logger.debug("Payments", "Creating DirectAddress from 33-byte compressed pubkey");
7379
7529
  return this.createDirectAddressFromPubkey(recipient);
7380
7530
  }
7381
7531
  const info = peerInfo ?? await this.deps?.transport.resolve?.(recipient) ?? null;
7382
7532
  if (!info) {
7383
- throw new Error(
7384
- `Recipient "${recipient}" not found. Use @nametag, a valid PROXY:/DIRECT: address, or a 33-byte hex pubkey.`
7533
+ throw new SphereError(
7534
+ `Recipient "${recipient}" not found. Use @nametag, a valid PROXY:/DIRECT: address, or a 33-byte hex pubkey.`,
7535
+ "INVALID_RECIPIENT"
7385
7536
  );
7386
7537
  }
7387
7538
  const nametag = recipient.startsWith("@") ? recipient.slice(1) : info.nametag || recipient;
7388
7539
  if (addressMode === "proxy") {
7389
- console.log(`[Payments] Using PROXY address for "${nametag}" (forced)`);
7540
+ logger.debug("Payments", `Using PROXY address for "${nametag}" (forced)`);
7390
7541
  return ProxyAddress.fromNameTag(nametag);
7391
7542
  }
7392
7543
  if (addressMode === "direct") {
7393
7544
  if (!info.directAddress) {
7394
- throw new Error(`"${nametag}" has no DirectAddress stored. It may be a legacy registration.`);
7545
+ throw new SphereError(`"${nametag}" has no DirectAddress stored. It may be a legacy registration.`, "INVALID_RECIPIENT");
7395
7546
  }
7396
- console.log(`[Payments] Using DirectAddress for "${nametag}" (forced): ${info.directAddress.slice(0, 30)}...`);
7547
+ logger.debug("Payments", `Using DirectAddress for "${nametag}" (forced): ${info.directAddress.slice(0, 30)}...`);
7397
7548
  return AddressFactory.createAddress(info.directAddress);
7398
7549
  }
7399
7550
  if (info.directAddress) {
7400
- this.log(`Using DirectAddress for "${nametag}": ${info.directAddress.slice(0, 30)}...`);
7551
+ logger.debug("Payments", `Using DirectAddress for "${nametag}": ${info.directAddress.slice(0, 30)}...`);
7401
7552
  return AddressFactory.createAddress(info.directAddress);
7402
7553
  }
7403
- this.log(`Using PROXY address for legacy nametag "${nametag}"`);
7554
+ logger.debug("Payments", `Using PROXY address for legacy nametag "${nametag}"`);
7404
7555
  return ProxyAddress.fromNameTag(nametag);
7405
7556
  }
7406
7557
  /**
@@ -7413,7 +7564,7 @@ var PaymentsModule = class _PaymentsModule {
7413
7564
  const sourceTokenInput = typeof payload.sourceToken === "string" ? JSON.parse(payload.sourceToken) : payload.sourceToken;
7414
7565
  const commitmentInput = typeof payload.commitmentData === "string" ? JSON.parse(payload.commitmentData) : payload.commitmentData;
7415
7566
  if (!sourceTokenInput || !commitmentInput) {
7416
- console.warn("[Payments] Invalid NOSTR-FIRST transfer format");
7567
+ logger.warn("Payments", "Invalid NOSTR-FIRST transfer format");
7417
7568
  return;
7418
7569
  }
7419
7570
  const token = await this.saveCommitmentOnlyToken(
@@ -7444,7 +7595,7 @@ var PaymentsModule = class _PaymentsModule {
7444
7595
  tokenId: nostrTokenId || token.id
7445
7596
  });
7446
7597
  } catch (error) {
7447
- console.error("[Payments] Failed to process NOSTR-FIRST transfer:", error);
7598
+ logger.error("Payments", "Failed to process NOSTR-FIRST transfer:", error);
7448
7599
  }
7449
7600
  }
7450
7601
  /**
@@ -7469,18 +7620,19 @@ var PaymentsModule = class _PaymentsModule {
7469
7620
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
7470
7621
  let proxyNametag = this.getNametag();
7471
7622
  if (!proxyNametag?.token) {
7472
- this.log("Nametag missing in memory, attempting reload from storage...");
7623
+ logger.debug("Payments", "Nametag missing in memory, attempting reload from storage...");
7473
7624
  await this.reloadNametagsFromStorage();
7474
7625
  proxyNametag = this.getNametag();
7475
7626
  }
7476
7627
  if (!proxyNametag?.token) {
7477
- throw new Error("Cannot finalize PROXY transfer - no nametag token");
7628
+ throw new SphereError("Cannot finalize PROXY transfer - no nametag token", "VALIDATION_ERROR");
7478
7629
  }
7479
7630
  const nametagToken = await SdkToken2.fromJSON(proxyNametag.token);
7480
7631
  const proxy = await ProxyAddress.fromTokenId(nametagToken.id);
7481
7632
  if (proxy.address !== recipientAddress.address) {
7482
- throw new Error(
7483
- `PROXY address mismatch: nametag resolves to ${proxy.address} but transfer targets ${recipientAddress.address}`
7633
+ throw new SphereError(
7634
+ `PROXY address mismatch: nametag resolves to ${proxy.address} but transfer targets ${recipientAddress.address}`,
7635
+ "VALIDATION_ERROR"
7484
7636
  );
7485
7637
  }
7486
7638
  nametagTokens = [nametagToken];
@@ -7500,12 +7652,12 @@ var PaymentsModule = class _PaymentsModule {
7500
7652
  try {
7501
7653
  const token = this.tokens.get(tokenId);
7502
7654
  if (!token) {
7503
- this.log(`Token ${tokenId} not found for finalization`);
7655
+ logger.debug("Payments", `Token ${tokenId} not found for finalization`);
7504
7656
  return;
7505
7657
  }
7506
7658
  const commitment = await TransferCommitment4.fromJSON(commitmentInput);
7507
7659
  if (!this.deps.oracle.waitForProofSdk) {
7508
- this.log("Cannot finalize - no waitForProofSdk");
7660
+ logger.debug("Payments", "Cannot finalize - no waitForProofSdk");
7509
7661
  token.status = "confirmed";
7510
7662
  token.updatedAt = Date.now();
7511
7663
  await this.save();
@@ -7517,7 +7669,7 @@ var PaymentsModule = class _PaymentsModule {
7517
7669
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7518
7670
  const trustBase = this.deps.oracle.getTrustBase?.();
7519
7671
  if (!stClient || !trustBase) {
7520
- this.log("Cannot finalize - missing state transition client or trust base");
7672
+ logger.debug("Payments", "Cannot finalize - missing state transition client or trust base");
7521
7673
  token.status = "confirmed";
7522
7674
  token.updatedAt = Date.now();
7523
7675
  await this.save();
@@ -7537,7 +7689,7 @@ var PaymentsModule = class _PaymentsModule {
7537
7689
  };
7538
7690
  this.tokens.set(tokenId, finalizedToken);
7539
7691
  await this.save();
7540
- this.log(`NOSTR-FIRST: Token ${tokenId.slice(0, 8)}... finalized and confirmed`);
7692
+ logger.debug("Payments", `NOSTR-FIRST: Token ${tokenId.slice(0, 8)}... finalized and confirmed`);
7541
7693
  this.deps.emitEvent("transfer:confirmed", {
7542
7694
  id: crypto.randomUUID(),
7543
7695
  status: "completed",
@@ -7545,7 +7697,7 @@ var PaymentsModule = class _PaymentsModule {
7545
7697
  tokenTransfers: []
7546
7698
  });
7547
7699
  } catch (error) {
7548
- console.error("[Payments] Failed to finalize received token:", error);
7700
+ logger.error("Payments", "Failed to finalize received token:", error);
7549
7701
  const token = this.tokens.get(tokenId);
7550
7702
  if (token && token.status === "submitted") {
7551
7703
  token.status = "confirmed";
@@ -7560,7 +7712,7 @@ var PaymentsModule = class _PaymentsModule {
7560
7712
  }
7561
7713
  try {
7562
7714
  const payload = transfer.payload;
7563
- console.log("[Payments][DEBUG] handleIncomingTransfer: keys=", Object.keys(payload).join(","));
7715
+ logger.debug("Payments", "handleIncomingTransfer: keys=", Object.keys(payload).join(","));
7564
7716
  let combinedBundle = null;
7565
7717
  if (isCombinedTransferBundleV6(payload)) {
7566
7718
  combinedBundle = payload;
@@ -7574,12 +7726,12 @@ var PaymentsModule = class _PaymentsModule {
7574
7726
  }
7575
7727
  }
7576
7728
  if (combinedBundle) {
7577
- this.log("Processing COMBINED_TRANSFER V6 bundle...");
7729
+ logger.debug("Payments", "Processing COMBINED_TRANSFER V6 bundle...");
7578
7730
  try {
7579
7731
  await this.processCombinedTransferBundle(combinedBundle, transfer.senderTransportPubkey);
7580
- this.log("COMBINED_TRANSFER V6 processed successfully");
7732
+ logger.debug("Payments", "COMBINED_TRANSFER V6 processed successfully");
7581
7733
  } catch (err) {
7582
- console.error("[Payments] COMBINED_TRANSFER V6 processing error:", err);
7734
+ logger.error("Payments", "COMBINED_TRANSFER V6 processing error:", err);
7583
7735
  }
7584
7736
  return;
7585
7737
  }
@@ -7596,7 +7748,7 @@ var PaymentsModule = class _PaymentsModule {
7596
7748
  }
7597
7749
  }
7598
7750
  if (instantBundle) {
7599
- this.log("Processing INSTANT_SPLIT bundle...");
7751
+ logger.debug("Payments", "Processing INSTANT_SPLIT bundle...");
7600
7752
  try {
7601
7753
  const result = await this.processInstantSplitBundle(
7602
7754
  instantBundle,
@@ -7604,28 +7756,28 @@ var PaymentsModule = class _PaymentsModule {
7604
7756
  payload.memo
7605
7757
  );
7606
7758
  if (result.success) {
7607
- this.log("INSTANT_SPLIT processed successfully");
7759
+ logger.debug("Payments", "INSTANT_SPLIT processed successfully");
7608
7760
  } else {
7609
- console.warn("[Payments] INSTANT_SPLIT processing failed:", result.error);
7761
+ logger.warn("Payments", "INSTANT_SPLIT processing failed:", result.error);
7610
7762
  }
7611
7763
  } catch (err) {
7612
- console.error("[Payments] INSTANT_SPLIT processing error:", err);
7764
+ logger.error("Payments", "INSTANT_SPLIT processing error:", err);
7613
7765
  }
7614
7766
  return;
7615
7767
  }
7616
7768
  if (payload.sourceToken && payload.commitmentData && !payload.transferTx) {
7617
- console.log("[Payments][DEBUG] >>> NOSTR-FIRST commitment-only transfer detected");
7769
+ logger.debug("Payments", "NOSTR-FIRST commitment-only transfer detected");
7618
7770
  await this.handleCommitmentOnlyTransfer(transfer, payload);
7619
7771
  return;
7620
7772
  }
7621
7773
  let tokenData;
7622
7774
  let finalizedSdkToken = null;
7623
7775
  if (payload.sourceToken && payload.transferTx) {
7624
- this.log("Processing Sphere wallet format transfer...");
7776
+ logger.debug("Payments", "Processing Sphere wallet format transfer...");
7625
7777
  const sourceTokenInput = typeof payload.sourceToken === "string" ? JSON.parse(payload.sourceToken) : payload.sourceToken;
7626
7778
  const transferTxInput = typeof payload.transferTx === "string" ? JSON.parse(payload.transferTx) : payload.transferTx;
7627
7779
  if (!sourceTokenInput || !transferTxInput) {
7628
- console.warn("[Payments] Invalid Sphere wallet transfer format");
7780
+ logger.warn("Payments", "Invalid Sphere wallet transfer format");
7629
7781
  return;
7630
7782
  }
7631
7783
  let sourceToken;
@@ -7633,7 +7785,7 @@ var PaymentsModule = class _PaymentsModule {
7633
7785
  try {
7634
7786
  sourceToken = await SdkToken2.fromJSON(sourceTokenInput);
7635
7787
  } catch (err) {
7636
- console.error("[Payments] Failed to parse sourceToken:", err);
7788
+ logger.error("Payments", "Failed to parse sourceToken:", err);
7637
7789
  return;
7638
7790
  }
7639
7791
  try {
@@ -7647,16 +7799,16 @@ var PaymentsModule = class _PaymentsModule {
7647
7799
  const commitment = await TransferCommitment4.fromJSON(transferTxInput);
7648
7800
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7649
7801
  if (!stClient) {
7650
- console.error("[Payments] Cannot process commitment - no state transition client");
7802
+ logger.error("Payments", "Cannot process commitment - no state transition client");
7651
7803
  return;
7652
7804
  }
7653
7805
  const response = await stClient.submitTransferCommitment(commitment);
7654
7806
  if (response.status !== "SUCCESS" && response.status !== "REQUEST_ID_EXISTS") {
7655
- console.error("[Payments] Transfer commitment submission failed:", response.status);
7807
+ logger.error("Payments", "Transfer commitment submission failed:", response.status);
7656
7808
  return;
7657
7809
  }
7658
7810
  if (!this.deps.oracle.waitForProofSdk) {
7659
- console.error("[Payments] Cannot wait for proof - missing oracle method");
7811
+ logger.error("Payments", "Cannot wait for proof - missing oracle method");
7660
7812
  return;
7661
7813
  }
7662
7814
  const inclusionProof = await this.deps.oracle.waitForProofSdk(commitment);
@@ -7668,7 +7820,7 @@ var PaymentsModule = class _PaymentsModule {
7668
7820
  const commitment = await TransferCommitment4.fromJSON(transferTxInput);
7669
7821
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7670
7822
  if (!stClient || !this.deps.oracle.waitForProofSdk) {
7671
- throw new Error("Cannot submit commitment - missing oracle methods");
7823
+ throw new SphereError("Cannot submit commitment - missing oracle methods", "AGGREGATOR_ERROR");
7672
7824
  }
7673
7825
  await stClient.submitTransferCommitment(commitment);
7674
7826
  const inclusionProof = await this.deps.oracle.waitForProofSdk(commitment);
@@ -7676,33 +7828,33 @@ var PaymentsModule = class _PaymentsModule {
7676
7828
  }
7677
7829
  }
7678
7830
  } catch (err) {
7679
- console.error("[Payments] Failed to parse transferTx:", err);
7831
+ logger.error("Payments", "Failed to parse transferTx:", err);
7680
7832
  return;
7681
7833
  }
7682
7834
  try {
7683
7835
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7684
7836
  const trustBase = this.deps.oracle.getTrustBase?.();
7685
7837
  if (!stClient || !trustBase) {
7686
- console.error("[Payments] Cannot finalize - missing state transition client or trust base. Token rejected.");
7838
+ logger.error("Payments", "Cannot finalize - missing state transition client or trust base. Token rejected.");
7687
7839
  return;
7688
7840
  }
7689
7841
  finalizedSdkToken = await this.finalizeTransferToken(sourceToken, transferTx, stClient, trustBase);
7690
7842
  tokenData = finalizedSdkToken.toJSON();
7691
7843
  const addressScheme = transferTx.data.recipient.scheme;
7692
- this.log(`${addressScheme === AddressScheme.PROXY ? "PROXY" : "DIRECT"} finalization successful`);
7844
+ logger.debug("Payments", `${addressScheme === AddressScheme.PROXY ? "PROXY" : "DIRECT"} finalization successful`);
7693
7845
  } catch (finalizeError) {
7694
- console.error(`[Payments] Finalization FAILED - token rejected:`, finalizeError);
7846
+ logger.error("Payments", "Finalization FAILED - token rejected:", finalizeError);
7695
7847
  return;
7696
7848
  }
7697
7849
  } else if (payload.token) {
7698
7850
  tokenData = payload.token;
7699
7851
  } else {
7700
- console.warn("[Payments] Unknown transfer payload format");
7852
+ logger.warn("Payments", "Unknown transfer payload format");
7701
7853
  return;
7702
7854
  }
7703
7855
  const validation = await this.deps.oracle.validateToken(tokenData);
7704
7856
  if (!validation.valid) {
7705
- console.warn("[Payments] Received invalid token");
7857
+ logger.warn("Payments", "Received invalid token");
7706
7858
  return;
7707
7859
  }
7708
7860
  const tokenInfo = await parseTokenInfo(tokenData);
@@ -7743,12 +7895,12 @@ var PaymentsModule = class _PaymentsModule {
7743
7895
  receivedAt: transfer.timestamp
7744
7896
  };
7745
7897
  this.deps.emitEvent("transfer:incoming", incomingTransfer);
7746
- this.log(`Incoming transfer processed: ${token.id}, ${token.amount} ${token.symbol}`);
7898
+ logger.debug("Payments", `Incoming transfer processed: ${token.id}, ${token.amount} ${token.symbol}`);
7747
7899
  } else {
7748
- this.log(`Duplicate transfer ignored: ${token.id}, ${token.amount} ${token.symbol}`);
7900
+ logger.debug("Payments", `Duplicate transfer ignored: ${token.id}, ${token.amount} ${token.symbol}`);
7749
7901
  }
7750
7902
  } catch (error) {
7751
- console.error("[Payments] Failed to process incoming transfer:", error);
7903
+ logger.error("Payments", "Failed to process incoming transfer:", error);
7752
7904
  }
7753
7905
  }
7754
7906
  // ===========================================================================
@@ -7763,15 +7915,15 @@ var PaymentsModule = class _PaymentsModule {
7763
7915
  if (existingArchive) {
7764
7916
  if (isIncrementalUpdate(existingArchive, txf)) {
7765
7917
  this.archivedTokens.set(tokenId, txf);
7766
- this.log(`Updated archived token ${tokenId.slice(0, 8)}...`);
7918
+ logger.debug("Payments", `Updated archived token ${tokenId.slice(0, 8)}...`);
7767
7919
  } else {
7768
7920
  const stateHash = getCurrentStateHash(txf) || "";
7769
7921
  await this.storeForkedToken(tokenId, stateHash, txf);
7770
- this.log(`Archived token ${tokenId.slice(0, 8)}... is a fork`);
7922
+ logger.debug("Payments", `Archived token ${tokenId.slice(0, 8)}... is a fork`);
7771
7923
  }
7772
7924
  } else {
7773
7925
  this.archivedTokens.set(tokenId, txf);
7774
- this.log(`Archived token ${tokenId.slice(0, 8)}...`);
7926
+ logger.debug("Payments", `Archived token ${tokenId.slice(0, 8)}...`);
7775
7927
  }
7776
7928
  }
7777
7929
  // ===========================================================================
@@ -7783,20 +7935,20 @@ var PaymentsModule = class _PaymentsModule {
7783
7935
  const txf = tokenToTxf(t);
7784
7936
  return `${t.id.slice(0, 12)}(${t.status},txf=${!!txf})`;
7785
7937
  });
7786
- console.log(`[Payments][DEBUG] save(): providers=${providers.size}, tokens=[${tokenStats.join(", ")}]`);
7938
+ logger.debug("Payments", `save(): providers=${providers.size}, tokens=[${tokenStats.join(", ")}]`);
7787
7939
  if (providers.size > 0) {
7788
7940
  const data = await this.createStorageData();
7789
7941
  const dataKeys = Object.keys(data).filter((k) => k.startsWith("token-"));
7790
- console.log(`[Payments][DEBUG] save(): TXF keys=${dataKeys.length} (${dataKeys.join(", ")})`);
7942
+ logger.debug("Payments", `save(): TXF keys=${dataKeys.length} (${dataKeys.join(", ")})`);
7791
7943
  for (const [id, provider] of providers) {
7792
7944
  try {
7793
7945
  await provider.save(data);
7794
7946
  } catch (err) {
7795
- console.error(`[Payments] Failed to save to provider ${id}:`, err);
7947
+ logger.error("Payments", `Failed to save to provider ${id}:`, err);
7796
7948
  }
7797
7949
  }
7798
7950
  } else {
7799
- console.log("[Payments][DEBUG] save(): No token storage providers - TXF not persisted");
7951
+ logger.debug("Payments", "save(): No token storage providers - TXF not persisted");
7800
7952
  }
7801
7953
  await this.savePendingV5Tokens();
7802
7954
  }
@@ -7834,14 +7986,14 @@ var PaymentsModule = class _PaymentsModule {
7834
7986
  }
7835
7987
  loadFromStorageData(data) {
7836
7988
  const parsed = parseTxfStorageData(data);
7837
- console.log(`[Payments][DEBUG] loadFromStorageData: parsed ${parsed.tokens.length} tokens, ${parsed.tombstones.length} tombstones, errors=[${parsed.validationErrors.join("; ")}]`);
7989
+ logger.debug("Payments", `loadFromStorageData: parsed ${parsed.tokens.length} tokens, ${parsed.tombstones.length} tombstones, errors=[${parsed.validationErrors.join("; ")}]`);
7838
7990
  this.tombstones = parsed.tombstones;
7839
7991
  this.tokens.clear();
7840
7992
  for (const token of parsed.tokens) {
7841
7993
  const sdkTokenId = extractTokenIdFromSdkData(token.sdkData);
7842
7994
  const stateHash = extractStateHashFromSdkData(token.sdkData);
7843
7995
  if (sdkTokenId && stateHash && this.isStateTombstoned(sdkTokenId, stateHash)) {
7844
- this.log(`Skipping tombstoned token ${sdkTokenId.slice(0, 8)}... during load (exact state match)`);
7996
+ logger.debug("Payments", `Skipping tombstoned token ${sdkTokenId.slice(0, 8)}... during load (exact state match)`);
7845
7997
  continue;
7846
7998
  }
7847
7999
  this.tokens.set(token.id, token);
@@ -7861,12 +8013,12 @@ var PaymentsModule = class _PaymentsModule {
7861
8013
  try {
7862
8014
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7863
8015
  if (!stClient) {
7864
- this.log("Cannot submit commitment - no state transition client");
8016
+ logger.debug("Payments", "Cannot submit commitment - no state transition client");
7865
8017
  return;
7866
8018
  }
7867
8019
  const response = await stClient.submitTransferCommitment(commitment);
7868
8020
  if (response.status !== "SUCCESS" && response.status !== "REQUEST_ID_EXISTS") {
7869
- this.log(`Transfer commitment submission failed: ${response.status}`);
8021
+ logger.debug("Payments", `Transfer commitment submission failed: ${response.status}`);
7870
8022
  const token = this.tokens.get(tokenId);
7871
8023
  if (token) {
7872
8024
  token.status = "invalid";
@@ -7886,7 +8038,7 @@ var PaymentsModule = class _PaymentsModule {
7886
8038
  onProofReceived
7887
8039
  });
7888
8040
  } catch (error) {
7889
- this.log("submitAndPollForProof error:", error);
8041
+ logger.debug("Payments", "submitAndPollForProof error:", error);
7890
8042
  }
7891
8043
  }
7892
8044
  /**
@@ -7894,7 +8046,7 @@ var PaymentsModule = class _PaymentsModule {
7894
8046
  */
7895
8047
  addProofPollingJob(job) {
7896
8048
  this.proofPollingJobs.set(job.tokenId, job);
7897
- this.log(`Added proof polling job for token ${job.tokenId.slice(0, 8)}...`);
8049
+ logger.debug("Payments", `Added proof polling job for token ${job.tokenId.slice(0, 8)}...`);
7898
8050
  this.startProofPolling();
7899
8051
  }
7900
8052
  /**
@@ -7903,7 +8055,7 @@ var PaymentsModule = class _PaymentsModule {
7903
8055
  startProofPolling() {
7904
8056
  if (this.proofPollingInterval) return;
7905
8057
  if (this.proofPollingJobs.size === 0) return;
7906
- this.log("Starting proof polling...");
8058
+ logger.debug("Payments", "Starting proof polling...");
7907
8059
  this.proofPollingInterval = setInterval(
7908
8060
  () => this.processProofPollingQueue(),
7909
8061
  _PaymentsModule.PROOF_POLLING_INTERVAL_MS
@@ -7916,7 +8068,7 @@ var PaymentsModule = class _PaymentsModule {
7916
8068
  if (this.proofPollingInterval) {
7917
8069
  clearInterval(this.proofPollingInterval);
7918
8070
  this.proofPollingInterval = null;
7919
- this.log("Stopped proof polling");
8071
+ logger.debug("Payments", "Stopped proof polling");
7920
8072
  }
7921
8073
  }
7922
8074
  /**
@@ -7933,7 +8085,7 @@ var PaymentsModule = class _PaymentsModule {
7933
8085
  job.attemptCount++;
7934
8086
  job.lastAttemptAt = Date.now();
7935
8087
  if (job.attemptCount >= _PaymentsModule.PROOF_POLLING_MAX_ATTEMPTS) {
7936
- this.log(`Proof polling timeout for token ${tokenId.slice(0, 8)}...`);
8088
+ logger.debug("Payments", `Proof polling timeout for token ${tokenId.slice(0, 8)}...`);
7937
8089
  const token2 = this.tokens.get(tokenId);
7938
8090
  if (token2 && token2.status === "submitted") {
7939
8091
  token2.status = "invalid";
@@ -7972,12 +8124,12 @@ var PaymentsModule = class _PaymentsModule {
7972
8124
  token.updatedAt = Date.now();
7973
8125
  this.tokens.set(tokenId, token);
7974
8126
  await this.save();
7975
- this.log(`Proof received for token ${tokenId.slice(0, 8)}..., status: spent`);
8127
+ logger.debug("Payments", `Proof received for token ${tokenId.slice(0, 8)}..., status: spent`);
7976
8128
  }
7977
8129
  job.onProofReceived?.(tokenId);
7978
8130
  completedJobs.push(tokenId);
7979
8131
  } catch (error) {
7980
- this.log(`Proof polling attempt ${job.attemptCount} for ${tokenId.slice(0, 8)}...: ${error}`);
8132
+ logger.debug("Payments", `Proof polling attempt ${job.attemptCount} for ${tokenId.slice(0, 8)}...: ${error}`);
7981
8133
  }
7982
8134
  }
7983
8135
  for (const tokenId of completedJobs) {
@@ -7992,7 +8144,7 @@ var PaymentsModule = class _PaymentsModule {
7992
8144
  // ===========================================================================
7993
8145
  ensureInitialized() {
7994
8146
  if (!this.deps) {
7995
- throw new Error("PaymentsModule not initialized");
8147
+ throw new SphereError("PaymentsModule not initialized", "NOT_INITIALIZED");
7996
8148
  }
7997
8149
  }
7998
8150
  };
@@ -8000,7 +8152,12 @@ function createPaymentsModule(config) {
8000
8152
  return new PaymentsModule(config);
8001
8153
  }
8002
8154
 
8155
+ // modules/payments/BackgroundCommitmentService.ts
8156
+ init_logger();
8157
+ init_errors();
8158
+
8003
8159
  // modules/payments/TokenRecoveryService.ts
8160
+ init_logger();
8004
8161
  import { TokenId as TokenId4 } from "@unicitylabs/state-transition-sdk/lib/token/TokenId";
8005
8162
  import { TokenState as TokenState6 } from "@unicitylabs/state-transition-sdk/lib/token/TokenState";
8006
8163
  import { TokenType as TokenType4 } from "@unicitylabs/state-transition-sdk/lib/token/TokenType";
@@ -8009,6 +8166,8 @@ import { HashAlgorithm as HashAlgorithm6 } from "@unicitylabs/state-transition-s
8009
8166
  import { UnmaskedPredicate as UnmaskedPredicate6 } from "@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate";
8010
8167
 
8011
8168
  // modules/communications/CommunicationsModule.ts
8169
+ init_logger();
8170
+ init_errors();
8012
8171
  init_constants();
8013
8172
  var CommunicationsModule = class {
8014
8173
  config;
@@ -8103,7 +8262,7 @@ var CommunicationsModule = class {
8103
8262
  }
8104
8263
  if (myMessages.length > 0) {
8105
8264
  await this.save();
8106
- console.log(`[Communications] Migrated ${myMessages.length} messages to per-address storage`);
8265
+ logger.debug("Communications", `Migrated ${myMessages.length} messages to per-address storage`);
8107
8266
  }
8108
8267
  }
8109
8268
  }
@@ -8189,7 +8348,7 @@ var CommunicationsModule = class {
8189
8348
  const msg = this.messages.get(id);
8190
8349
  if (msg && msg.senderPubkey !== this.deps.identity.chainPubkey) {
8191
8350
  this.deps.transport.sendReadReceipt(msg.senderPubkey, id).catch((err) => {
8192
- console.warn("[Communications] Failed to send read receipt:", err);
8351
+ logger.warn("Communications", "Failed to send read receipt:", err);
8193
8352
  });
8194
8353
  }
8195
8354
  }
@@ -8389,7 +8548,7 @@ var CommunicationsModule = class {
8389
8548
  try {
8390
8549
  handler(message);
8391
8550
  } catch (error) {
8392
- console.error("[Communications] Handler error:", error);
8551
+ logger.error("Communications", "Handler error:", error);
8393
8552
  }
8394
8553
  }
8395
8554
  if (this.config.autoSave) {
@@ -8408,7 +8567,7 @@ var CommunicationsModule = class {
8408
8567
  try {
8409
8568
  handler(composing);
8410
8569
  } catch (error) {
8411
- console.error("[Communications] Composing handler error:", error);
8570
+ logger.error("Communications", "Composing handler error:", error);
8412
8571
  }
8413
8572
  }
8414
8573
  }
@@ -8426,7 +8585,7 @@ var CommunicationsModule = class {
8426
8585
  try {
8427
8586
  handler(message);
8428
8587
  } catch (error) {
8429
- console.error("[Communications] Handler error:", error);
8588
+ logger.error("Communications", "Handler error:", error);
8430
8589
  }
8431
8590
  }
8432
8591
  }
@@ -8467,7 +8626,7 @@ var CommunicationsModule = class {
8467
8626
  const nametag = recipient.slice(1);
8468
8627
  const pubkey = await this.deps.transport.resolveNametag?.(nametag);
8469
8628
  if (!pubkey) {
8470
- throw new Error(`Nametag not found: ${recipient}`);
8629
+ throw new SphereError(`Nametag not found: ${recipient}`, "INVALID_RECIPIENT");
8471
8630
  }
8472
8631
  return { pubkey, nametag };
8473
8632
  }
@@ -8475,7 +8634,7 @@ var CommunicationsModule = class {
8475
8634
  }
8476
8635
  ensureInitialized() {
8477
8636
  if (!this.deps) {
8478
- throw new Error("CommunicationsModule not initialized");
8637
+ throw new SphereError("CommunicationsModule not initialized", "NOT_INITIALIZED");
8479
8638
  }
8480
8639
  }
8481
8640
  };
@@ -8484,6 +8643,8 @@ function createCommunicationsModule(config) {
8484
8643
  }
8485
8644
 
8486
8645
  // modules/groupchat/GroupChatModule.ts
8646
+ init_logger();
8647
+ init_errors();
8487
8648
  init_constants();
8488
8649
  import {
8489
8650
  NostrClient,
@@ -8634,13 +8795,15 @@ var GroupChatModule = class {
8634
8795
  for (const subId of this.subscriptionIds) {
8635
8796
  try {
8636
8797
  this.client.unsubscribe(subId);
8637
- } catch {
8798
+ } catch (err) {
8799
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
8638
8800
  }
8639
8801
  }
8640
8802
  this.subscriptionIds = [];
8641
8803
  try {
8642
8804
  this.client.disconnect();
8643
- } catch {
8805
+ } catch (err) {
8806
+ logger.debug("GroupChat", "Failed to disconnect", err);
8644
8807
  }
8645
8808
  this.client = null;
8646
8809
  }
@@ -8680,7 +8843,8 @@ var GroupChatModule = class {
8680
8843
  for (const subId of this.subscriptionIds) {
8681
8844
  try {
8682
8845
  this.client.unsubscribe(subId);
8683
- } catch {
8846
+ } catch (err) {
8847
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
8684
8848
  }
8685
8849
  }
8686
8850
  this.subscriptionIds = [];
@@ -8715,21 +8879,21 @@ var GroupChatModule = class {
8715
8879
  }
8716
8880
  this.deps.emitEvent("groupchat:connection", { connected: true });
8717
8881
  } catch (error) {
8718
- console.error("[GroupChat] Failed to connect to relays", error);
8882
+ logger.error("GroupChat", "Failed to connect to relays", error);
8719
8883
  this.deps.emitEvent("groupchat:connection", { connected: false });
8720
8884
  this.scheduleReconnect();
8721
8885
  }
8722
8886
  }
8723
8887
  scheduleReconnect() {
8724
8888
  if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
8725
- console.error("[GroupChat] Max reconnection attempts reached");
8889
+ logger.error("GroupChat", "Max reconnection attempts reached");
8726
8890
  return;
8727
8891
  }
8728
8892
  this.reconnectAttempts++;
8729
8893
  this.reconnectTimer = setTimeout(() => {
8730
8894
  this.reconnectTimer = null;
8731
8895
  if (this.deps) {
8732
- this.connect().catch(console.error);
8896
+ this.connect().catch((err) => logger.error("GroupChat", "Reconnect failed:", err));
8733
8897
  }
8734
8898
  }, this.config.reconnectDelayMs);
8735
8899
  }
@@ -8964,7 +9128,8 @@ var GroupChatModule = class {
8964
9128
  },
8965
9129
  onComplete: () => {
8966
9130
  },
8967
- timeoutMs: 15e3
9131
+ timeoutMs: 15e3,
9132
+ timeoutLabel: "restoreJoinedGroups"
8968
9133
  }
8969
9134
  );
8970
9135
  if (groupIdsWithMembership.size === 0) return [];
@@ -8981,7 +9146,8 @@ var GroupChatModule = class {
8981
9146
  this.fetchMessages(groupId)
8982
9147
  ]);
8983
9148
  }
8984
- } catch {
9149
+ } catch (error) {
9150
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
8985
9151
  }
8986
9152
  }
8987
9153
  if (restoredGroups.length > 0) {
@@ -9014,7 +9180,8 @@ var GroupChatModule = class {
9014
9180
  },
9015
9181
  onComplete: () => {
9016
9182
  },
9017
- timeoutMs: 1e4
9183
+ timeoutMs: 1e4,
9184
+ timeoutLabel: "fetchAvailableGroups(metadata)"
9018
9185
  }
9019
9186
  ),
9020
9187
  this.oneshotSubscription(
@@ -9029,7 +9196,8 @@ var GroupChatModule = class {
9029
9196
  },
9030
9197
  onComplete: () => {
9031
9198
  },
9032
- timeoutMs: 1e4
9199
+ timeoutMs: 1e4,
9200
+ timeoutLabel: "fetchAvailableGroups(members)"
9033
9201
  }
9034
9202
  )
9035
9203
  ]);
@@ -9088,7 +9256,7 @@ var GroupChatModule = class {
9088
9256
  return true;
9089
9257
  }
9090
9258
  }
9091
- console.error("[GroupChat] Failed to join group", error);
9259
+ logger.error("GroupChat", "Failed to join group", error);
9092
9260
  return false;
9093
9261
  }
9094
9262
  }
@@ -9118,7 +9286,7 @@ var GroupChatModule = class {
9118
9286
  this.persistAll();
9119
9287
  return true;
9120
9288
  }
9121
- console.error("[GroupChat] Failed to leave group", error);
9289
+ logger.error("GroupChat", "Failed to leave group", error);
9122
9290
  return false;
9123
9291
  }
9124
9292
  }
@@ -9169,10 +9337,8 @@ var GroupChatModule = class {
9169
9337
  kind: NIP29_KINDS.JOIN_REQUEST,
9170
9338
  tags: [["h", group.id]],
9171
9339
  content: ""
9172
- }).catch(() => {
9173
- });
9174
- await this.fetchAndSaveMembers(group.id).catch(() => {
9175
- });
9340
+ }).catch((err) => logger.debug("GroupChat", "Background operation failed", err));
9341
+ await this.fetchAndSaveMembers(group.id).catch((err) => logger.debug("GroupChat", "Failed to fetch members", group.id, err));
9176
9342
  this.saveMemberToMemory({
9177
9343
  pubkey: creatorPubkey,
9178
9344
  groupId: group.id,
@@ -9184,7 +9350,7 @@ var GroupChatModule = class {
9184
9350
  this.schedulePersist();
9185
9351
  return group;
9186
9352
  } catch (error) {
9187
- console.error("[GroupChat] Failed to create group", error);
9353
+ logger.error("GroupChat", "Failed to create group", error);
9188
9354
  return null;
9189
9355
  }
9190
9356
  }
@@ -9211,7 +9377,7 @@ var GroupChatModule = class {
9211
9377
  }
9212
9378
  return false;
9213
9379
  } catch (error) {
9214
- console.error("[GroupChat] Failed to delete group", error);
9380
+ logger.error("GroupChat", "Failed to delete group", error);
9215
9381
  return false;
9216
9382
  }
9217
9383
  }
@@ -9231,7 +9397,7 @@ var GroupChatModule = class {
9231
9397
  });
9232
9398
  return eventId ? inviteCode : null;
9233
9399
  } catch (error) {
9234
- console.error("[GroupChat] Failed to create invite", error);
9400
+ logger.error("GroupChat", "Failed to create invite", error);
9235
9401
  return null;
9236
9402
  }
9237
9403
  }
@@ -9281,7 +9447,7 @@ var GroupChatModule = class {
9281
9447
  }
9282
9448
  return null;
9283
9449
  } catch (error) {
9284
- console.error("[GroupChat] Failed to send message", error);
9450
+ logger.error("GroupChat", "Failed to send message", error);
9285
9451
  return null;
9286
9452
  }
9287
9453
  }
@@ -9320,7 +9486,8 @@ var GroupChatModule = class {
9320
9486
  this.schedulePersist();
9321
9487
  return fetchedMessages;
9322
9488
  },
9323
- timeoutMs: 1e4
9489
+ timeoutMs: 1e4,
9490
+ timeoutLabel: `fetchMessages(${groupId})`
9324
9491
  });
9325
9492
  }
9326
9493
  // ===========================================================================
@@ -9381,7 +9548,7 @@ var GroupChatModule = class {
9381
9548
  }
9382
9549
  return false;
9383
9550
  } catch (error) {
9384
- console.error("[GroupChat] Failed to kick user", error);
9551
+ logger.error("GroupChat", "Failed to kick user", error);
9385
9552
  return false;
9386
9553
  }
9387
9554
  }
@@ -9404,7 +9571,7 @@ var GroupChatModule = class {
9404
9571
  }
9405
9572
  return false;
9406
9573
  } catch (error) {
9407
- console.error("[GroupChat] Failed to delete message", error);
9574
+ logger.error("GroupChat", "Failed to delete message", error);
9408
9575
  return false;
9409
9576
  }
9410
9577
  }
@@ -9689,7 +9856,7 @@ var GroupChatModule = class {
9689
9856
  this.persistTimer = setTimeout(() => {
9690
9857
  this.persistTimer = null;
9691
9858
  this.persistPromise = this.doPersistAll().catch((err) => {
9692
- console.error("[GroupChat] Persistence error:", err);
9859
+ logger.error("GroupChat", "Persistence error:", err);
9693
9860
  }).finally(() => {
9694
9861
  this.persistPromise = null;
9695
9862
  });
@@ -9869,7 +10036,8 @@ var GroupChatModule = class {
9869
10036
  if (state.subId) {
9870
10037
  try {
9871
10038
  this.client.unsubscribe(state.subId);
9872
- } catch {
10039
+ } catch (err) {
10040
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
9873
10041
  }
9874
10042
  const idx = this.subscriptionIds.indexOf(state.subId);
9875
10043
  if (idx >= 0) this.subscriptionIds.splice(idx, 1);
@@ -9884,12 +10052,17 @@ var GroupChatModule = class {
9884
10052
  });
9885
10053
  state.subId = subId;
9886
10054
  this.subscriptionIds.push(subId);
9887
- setTimeout(finish, opts.timeoutMs ?? 5e3);
10055
+ setTimeout(() => {
10056
+ if (!done && opts.timeoutLabel) {
10057
+ logger.warn("GroupChat", `${opts.timeoutLabel} timed out`);
10058
+ }
10059
+ finish();
10060
+ }, opts.timeoutMs ?? 5e3);
9888
10061
  });
9889
10062
  }
9890
10063
  ensureInitialized() {
9891
10064
  if (!this.deps) {
9892
- throw new Error("GroupChatModule not initialized");
10065
+ throw new SphereError("GroupChatModule not initialized", "NOT_INITIALIZED");
9893
10066
  }
9894
10067
  }
9895
10068
  async ensureConnected() {
@@ -12058,6 +12231,7 @@ var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {
12058
12231
  var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha2564);
12059
12232
 
12060
12233
  // modules/market/MarketModule.ts
12234
+ init_errors();
12061
12235
  var DEFAULT_MARKET_API_URL = "https://market-api.unicity.network";
12062
12236
  function hexToBytes3(hex) {
12063
12237
  const len = hex.length >> 1;
@@ -12247,7 +12421,7 @@ var MarketModule = class {
12247
12421
  // ---------------------------------------------------------------------------
12248
12422
  ensureIdentity() {
12249
12423
  if (!this.identity) {
12250
- throw new Error("MarketModule not initialized \u2014 call initialize() first");
12424
+ throw new SphereError("MarketModule not initialized \u2014 call initialize() first", "NOT_INITIALIZED");
12251
12425
  }
12252
12426
  }
12253
12427
  /** Register the agent's public key with the server (idempotent) */
@@ -12273,7 +12447,7 @@ var MarketModule = class {
12273
12447
  data = JSON.parse(text);
12274
12448
  } catch {
12275
12449
  }
12276
- throw new Error(data?.error ?? `Agent registration failed: HTTP ${res.status}`);
12450
+ throw new SphereError(data?.error ?? `Agent registration failed: HTTP ${res.status}`, "NETWORK_ERROR");
12277
12451
  }
12278
12452
  async parseResponse(res) {
12279
12453
  const text = await res.text();
@@ -12281,9 +12455,9 @@ var MarketModule = class {
12281
12455
  try {
12282
12456
  data = JSON.parse(text);
12283
12457
  } catch {
12284
- throw new Error(`Market API error: HTTP ${res.status} \u2014 unexpected response (not JSON)`);
12458
+ throw new SphereError(`Market API error: HTTP ${res.status} \u2014 unexpected response (not JSON)`, "NETWORK_ERROR");
12285
12459
  }
12286
- if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
12460
+ if (!res.ok) throw new SphereError(data.error ?? `HTTP ${res.status}`, "NETWORK_ERROR");
12287
12461
  return data;
12288
12462
  }
12289
12463
  async apiPost(path, body) {
@@ -12338,6 +12512,8 @@ function createMarketModule(config) {
12338
12512
  init_constants();
12339
12513
 
12340
12514
  // core/encryption.ts
12515
+ init_errors();
12516
+ init_logger();
12341
12517
  import CryptoJS6 from "crypto-js";
12342
12518
  var DEFAULT_ITERATIONS = 1e5;
12343
12519
  var KEY_SIZE = 256;
@@ -12386,7 +12562,7 @@ function decrypt2(encryptedData, password) {
12386
12562
  });
12387
12563
  const result = decrypted.toString(CryptoJS6.enc.Utf8);
12388
12564
  if (!result) {
12389
- throw new Error("Decryption failed: invalid password or corrupted data");
12565
+ throw new SphereError("Decryption failed: invalid password or corrupted data", "DECRYPTION_ERROR");
12390
12566
  }
12391
12567
  return result;
12392
12568
  }
@@ -12395,7 +12571,7 @@ function decryptJson(encryptedData, password) {
12395
12571
  try {
12396
12572
  return JSON.parse(decrypted);
12397
12573
  } catch {
12398
- throw new Error("Decryption failed: invalid JSON data");
12574
+ throw new SphereError("Decryption failed: invalid JSON data", "DECRYPTION_ERROR");
12399
12575
  }
12400
12576
  }
12401
12577
  function encryptSimple(plaintext, password) {
@@ -12405,7 +12581,7 @@ function decryptSimple(ciphertext, password) {
12405
12581
  const decrypted = CryptoJS6.AES.decrypt(ciphertext, password);
12406
12582
  const result = decrypted.toString(CryptoJS6.enc.Utf8);
12407
12583
  if (!result) {
12408
- throw new Error("Decryption failed: invalid password or corrupted data");
12584
+ throw new SphereError("Decryption failed: invalid password or corrupted data", "DECRYPTION_ERROR");
12409
12585
  }
12410
12586
  return result;
12411
12587
  }
@@ -12419,7 +12595,8 @@ function decryptWithSalt(ciphertext, password, salt) {
12419
12595
  const decrypted = CryptoJS6.AES.decrypt(ciphertext, key);
12420
12596
  const result = decrypted.toString(CryptoJS6.enc.Utf8);
12421
12597
  return result || null;
12422
- } catch {
12598
+ } catch (err) {
12599
+ logger.debug("Encryption", "decryptWithSalt failed", err);
12423
12600
  return null;
12424
12601
  }
12425
12602
  }
@@ -12442,7 +12619,7 @@ function serializeEncrypted(data) {
12442
12619
  function deserializeEncrypted(serialized) {
12443
12620
  const parsed = JSON.parse(serialized);
12444
12621
  if (!isEncryptedData(parsed)) {
12445
- throw new Error("Invalid encrypted data format");
12622
+ throw new SphereError("Invalid encrypted data format", "VALIDATION_ERROR");
12446
12623
  }
12447
12624
  return parsed;
12448
12625
  }
@@ -12451,6 +12628,7 @@ function generateRandomKey(bytes = 32) {
12451
12628
  }
12452
12629
 
12453
12630
  // core/scan.ts
12631
+ init_logger();
12454
12632
  async function scanAddressesImpl(deriveAddress, options = {}) {
12455
12633
  const maxAddresses = options.maxAddresses ?? 50;
12456
12634
  const gapLimit = options.gapLimit ?? 20;
@@ -12489,7 +12667,8 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
12489
12667
  nametag = tag;
12490
12668
  nametagsFoundCount++;
12491
12669
  }
12492
- } catch {
12670
+ } catch (err) {
12671
+ logger.debug("Sphere", "Nametag resolution failed during scan", err);
12493
12672
  }
12494
12673
  }
12495
12674
  foundAddresses.push({
@@ -12506,7 +12685,7 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
12506
12685
  consecutiveEmpty++;
12507
12686
  }
12508
12687
  } catch (err) {
12509
- console.warn(`[scanAddresses] Error checking ${addrInfo.address}:`, err);
12688
+ logger.warn("Sphere", `scanAddresses: Error checking ${addrInfo.address}:`, err);
12510
12689
  consecutiveEmpty++;
12511
12690
  }
12512
12691
  if (consecutiveEmpty >= gapLimit) {
@@ -12598,6 +12777,7 @@ init_network();
12598
12777
  import CryptoJS7 from "crypto-js";
12599
12778
 
12600
12779
  // core/utils.ts
12780
+ init_errors();
12601
12781
  var SECP256K1_ORDER = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
12602
12782
  var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
12603
12783
  function isValidPrivateKey(hex) {
@@ -12637,7 +12817,7 @@ function base58Decode(str) {
12637
12817
  for (let i = 0; i < str.length; i++) {
12638
12818
  const char = str[i];
12639
12819
  if (!(char in ALPHABET_MAP)) {
12640
- throw new Error("Invalid base58 character: " + char);
12820
+ throw new SphereError("Invalid base58 character: " + char, "VALIDATION_ERROR");
12641
12821
  }
12642
12822
  num = num * BigInt(58) + BigInt(ALPHABET_MAP[char]);
12643
12823
  }
@@ -12919,6 +13099,7 @@ function parseAndDecryptWalletText(content, password) {
12919
13099
  }
12920
13100
 
12921
13101
  // serialization/wallet-dat.ts
13102
+ init_errors();
12922
13103
  import CryptoJS8 from "crypto-js";
12923
13104
  function uint8ArrayToWordArray(u8arr) {
12924
13105
  const hex = bytesToHex2(u8arr);
@@ -13104,7 +13285,7 @@ async function decryptCMasterKey(cmk, password, onProgress) {
13104
13285
  );
13105
13286
  const result = CryptoJS8.enc.Hex.stringify(decrypted);
13106
13287
  if (!result || result.length !== 64) {
13107
- throw new Error("Master key decryption failed - incorrect password");
13288
+ throw new SphereError("Master key decryption failed - incorrect password", "DECRYPTION_ERROR");
13108
13289
  }
13109
13290
  return result;
13110
13291
  }
@@ -13399,6 +13580,7 @@ var Sphere = class _Sphere {
13399
13580
  * ```
13400
13581
  */
13401
13582
  static async init(options) {
13583
+ if (options.debug) logger.configure({ debug: true });
13402
13584
  _Sphere.configureTokenRegistry(options.storage, options.network);
13403
13585
  const groupChat = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
13404
13586
  const market = _Sphere.resolveMarketConfig(options.market);
@@ -13426,8 +13608,9 @@ var Sphere = class _Sphere {
13426
13608
  mnemonic = _Sphere.generateMnemonic();
13427
13609
  generatedMnemonic = mnemonic;
13428
13610
  } else {
13429
- throw new Error(
13430
- "No wallet exists and no mnemonic provided. Provide a mnemonic or set autoGenerate: true."
13611
+ throw new SphereError(
13612
+ "No wallet exists and no mnemonic provided. Provide a mnemonic or set autoGenerate: true.",
13613
+ "INVALID_CONFIG"
13431
13614
  );
13432
13615
  }
13433
13616
  }
@@ -13500,11 +13683,12 @@ var Sphere = class _Sphere {
13500
13683
  * Create new wallet with mnemonic
13501
13684
  */
13502
13685
  static async create(options) {
13686
+ if (options.debug) logger.configure({ debug: true });
13503
13687
  if (!options.mnemonic || !_Sphere.validateMnemonic(options.mnemonic)) {
13504
- throw new Error("Invalid mnemonic");
13688
+ throw new SphereError("Invalid mnemonic", "INVALID_IDENTITY");
13505
13689
  }
13506
13690
  if (await _Sphere.exists(options.storage)) {
13507
- throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
13691
+ throw new SphereError("Wallet already exists. Use Sphere.load() or Sphere.clear() first.", "ALREADY_INITIALIZED");
13508
13692
  }
13509
13693
  const progress = options.onProgress;
13510
13694
  if (!options.storage.isConnected()) {
@@ -13550,10 +13734,10 @@ var Sphere = class _Sphere {
13550
13734
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13551
13735
  const result = await sphere.discoverAddresses(discoverOpts);
13552
13736
  if (result.addresses.length > 0) {
13553
- console.log(`[Sphere.create] Address discovery: found ${result.addresses.length} address(es)`);
13737
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
13554
13738
  }
13555
13739
  } catch (err) {
13556
- console.warn("[Sphere.create] Address discovery failed (non-fatal):", err);
13740
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
13557
13741
  }
13558
13742
  }
13559
13743
  progress?.({ step: "complete", message: "Wallet created" });
@@ -13563,8 +13747,9 @@ var Sphere = class _Sphere {
13563
13747
  * Load existing wallet from storage
13564
13748
  */
13565
13749
  static async load(options) {
13750
+ if (options.debug) logger.configure({ debug: true });
13566
13751
  if (!await _Sphere.exists(options.storage)) {
13567
- throw new Error("No wallet found. Use Sphere.create() to create a new wallet.");
13752
+ throw new SphereError("No wallet found. Use Sphere.create() to create a new wallet.", "NOT_INITIALIZED");
13568
13753
  }
13569
13754
  const progress = options.onProgress;
13570
13755
  _Sphere.configureTokenRegistry(options.storage, options.network);
@@ -13595,16 +13780,16 @@ var Sphere = class _Sphere {
13595
13780
  _Sphere.instance = sphere;
13596
13781
  if (sphere._identity?.nametag && !sphere._payments.hasNametag()) {
13597
13782
  progress?.({ step: "registering_nametag", message: "Restoring nametag token..." });
13598
- console.log(`[Sphere] Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
13783
+ logger.debug("Sphere", `Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
13599
13784
  try {
13600
13785
  const result = await sphere.mintNametag(sphere._identity.nametag);
13601
13786
  if (result.success) {
13602
- console.log(`[Sphere] Nametag token minted successfully on load`);
13787
+ logger.debug("Sphere", `Nametag token minted successfully on load`);
13603
13788
  } else {
13604
- console.warn(`[Sphere] Could not mint nametag token: ${result.error}`);
13789
+ logger.warn("Sphere", `Could not mint nametag token: ${result.error}`);
13605
13790
  }
13606
13791
  } catch (err) {
13607
- console.warn(`[Sphere] Nametag token mint failed:`, err);
13792
+ logger.warn("Sphere", `Nametag token mint failed:`, err);
13608
13793
  }
13609
13794
  }
13610
13795
  if (options.discoverAddresses !== false && sphere._transport.discoverAddresses && sphere._masterKey) {
@@ -13613,10 +13798,10 @@ var Sphere = class _Sphere {
13613
13798
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13614
13799
  const result = await sphere.discoverAddresses(discoverOpts);
13615
13800
  if (result.addresses.length > 0) {
13616
- console.log(`[Sphere.load] Address discovery: found ${result.addresses.length} address(es)`);
13801
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
13617
13802
  }
13618
13803
  } catch (err) {
13619
- console.warn("[Sphere.load] Address discovery failed (non-fatal):", err);
13804
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
13620
13805
  }
13621
13806
  }
13622
13807
  progress?.({ step: "complete", message: "Wallet loaded" });
@@ -13626,24 +13811,25 @@ var Sphere = class _Sphere {
13626
13811
  * Import wallet from mnemonic or master key
13627
13812
  */
13628
13813
  static async import(options) {
13814
+ if (options.debug) logger.configure({ debug: true });
13629
13815
  if (!options.mnemonic && !options.masterKey) {
13630
- throw new Error("Either mnemonic or masterKey is required");
13816
+ throw new SphereError("Either mnemonic or masterKey is required", "INVALID_CONFIG");
13631
13817
  }
13632
13818
  const progress = options.onProgress;
13633
- console.log("[Sphere.import] Starting import...");
13819
+ logger.debug("Sphere", "Starting import...");
13634
13820
  const needsClear = _Sphere.instance !== null || await _Sphere.exists(options.storage);
13635
13821
  if (needsClear) {
13636
13822
  progress?.({ step: "clearing", message: "Clearing previous wallet data..." });
13637
- console.log("[Sphere.import] Clearing existing wallet data...");
13823
+ logger.debug("Sphere", "Clearing existing wallet data...");
13638
13824
  await _Sphere.clear({ storage: options.storage, tokenStorage: options.tokenStorage });
13639
- console.log("[Sphere.import] Clear done");
13825
+ logger.debug("Sphere", "Clear done");
13640
13826
  } else {
13641
- console.log("[Sphere.import] No existing wallet \u2014 skipping clear");
13827
+ logger.debug("Sphere", "No existing wallet \u2014 skipping clear");
13642
13828
  }
13643
13829
  if (!options.storage.isConnected()) {
13644
- console.log("[Sphere.import] Reconnecting storage...");
13830
+ logger.debug("Sphere", "Reconnecting storage...");
13645
13831
  await options.storage.connect();
13646
- console.log("[Sphere.import] Storage reconnected");
13832
+ logger.debug("Sphere", "Storage reconnected");
13647
13833
  }
13648
13834
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat);
13649
13835
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -13661,14 +13847,14 @@ var Sphere = class _Sphere {
13661
13847
  progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
13662
13848
  if (options.mnemonic) {
13663
13849
  if (!_Sphere.validateMnemonic(options.mnemonic)) {
13664
- throw new Error("Invalid mnemonic");
13850
+ throw new SphereError("Invalid mnemonic", "INVALID_IDENTITY");
13665
13851
  }
13666
- console.log("[Sphere.import] Storing mnemonic...");
13852
+ logger.debug("Sphere", "Storing mnemonic...");
13667
13853
  await sphere.storeMnemonic(options.mnemonic, options.derivationPath, options.basePath);
13668
- console.log("[Sphere.import] Initializing identity from mnemonic...");
13854
+ logger.debug("Sphere", "Initializing identity from mnemonic...");
13669
13855
  await sphere.initializeIdentityFromMnemonic(options.mnemonic, options.derivationPath);
13670
13856
  } else if (options.masterKey) {
13671
- console.log("[Sphere.import] Storing master key...");
13857
+ logger.debug("Sphere", "Storing master key...");
13672
13858
  await sphere.storeMasterKey(
13673
13859
  options.masterKey,
13674
13860
  options.chainCode,
@@ -13676,7 +13862,7 @@ var Sphere = class _Sphere {
13676
13862
  options.basePath,
13677
13863
  options.derivationMode
13678
13864
  );
13679
- console.log("[Sphere.import] Initializing identity from master key...");
13865
+ logger.debug("Sphere", "Initializing identity from master key...");
13680
13866
  await sphere.initializeIdentityFromMasterKey(
13681
13867
  options.masterKey,
13682
13868
  options.chainCode,
@@ -13684,38 +13870,38 @@ var Sphere = class _Sphere {
13684
13870
  );
13685
13871
  }
13686
13872
  progress?.({ step: "initializing", message: "Initializing wallet..." });
13687
- console.log("[Sphere.import] Initializing providers...");
13873
+ logger.debug("Sphere", "Initializing providers...");
13688
13874
  await sphere.initializeProviders();
13689
- console.log("[Sphere.import] Providers initialized. Initializing modules...");
13875
+ logger.debug("Sphere", "Providers initialized. Initializing modules...");
13690
13876
  await sphere.initializeModules();
13691
- console.log("[Sphere.import] Modules initialized");
13877
+ logger.debug("Sphere", "Modules initialized");
13692
13878
  if (!options.nametag) {
13693
13879
  progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
13694
- console.log("[Sphere.import] Recovering nametag from transport...");
13880
+ logger.debug("Sphere", "Recovering nametag from transport...");
13695
13881
  await sphere.recoverNametagFromTransport();
13696
- console.log("[Sphere.import] Nametag recovery done");
13882
+ logger.debug("Sphere", "Nametag recovery done");
13697
13883
  progress?.({ step: "syncing_identity", message: "Publishing identity..." });
13698
13884
  await sphere.syncIdentityWithTransport();
13699
13885
  }
13700
13886
  progress?.({ step: "finalizing", message: "Finalizing wallet..." });
13701
- console.log("[Sphere.import] Finalizing wallet creation...");
13887
+ logger.debug("Sphere", "Finalizing wallet creation...");
13702
13888
  await sphere.finalizeWalletCreation();
13703
13889
  sphere._initialized = true;
13704
13890
  _Sphere.instance = sphere;
13705
- console.log("[Sphere.import] Tracking address 0...");
13891
+ logger.debug("Sphere", "Tracking address 0...");
13706
13892
  await sphere.ensureAddressTracked(0);
13707
13893
  if (options.nametag) {
13708
13894
  progress?.({ step: "registering_nametag", message: "Registering nametag..." });
13709
- console.log("[Sphere.import] Registering nametag...");
13895
+ logger.debug("Sphere", "Registering nametag...");
13710
13896
  await sphere.registerNametag(options.nametag);
13711
13897
  }
13712
13898
  if (sphere._tokenStorageProviders.size > 0) {
13713
13899
  progress?.({ step: "syncing_tokens", message: "Syncing tokens..." });
13714
13900
  try {
13715
13901
  const syncResult = await sphere._payments.sync();
13716
- console.log(`[Sphere.import] Auto-sync: +${syncResult.added} -${syncResult.removed}`);
13902
+ logger.debug("Sphere", `Auto-sync: +${syncResult.added} -${syncResult.removed}`);
13717
13903
  } catch (err) {
13718
- console.warn("[Sphere.import] Auto-sync failed (non-fatal):", err);
13904
+ logger.warn("Sphere", "Auto-sync failed (non-fatal):", err);
13719
13905
  }
13720
13906
  }
13721
13907
  if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
@@ -13724,14 +13910,14 @@ var Sphere = class _Sphere {
13724
13910
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13725
13911
  const result = await sphere.discoverAddresses(discoverOpts);
13726
13912
  if (result.addresses.length > 0) {
13727
- console.log(`[Sphere.import] Address discovery: found ${result.addresses.length} address(es)`);
13913
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
13728
13914
  }
13729
13915
  } catch (err) {
13730
- console.warn("[Sphere.import] Address discovery failed (non-fatal):", err);
13916
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
13731
13917
  }
13732
13918
  }
13733
13919
  progress?.({ step: "complete", message: "Import complete" });
13734
- console.log("[Sphere.import] Import complete");
13920
+ logger.debug("Sphere", "Import complete");
13735
13921
  return sphere;
13736
13922
  }
13737
13923
  /**
@@ -13757,26 +13943,26 @@ var Sphere = class _Sphere {
13757
13943
  const storage = "get" in storageOrOptions ? storageOrOptions : storageOrOptions.storage;
13758
13944
  const tokenStorage = "get" in storageOrOptions ? void 0 : storageOrOptions.tokenStorage;
13759
13945
  if (_Sphere.instance) {
13760
- console.log("[Sphere.clear] Destroying Sphere instance...");
13946
+ logger.debug("Sphere", "Destroying Sphere instance...");
13761
13947
  await _Sphere.instance.destroy();
13762
- console.log("[Sphere.clear] Sphere instance destroyed");
13948
+ logger.debug("Sphere", "Sphere instance destroyed");
13763
13949
  }
13764
- console.log("[Sphere.clear] Clearing L1 vesting cache...");
13950
+ logger.debug("Sphere", "Clearing L1 vesting cache...");
13765
13951
  await vestingClassifier.destroy();
13766
- console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
13952
+ logger.debug("Sphere", "Yielding 50ms for IDB transaction settlement...");
13767
13953
  await new Promise((r) => setTimeout(r, 50));
13768
13954
  if (tokenStorage?.clear) {
13769
- console.log("[Sphere.clear] Clearing token storage...");
13955
+ logger.debug("Sphere", "Clearing token storage...");
13770
13956
  try {
13771
13957
  await tokenStorage.clear();
13772
- console.log("[Sphere.clear] Token storage cleared");
13958
+ logger.debug("Sphere", "Token storage cleared");
13773
13959
  } catch (err) {
13774
- console.warn("[Sphere.clear] Token storage clear failed:", err);
13960
+ logger.warn("Sphere", "Token storage clear failed:", err);
13775
13961
  }
13776
13962
  } else {
13777
- console.log("[Sphere.clear] No token storage provider to clear");
13963
+ logger.debug("Sphere", "No token storage provider to clear");
13778
13964
  }
13779
- console.log("[Sphere.clear] Clearing KV storage...");
13965
+ logger.debug("Sphere", "Clearing KV storage...");
13780
13966
  if (!storage.isConnected()) {
13781
13967
  try {
13782
13968
  await storage.connect();
@@ -13785,11 +13971,11 @@ var Sphere = class _Sphere {
13785
13971
  }
13786
13972
  if (storage.isConnected()) {
13787
13973
  await storage.clear();
13788
- console.log("[Sphere.clear] KV storage cleared");
13974
+ logger.debug("Sphere", "KV storage cleared");
13789
13975
  } else {
13790
- console.log("[Sphere.clear] KV storage not connected, skipping");
13976
+ logger.debug("Sphere", "KV storage not connected, skipping");
13791
13977
  }
13792
- console.log("[Sphere.clear] Done");
13978
+ logger.debug("Sphere", "Done");
13793
13979
  }
13794
13980
  /**
13795
13981
  * Get current instance
@@ -13881,7 +14067,7 @@ var Sphere = class _Sphere {
13881
14067
  */
13882
14068
  async addTokenStorageProvider(provider) {
13883
14069
  if (this._tokenStorageProviders.has(provider.id)) {
13884
- throw new Error(`Token storage provider '${provider.id}' already exists`);
14070
+ throw new SphereError(`Token storage provider '${provider.id}' already exists`, "INVALID_CONFIG");
13885
14071
  }
13886
14072
  if (this._identity) {
13887
14073
  provider.setIdentity(this._identity);
@@ -14001,7 +14187,7 @@ var Sphere = class _Sphere {
14001
14187
  exportToJSON(options = {}) {
14002
14188
  this.ensureReady();
14003
14189
  if (!this._masterKey && !this._identity) {
14004
- throw new Error("Wallet not initialized");
14190
+ throw new SphereError("Wallet not initialized", "NOT_INITIALIZED");
14005
14191
  }
14006
14192
  const addressCount = options.addressCount || 1;
14007
14193
  const addresses = [];
@@ -14081,7 +14267,7 @@ var Sphere = class _Sphere {
14081
14267
  exportToTxt(options = {}) {
14082
14268
  this.ensureReady();
14083
14269
  if (!this._masterKey && !this._identity) {
14084
- throw new Error("Wallet not initialized");
14270
+ throw new SphereError("Wallet not initialized", "NOT_INITIALIZED");
14085
14271
  }
14086
14272
  const addressCount = options.addressCount || 1;
14087
14273
  const addresses = [];
@@ -14520,7 +14706,7 @@ var Sphere = class _Sphere {
14520
14706
  this.ensureReady();
14521
14707
  const entry = this._trackedAddresses.get(index);
14522
14708
  if (!entry) {
14523
- throw new Error(`Address at index ${index} is not tracked. Switch to it first.`);
14709
+ throw new SphereError(`Address at index ${index} is not tracked. Switch to it first.`, "INVALID_CONFIG");
14524
14710
  }
14525
14711
  if (entry.hidden === hidden) return;
14526
14712
  entry.hidden = hidden;
@@ -14550,14 +14736,14 @@ var Sphere = class _Sphere {
14550
14736
  async switchToAddress(index, options) {
14551
14737
  this.ensureReady();
14552
14738
  if (!this._masterKey) {
14553
- throw new Error("HD derivation requires master key with chain code. Cannot switch addresses.");
14739
+ throw new SphereError("HD derivation requires master key with chain code. Cannot switch addresses.", "INVALID_CONFIG");
14554
14740
  }
14555
14741
  if (index < 0) {
14556
- throw new Error("Address index must be non-negative");
14742
+ throw new SphereError("Address index must be non-negative", "INVALID_CONFIG");
14557
14743
  }
14558
14744
  const newNametag = options?.nametag ? this.cleanNametag(options.nametag) : void 0;
14559
14745
  if (newNametag && !isValidNametag(newNametag)) {
14560
- throw new Error("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.");
14746
+ throw new SphereError("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.", "VALIDATION_ERROR");
14561
14747
  }
14562
14748
  const addressInfo = this.deriveAddress(index, false);
14563
14749
  const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
@@ -14567,7 +14753,7 @@ var Sphere = class _Sphere {
14567
14753
  if (newNametag) {
14568
14754
  const existing = await this._transport.resolveNametag?.(newNametag);
14569
14755
  if (existing) {
14570
- throw new Error(`Nametag @${newNametag} is already taken`);
14756
+ throw new SphereError(`Nametag @${newNametag} is already taken`, "VALIDATION_ERROR");
14571
14757
  }
14572
14758
  let nametags = this._addressNametags.get(addressId);
14573
14759
  if (!nametags) {
@@ -14590,12 +14776,12 @@ var Sphere = class _Sphere {
14590
14776
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
14591
14777
  this._storage.setIdentity(this._identity);
14592
14778
  await this._transport.setIdentity(this._identity);
14593
- console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
14779
+ logger.debug("Sphere", `switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
14594
14780
  for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
14595
- console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
14781
+ logger.debug("Sphere", `switchToAddress(${index}): shutdown provider=${providerId}`);
14596
14782
  await provider.shutdown();
14597
14783
  provider.setIdentity(this._identity);
14598
- console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
14784
+ logger.debug("Sphere", `switchToAddress(${index}): initialize provider=${providerId}`);
14599
14785
  await provider.initialize();
14600
14786
  }
14601
14787
  await this.reinitializeModulesForNewAddress();
@@ -14606,9 +14792,9 @@ var Sphere = class _Sphere {
14606
14792
  nametag: this._identity.nametag,
14607
14793
  addressIndex: index
14608
14794
  });
14609
- console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
14795
+ logger.debug("Sphere", `Switched to address ${index}:`, this._identity.l1Address);
14610
14796
  this.postSwitchSync(index, newNametag).catch((err) => {
14611
- console.warn(`[Sphere] Post-switch sync failed for address ${index}:`, err);
14797
+ logger.warn("Sphere", `Post-switch sync failed for address ${index}:`, err);
14612
14798
  });
14613
14799
  }
14614
14800
  /**
@@ -14622,16 +14808,16 @@ var Sphere = class _Sphere {
14622
14808
  if (newNametag) {
14623
14809
  await this.persistAddressNametags();
14624
14810
  if (!this._payments.hasNametag()) {
14625
- console.log(`[Sphere] Minting nametag token for @${newNametag}...`);
14811
+ logger.debug("Sphere", `Minting nametag token for @${newNametag}...`);
14626
14812
  try {
14627
14813
  const result = await this.mintNametag(newNametag);
14628
14814
  if (result.success) {
14629
- console.log(`[Sphere] Nametag token minted successfully`);
14815
+ logger.debug("Sphere", `Nametag token minted successfully`);
14630
14816
  } else {
14631
- console.warn(`[Sphere] Could not mint nametag token: ${result.error}`);
14817
+ logger.warn("Sphere", `Could not mint nametag token: ${result.error}`);
14632
14818
  }
14633
14819
  } catch (err) {
14634
- console.warn(`[Sphere] Nametag token mint failed:`, err);
14820
+ logger.warn("Sphere", `Nametag token mint failed:`, err);
14635
14821
  }
14636
14822
  }
14637
14823
  this.emitEvent("nametag:registered", {
@@ -14639,16 +14825,16 @@ var Sphere = class _Sphere {
14639
14825
  addressIndex: index
14640
14826
  });
14641
14827
  } else if (this._identity?.nametag && !this._payments.hasNametag()) {
14642
- console.log(`[Sphere] Nametag @${this._identity.nametag} has no token after switch, minting...`);
14828
+ logger.debug("Sphere", `Nametag @${this._identity.nametag} has no token after switch, minting...`);
14643
14829
  try {
14644
14830
  const result = await this.mintNametag(this._identity.nametag);
14645
14831
  if (result.success) {
14646
- console.log(`[Sphere] Nametag token minted successfully after switch`);
14832
+ logger.debug("Sphere", `Nametag token minted successfully after switch`);
14647
14833
  } else {
14648
- console.warn(`[Sphere] Could not mint nametag token after switch: ${result.error}`);
14834
+ logger.warn("Sphere", `Could not mint nametag token after switch: ${result.error}`);
14649
14835
  }
14650
14836
  } catch (err) {
14651
- console.warn(`[Sphere] Nametag token mint failed after switch:`, err);
14837
+ logger.warn("Sphere", `Nametag token mint failed after switch:`, err);
14652
14838
  }
14653
14839
  }
14654
14840
  }
@@ -14687,7 +14873,7 @@ var Sphere = class _Sphere {
14687
14873
  await this._groupChat?.load();
14688
14874
  await this._market?.load();
14689
14875
  this._payments.sync().catch((err) => {
14690
- console.warn("[Sphere] Post-switch sync failed:", err);
14876
+ logger.warn("Sphere", "Post-switch sync failed:", err);
14691
14877
  });
14692
14878
  }
14693
14879
  /**
@@ -14721,7 +14907,7 @@ var Sphere = class _Sphere {
14721
14907
  */
14722
14908
  _deriveAddressInternal(index, isChange = false) {
14723
14909
  if (!this._masterKey) {
14724
- throw new Error("HD derivation requires master key with chain code");
14910
+ throw new SphereError("HD derivation requires master key with chain code", "INVALID_CONFIG");
14725
14911
  }
14726
14912
  if (this._derivationMode === "wif_hmac") {
14727
14913
  return generateAddressFromMasterKey(this._masterKey.privateKey, index);
@@ -14751,7 +14937,7 @@ var Sphere = class _Sphere {
14751
14937
  deriveAddressAtPath(path) {
14752
14938
  this.ensureReady();
14753
14939
  if (!this._masterKey) {
14754
- throw new Error("HD derivation requires master key with chain code");
14940
+ throw new SphereError("HD derivation requires master key with chain code", "INVALID_CONFIG");
14755
14941
  }
14756
14942
  const match = path.match(/\/(\d+)$/);
14757
14943
  const index = match ? parseInt(match[1], 10) : 0;
@@ -14818,13 +15004,14 @@ var Sphere = class _Sphere {
14818
15004
  async scanAddresses(options = {}) {
14819
15005
  this.ensureReady();
14820
15006
  if (!this._masterKey) {
14821
- throw new Error("Address scanning requires HD master key");
15007
+ throw new SphereError("Address scanning requires HD master key", "INVALID_CONFIG");
14822
15008
  }
14823
15009
  const resolveNametag = options.resolveNametag ?? (this._transport.resolveAddressInfo ? async (l1Address) => {
14824
15010
  try {
14825
15011
  const info = await this._transport.resolveAddressInfo(l1Address);
14826
15012
  return info?.nametag ?? null;
14827
- } catch {
15013
+ } catch (err) {
15014
+ logger.debug("Sphere", "Nametag resolution failed during scan", err);
14828
15015
  return null;
14829
15016
  }
14830
15017
  } : void 0);
@@ -14875,10 +15062,10 @@ var Sphere = class _Sphere {
14875
15062
  async discoverAddresses(options = {}) {
14876
15063
  this.ensureReady();
14877
15064
  if (!this._masterKey) {
14878
- throw new Error("Address discovery requires HD master key");
15065
+ throw new SphereError("Address discovery requires HD master key", "INVALID_CONFIG");
14879
15066
  }
14880
15067
  if (!this._transport.discoverAddresses) {
14881
- throw new Error("Transport provider does not support address discovery");
15068
+ throw new SphereError("Transport provider does not support address discovery", "INVALID_CONFIG");
14882
15069
  }
14883
15070
  const includeL1Scan = options.includeL1Scan ?? true;
14884
15071
  const transportResult = await discoverAddressesImpl(
@@ -14934,7 +15121,7 @@ var Sphere = class _Sphere {
14934
15121
  }
14935
15122
  transportResult.addresses.sort((a, b) => a.index - b.index);
14936
15123
  } catch (err) {
14937
- console.warn("[Sphere] L1 scan failed during discovery (non-fatal):", err);
15124
+ logger.warn("Sphere", "L1 scan failed during discovery (non-fatal):", err);
14938
15125
  }
14939
15126
  }
14940
15127
  if (options.autoTrack && transportResult.addresses.length > 0) {
@@ -15032,7 +15219,7 @@ var Sphere = class _Sphere {
15032
15219
  */
15033
15220
  async disableProvider(providerId) {
15034
15221
  if (providerId === this._storage.id) {
15035
- throw new Error("Cannot disable the main storage provider");
15222
+ throw new SphereError("Cannot disable the main storage provider", "INVALID_CONFIG");
15036
15223
  }
15037
15224
  const provider = this.findProviderById(providerId);
15038
15225
  if (!provider) return false;
@@ -15235,10 +15422,10 @@ var Sphere = class _Sphere {
15235
15422
  this.ensureReady();
15236
15423
  const cleanNametag = this.cleanNametag(nametag);
15237
15424
  if (!isValidNametag(cleanNametag)) {
15238
- throw new Error("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.");
15425
+ throw new SphereError("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.", "VALIDATION_ERROR");
15239
15426
  }
15240
15427
  if (this._identity?.nametag) {
15241
- throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
15428
+ throw new SphereError(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`, "ALREADY_INITIALIZED");
15242
15429
  }
15243
15430
  if (this._transport.publishIdentityBinding) {
15244
15431
  const success = await this._transport.publishIdentityBinding(
@@ -15248,7 +15435,7 @@ var Sphere = class _Sphere {
15248
15435
  cleanNametag
15249
15436
  );
15250
15437
  if (!success) {
15251
- throw new Error("Failed to register nametag. It may already be taken.");
15438
+ throw new SphereError("Failed to register nametag. It may already be taken.", "VALIDATION_ERROR");
15252
15439
  }
15253
15440
  }
15254
15441
  this._identity.nametag = cleanNametag;
@@ -15264,19 +15451,19 @@ var Sphere = class _Sphere {
15264
15451
  }
15265
15452
  await this.persistAddressNametags();
15266
15453
  if (!this._payments.hasNametag()) {
15267
- console.log(`[Sphere] Minting nametag token for @${cleanNametag}...`);
15454
+ logger.debug("Sphere", `Minting nametag token for @${cleanNametag}...`);
15268
15455
  const result = await this.mintNametag(cleanNametag);
15269
15456
  if (!result.success) {
15270
- console.warn(`[Sphere] Failed to mint nametag token: ${result.error}`);
15457
+ logger.warn("Sphere", `Failed to mint nametag token: ${result.error}`);
15271
15458
  } else {
15272
- console.log(`[Sphere] Nametag token minted successfully`);
15459
+ logger.debug("Sphere", `Nametag token minted successfully`);
15273
15460
  }
15274
15461
  }
15275
15462
  this.emitEvent("nametag:registered", {
15276
15463
  nametag: cleanNametag,
15277
15464
  addressIndex: this._currentAddressIndex
15278
15465
  });
15279
- console.log(`[Sphere] Nametag registered for address ${this._currentAddressIndex}:`, cleanNametag);
15466
+ logger.debug("Sphere", `Nametag registered for address ${this._currentAddressIndex}:`, cleanNametag);
15280
15467
  }
15281
15468
  /**
15282
15469
  * Persist tracked addresses to storage (only minimal fields via StorageProvider)
@@ -15516,13 +15703,13 @@ var Sphere = class _Sphere {
15516
15703
  this._identity.directAddress || "",
15517
15704
  recoveredNametag
15518
15705
  );
15519
- console.log(`[Sphere] Migrated legacy binding with nametag @${recoveredNametag}`);
15706
+ logger.debug("Sphere", `Migrated legacy binding with nametag @${recoveredNametag}`);
15520
15707
  return;
15521
15708
  }
15522
15709
  }
15523
15710
  const needsUpdate = !existing.directAddress || !existing.l1Address || !existing.chainPubkey || this._identity?.nametag && !existing.nametag;
15524
15711
  if (needsUpdate) {
15525
- console.log("[Sphere] Existing binding incomplete, re-publishing with full data");
15712
+ logger.debug("Sphere", "Existing binding incomplete, re-publishing with full data");
15526
15713
  await this._transport.publishIdentityBinding(
15527
15714
  this._identity.chainPubkey,
15528
15715
  this._identity.l1Address,
@@ -15531,11 +15718,11 @@ var Sphere = class _Sphere {
15531
15718
  );
15532
15719
  return;
15533
15720
  }
15534
- console.log("[Sphere] Existing binding found, skipping re-publish");
15721
+ logger.debug("Sphere", "Existing binding found, skipping re-publish");
15535
15722
  return;
15536
15723
  }
15537
15724
  } catch (e) {
15538
- console.warn("[Sphere] resolve() failed, skipping publish to avoid overwrite", e);
15725
+ logger.warn("Sphere", "resolve() failed, skipping publish to avoid overwrite", e);
15539
15726
  return;
15540
15727
  }
15541
15728
  }
@@ -15547,12 +15734,12 @@ var Sphere = class _Sphere {
15547
15734
  nametag || void 0
15548
15735
  );
15549
15736
  if (success) {
15550
- console.log(`[Sphere] Identity binding published${nametag ? ` with nametag @${nametag}` : ""}`);
15737
+ logger.debug("Sphere", `Identity binding published${nametag ? ` with nametag @${nametag}` : ""}`);
15551
15738
  } else if (nametag) {
15552
- console.warn(`[Sphere] Nametag @${nametag} is taken by another pubkey`);
15739
+ logger.warn("Sphere", `Nametag @${nametag} is taken by another pubkey`);
15553
15740
  }
15554
15741
  } catch (error) {
15555
- console.warn(`[Sphere] Identity binding sync failed:`, error);
15742
+ logger.warn("Sphere", `Identity binding sync failed:`, error);
15556
15743
  }
15557
15744
  }
15558
15745
  /**
@@ -15705,7 +15892,7 @@ var Sphere = class _Sphere {
15705
15892
  if (encryptedMnemonic) {
15706
15893
  const mnemonic = this.decrypt(encryptedMnemonic);
15707
15894
  if (!mnemonic) {
15708
- throw new Error("Failed to decrypt mnemonic");
15895
+ throw new SphereError("Failed to decrypt mnemonic", "STORAGE_ERROR");
15709
15896
  }
15710
15897
  this._mnemonic = mnemonic;
15711
15898
  this._source = "mnemonic";
@@ -15713,7 +15900,7 @@ var Sphere = class _Sphere {
15713
15900
  } else if (encryptedMasterKey) {
15714
15901
  const masterKey = this.decrypt(encryptedMasterKey);
15715
15902
  if (!masterKey) {
15716
- throw new Error("Failed to decrypt master key");
15903
+ throw new SphereError("Failed to decrypt master key", "STORAGE_ERROR");
15717
15904
  }
15718
15905
  this._mnemonic = null;
15719
15906
  if (this._source === "unknown") {
@@ -15725,7 +15912,7 @@ var Sphere = class _Sphere {
15725
15912
  derivationPath ?? void 0
15726
15913
  );
15727
15914
  } else {
15728
- throw new Error("No wallet data found in storage");
15915
+ throw new SphereError("No wallet data found in storage", "NOT_INITIALIZED");
15729
15916
  }
15730
15917
  if (this._identity) {
15731
15918
  this._storage.setIdentity(this._identity);
@@ -15747,7 +15934,7 @@ var Sphere = class _Sphere {
15747
15934
  nametag
15748
15935
  };
15749
15936
  this._storage.setIdentity(this._identity);
15750
- console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
15937
+ logger.debug("Sphere", `Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
15751
15938
  } else if (this._identity && nametag) {
15752
15939
  this._identity.nametag = nametag;
15753
15940
  }
@@ -15938,7 +16125,7 @@ var Sphere = class _Sphere {
15938
16125
  // ===========================================================================
15939
16126
  ensureReady() {
15940
16127
  if (!this._initialized) {
15941
- throw new Error("Sphere not initialized");
16128
+ throw new SphereError("Sphere not initialized", "NOT_INITIALIZED");
15942
16129
  }
15943
16130
  }
15944
16131
  emitEvent(type, data) {
@@ -15948,7 +16135,7 @@ var Sphere = class _Sphere {
15948
16135
  try {
15949
16136
  handler(data);
15950
16137
  } catch (error) {
15951
- console.error("[Sphere] Event handler error:", error);
16138
+ logger.error("Sphere", "Event handler error:", error);
15952
16139
  }
15953
16140
  }
15954
16141
  }
@@ -15985,6 +16172,7 @@ var getSphere = Sphere.getInstance.bind(Sphere);
15985
16172
  var sphereExists = Sphere.exists.bind(Sphere);
15986
16173
 
15987
16174
  // core/currency.ts
16175
+ init_logger();
15988
16176
  var DEFAULT_TOKEN_DECIMALS = 18;
15989
16177
  function toSmallestUnit(amount, decimals = DEFAULT_TOKEN_DECIMALS) {
15990
16178
  if (!amount) return 0n;
@@ -15993,7 +16181,8 @@ function toSmallestUnit(amount, decimals = DEFAULT_TOKEN_DECIMALS) {
15993
16181
  const [integer, fraction = ""] = str.split(".");
15994
16182
  const paddedFraction = fraction.padEnd(decimals, "0").slice(0, decimals);
15995
16183
  return BigInt(integer + paddedFraction);
15996
- } catch {
16184
+ } catch (err) {
16185
+ logger.debug("Currency", "toSmallestUnit conversion failed", err);
15997
16186
  return 0n;
15998
16187
  }
15999
16188
  }
@@ -16022,6 +16211,8 @@ var CurrencyUtils = {
16022
16211
 
16023
16212
  // core/index.ts
16024
16213
  init_bech32();
16214
+ init_logger();
16215
+ init_errors();
16025
16216
 
16026
16217
  // core/network-health.ts
16027
16218
  init_constants();
@@ -16215,6 +16406,7 @@ export {
16215
16406
  DEFAULT_DERIVATION_PATH2 as DEFAULT_DERIVATION_PATH,
16216
16407
  DEFAULT_TOKEN_DECIMALS,
16217
16408
  Sphere,
16409
+ SphereError,
16218
16410
  base58Decode,
16219
16411
  base58Encode,
16220
16412
  bytesToHex2 as bytesToHex,
@@ -16261,10 +16453,12 @@ export {
16261
16453
  importSphere,
16262
16454
  initSphere,
16263
16455
  isEncryptedData,
16456
+ isSphereError,
16264
16457
  isValidBech32,
16265
16458
  isValidNametag,
16266
16459
  isValidPrivateKey,
16267
16460
  loadSphere,
16461
+ logger,
16268
16462
  mnemonicToEntropy2 as mnemonicToEntropy,
16269
16463
  mnemonicToSeed2 as mnemonicToSeed,
16270
16464
  mnemonicToSeedSync2 as mnemonicToSeedSync,