@unicitylabs/sphere-sdk 0.5.4 → 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 (39) hide show
  1. package/dist/connect/index.cjs +128 -22
  2. package/dist/connect/index.cjs.map +1 -1
  3. package/dist/connect/index.js +128 -22
  4. package/dist/connect/index.js.map +1 -1
  5. package/dist/core/index.cjs +670 -473
  6. package/dist/core/index.cjs.map +1 -1
  7. package/dist/core/index.d.cts +123 -2
  8. package/dist/core/index.d.ts +123 -2
  9. package/dist/core/index.js +667 -473
  10. package/dist/core/index.js.map +1 -1
  11. package/dist/impl/browser/index.cjs +306 -193
  12. package/dist/impl/browser/index.cjs.map +1 -1
  13. package/dist/impl/browser/index.js +306 -193
  14. package/dist/impl/browser/index.js.map +1 -1
  15. package/dist/impl/browser/ipfs.cjs +134 -19
  16. package/dist/impl/browser/ipfs.cjs.map +1 -1
  17. package/dist/impl/browser/ipfs.js +134 -19
  18. package/dist/impl/browser/ipfs.js.map +1 -1
  19. package/dist/impl/nodejs/connect/index.cjs +101 -6
  20. package/dist/impl/nodejs/connect/index.cjs.map +1 -1
  21. package/dist/impl/nodejs/connect/index.js +101 -6
  22. package/dist/impl/nodejs/connect/index.js.map +1 -1
  23. package/dist/impl/nodejs/index.cjs +267 -152
  24. package/dist/impl/nodejs/index.cjs.map +1 -1
  25. package/dist/impl/nodejs/index.d.cts +2 -1
  26. package/dist/impl/nodejs/index.d.ts +2 -1
  27. package/dist/impl/nodejs/index.js +267 -152
  28. package/dist/impl/nodejs/index.js.map +1 -1
  29. package/dist/index.cjs +682 -493
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +124 -8
  32. package/dist/index.d.ts +124 -8
  33. package/dist/index.js +680 -493
  34. package/dist/index.js.map +1 -1
  35. package/dist/l1/index.cjs +139 -32
  36. package/dist/l1/index.cjs.map +1 -1
  37. package/dist/l1/index.js +139 -32
  38. package/dist/l1/index.js.map +1 -1
  39. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -30,6 +30,125 @@ var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__
30
30
  ));
31
31
  var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
32
32
 
33
+ // core/logger.ts
34
+ function getState() {
35
+ const g = globalThis;
36
+ if (!g[LOGGER_KEY]) {
37
+ g[LOGGER_KEY] = { debug: false, tags: {}, handler: null };
38
+ }
39
+ return g[LOGGER_KEY];
40
+ }
41
+ function isEnabled(tag) {
42
+ const state = getState();
43
+ if (tag in state.tags) return state.tags[tag];
44
+ return state.debug;
45
+ }
46
+ var LOGGER_KEY, logger;
47
+ var init_logger = __esm({
48
+ "core/logger.ts"() {
49
+ "use strict";
50
+ LOGGER_KEY = "__sphere_sdk_logger__";
51
+ logger = {
52
+ /**
53
+ * Configure the logger. Can be called multiple times (last write wins).
54
+ * Typically called by createBrowserProviders(), createNodeProviders(), or Sphere.init().
55
+ */
56
+ configure(config) {
57
+ const state = getState();
58
+ if (config.debug !== void 0) state.debug = config.debug;
59
+ if (config.handler !== void 0) state.handler = config.handler;
60
+ },
61
+ /**
62
+ * Enable/disable debug logging for a specific tag.
63
+ * Per-tag setting overrides the global debug flag.
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * logger.setTagDebug('Nostr', true); // enable only Nostr logs
68
+ * logger.setTagDebug('Nostr', false); // disable Nostr logs even if global debug=true
69
+ * ```
70
+ */
71
+ setTagDebug(tag, enabled) {
72
+ getState().tags[tag] = enabled;
73
+ },
74
+ /**
75
+ * Clear per-tag override, falling back to global debug flag.
76
+ */
77
+ clearTagDebug(tag) {
78
+ delete getState().tags[tag];
79
+ },
80
+ /** Returns true if debug mode is enabled for the given tag (or globally). */
81
+ isDebugEnabled(tag) {
82
+ if (tag) return isEnabled(tag);
83
+ return getState().debug;
84
+ },
85
+ /**
86
+ * Debug-level log. Only shown when debug is enabled (globally or for this tag).
87
+ * Use for detailed operational information.
88
+ */
89
+ debug(tag, message, ...args) {
90
+ if (!isEnabled(tag)) return;
91
+ const state = getState();
92
+ if (state.handler) {
93
+ state.handler("debug", tag, message, ...args);
94
+ } else {
95
+ console.log(`[${tag}]`, message, ...args);
96
+ }
97
+ },
98
+ /**
99
+ * Warning-level log. ALWAYS shown regardless of debug flag.
100
+ * Use for important but non-critical issues (timeouts, retries, degraded state).
101
+ */
102
+ warn(tag, message, ...args) {
103
+ const state = getState();
104
+ if (state.handler) {
105
+ state.handler("warn", tag, message, ...args);
106
+ } else {
107
+ console.warn(`[${tag}]`, message, ...args);
108
+ }
109
+ },
110
+ /**
111
+ * Error-level log. ALWAYS shown regardless of debug flag.
112
+ * Use for critical failures that should never be silenced.
113
+ */
114
+ error(tag, message, ...args) {
115
+ const state = getState();
116
+ if (state.handler) {
117
+ state.handler("error", tag, message, ...args);
118
+ } else {
119
+ console.error(`[${tag}]`, message, ...args);
120
+ }
121
+ },
122
+ /** Reset all logger state (debug flag, tags, handler). Primarily for tests. */
123
+ reset() {
124
+ const g = globalThis;
125
+ delete g[LOGGER_KEY];
126
+ }
127
+ };
128
+ }
129
+ });
130
+
131
+ // core/errors.ts
132
+ function isSphereError(err) {
133
+ return err instanceof SphereError;
134
+ }
135
+ var SphereError;
136
+ var init_errors = __esm({
137
+ "core/errors.ts"() {
138
+ "use strict";
139
+ SphereError = class extends Error {
140
+ code;
141
+ cause;
142
+ constructor(message, code, cause) {
143
+ super(message);
144
+ this.name = "SphereError";
145
+ this.code = code;
146
+ this.cause = cause;
147
+ }
148
+ };
149
+ }
150
+ });
151
+
33
152
  // constants.ts
34
153
  function getAddressStorageKey(addressId, key) {
35
154
  return `${addressId}_${key}`;
@@ -310,11 +429,11 @@ function bech32Checksum(hrp, data) {
310
429
  }
311
430
  function encodeBech32(hrp, version, program) {
312
431
  if (version < 0 || version > 16) {
313
- throw new Error("Invalid witness version");
432
+ throw new SphereError("Invalid witness version", "VALIDATION_ERROR");
314
433
  }
315
434
  const converted = convertBits(Array.from(program), 8, 5, true);
316
435
  if (!converted) {
317
- throw new Error("Failed to convert bits");
436
+ throw new SphereError("Failed to convert bits", "VALIDATION_ERROR");
318
437
  }
319
438
  const data = [version].concat(converted);
320
439
  const checksum = bech32Checksum(hrp, data);
@@ -367,6 +486,7 @@ var CHARSET, GENERATOR, createBech32;
367
486
  var init_bech32 = __esm({
368
487
  "core/bech32.ts"() {
369
488
  "use strict";
489
+ init_errors();
370
490
  CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
371
491
  GENERATOR = [996825010, 642813549, 513874426, 1027748829, 705979059];
372
492
  createBech32 = encodeBech32;
@@ -379,7 +499,7 @@ function bytesToHex(buf) {
379
499
  }
380
500
  function addressToScriptHash(address) {
381
501
  const decoded = decodeBech32(address);
382
- if (!decoded) throw new Error("Invalid bech32 address: " + address);
502
+ if (!decoded) throw new SphereError("Invalid bech32 address: " + address, "VALIDATION_ERROR");
383
503
  const scriptHex = "0014" + bytesToHex(decoded.data);
384
504
  const sha = import_crypto_js.default.SHA256(import_crypto_js.default.enc.Hex.parse(scriptHex)).toString();
385
505
  return sha.match(/../g).reverse().join("");
@@ -389,6 +509,7 @@ var init_addressToScriptHash = __esm({
389
509
  "l1/addressToScriptHash.ts"() {
390
510
  "use strict";
391
511
  init_bech32();
512
+ init_errors();
392
513
  import_crypto_js = __toESM(require("crypto-js"), 1);
393
514
  }
394
515
  });
@@ -449,7 +570,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
449
570
  try {
450
571
  ws = new WebSocket(endpoint);
451
572
  } catch (err) {
452
- console.error("[L1] WebSocket constructor threw exception:", err);
573
+ logger.error("L1", "WebSocket constructor threw exception:", err);
453
574
  isConnecting = false;
454
575
  reject(err);
455
576
  return;
@@ -485,7 +606,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
485
606
  return;
486
607
  }
487
608
  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
488
- console.error("[L1] Max reconnect attempts reached. Giving up.");
609
+ logger.error("L1", "Max reconnect attempts reached. Giving up.");
489
610
  isConnecting = false;
490
611
  const error = new Error("Max reconnect attempts reached");
491
612
  connectionCallbacks.forEach((cb) => {
@@ -501,8 +622,9 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
501
622
  }
502
623
  const delay = Math.min(BASE_DELAY * Math.pow(2, reconnectAttempts), MAX_DELAY);
503
624
  reconnectAttempts++;
504
- console.warn(
505
- `[L1] WebSocket closed unexpectedly. Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`
625
+ logger.warn(
626
+ "L1",
627
+ `WebSocket closed unexpectedly. Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`
506
628
  );
507
629
  setTimeout(() => {
508
630
  connect(endpoint).then(() => {
@@ -519,7 +641,7 @@ function connect(endpoint = DEFAULT_ENDPOINT) {
519
641
  }, delay);
520
642
  };
521
643
  ws.onerror = (err) => {
522
- console.error("[L1] WebSocket error:", err);
644
+ logger.error("L1", "WebSocket error:", err);
523
645
  };
524
646
  ws.onmessage = (msg) => handleMessage(msg);
525
647
  });
@@ -577,7 +699,7 @@ async function getUtxo(address) {
577
699
  const scripthash = addressToScriptHash(address);
578
700
  const result = await rpc("blockchain.scripthash.listunspent", [scripthash]);
579
701
  if (!Array.isArray(result)) {
580
- console.warn("listunspent returned non-array:", result);
702
+ logger.warn("L1", "listunspent returned non-array:", result);
581
703
  return [];
582
704
  }
583
705
  return result.map((u) => ({
@@ -629,7 +751,7 @@ async function getTransactionHistory(address) {
629
751
  const scriptHash = addressToScriptHash(address);
630
752
  const result = await rpc("blockchain.scripthash.get_history", [scriptHash]);
631
753
  if (!Array.isArray(result)) {
632
- console.warn("get_history returned non-array:", result);
754
+ logger.warn("L1", "get_history returned non-array:", result);
633
755
  return [];
634
756
  }
635
757
  return result;
@@ -645,7 +767,7 @@ async function getCurrentBlockHeight() {
645
767
  const header = await rpc("blockchain.headers.subscribe", []);
646
768
  return header?.height || 0;
647
769
  } catch (err) {
648
- console.error("Error getting current block height:", err);
770
+ logger.error("L1", "Error getting current block height:", err);
649
771
  return 0;
650
772
  }
651
773
  }
@@ -674,6 +796,7 @@ var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose
674
796
  var init_network = __esm({
675
797
  "l1/network.ts"() {
676
798
  "use strict";
799
+ init_logger();
677
800
  init_addressToScriptHash();
678
801
  init_constants();
679
802
  DEFAULT_ENDPOINT = DEFAULT_ELECTRUM_URL;
@@ -804,6 +927,7 @@ __export(index_exports, {
804
927
  isPaymentSessionTimedOut: () => isPaymentSessionTimedOut,
805
928
  isPhoneNumber: () => import_nostr_js_sdk4.isPhoneNumber,
806
929
  isSQLiteDatabase: () => isSQLiteDatabase,
930
+ isSphereError: () => isSphereError,
807
931
  isTextWalletEncrypted: () => isTextWalletEncrypted,
808
932
  isTokenKey: () => isTokenKey,
809
933
  isValidBech32: () => isValidBech32,
@@ -814,6 +938,7 @@ __export(index_exports, {
814
938
  isWalletTextFormat: () => isWalletTextFormat,
815
939
  keyFromTokenId: () => keyFromTokenId,
816
940
  loadSphere: () => loadSphere,
941
+ logger: () => logger,
817
942
  mnemonicToSeedSync: () => mnemonicToSeedSync2,
818
943
  normalizeNametag: () => import_nostr_js_sdk4.normalizeNametag,
819
944
  normalizeSdkTokenToStorage: () => normalizeSdkTokenToStorage,
@@ -841,7 +966,12 @@ __export(index_exports, {
841
966
  });
842
967
  module.exports = __toCommonJS(index_exports);
843
968
 
969
+ // core/Sphere.ts
970
+ init_logger();
971
+ init_errors();
972
+
844
973
  // modules/payments/L1PaymentsModule.ts
974
+ init_errors();
845
975
  init_constants();
846
976
 
847
977
  // l1/index.ts
@@ -937,6 +1067,7 @@ var bip39 = __toESM(require("bip39"), 1);
937
1067
  var import_crypto_js2 = __toESM(require("crypto-js"), 1);
938
1068
  var import_elliptic = __toESM(require("elliptic"), 1);
939
1069
  init_bech32();
1070
+ init_errors();
940
1071
  var ec = new import_elliptic.default.ec("secp256k1");
941
1072
  var CURVE_ORDER = BigInt(
942
1073
  "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"
@@ -960,7 +1091,7 @@ function generateMasterKey(seedHex) {
960
1091
  const IR = I.substring(64);
961
1092
  const masterKeyBigInt = BigInt("0x" + IL);
962
1093
  if (masterKeyBigInt === 0n || masterKeyBigInt >= CURVE_ORDER) {
963
- throw new Error("Invalid master key generated");
1094
+ throw new SphereError("Invalid master key generated", "VALIDATION_ERROR");
964
1095
  }
965
1096
  return {
966
1097
  privateKey: IL,
@@ -988,11 +1119,11 @@ function deriveChildKey(parentPrivKey, parentChainCode, index) {
988
1119
  const ilBigInt = BigInt("0x" + IL);
989
1120
  const parentKeyBigInt = BigInt("0x" + parentPrivKey);
990
1121
  if (ilBigInt >= CURVE_ORDER) {
991
- throw new Error("Invalid key: IL >= curve order");
1122
+ throw new SphereError("Invalid key: IL >= curve order", "VALIDATION_ERROR");
992
1123
  }
993
1124
  const childKeyBigInt = (ilBigInt + parentKeyBigInt) % CURVE_ORDER;
994
1125
  if (childKeyBigInt === 0n) {
995
- throw new Error("Invalid key: child key is zero");
1126
+ throw new SphereError("Invalid key: child key is zero", "VALIDATION_ERROR");
996
1127
  }
997
1128
  const childPrivKey = childKeyBigInt.toString(16).padStart(64, "0");
998
1129
  return {
@@ -1078,7 +1209,7 @@ function randomBytes(length) {
1078
1209
  }
1079
1210
  function identityFromMnemonicSync(mnemonic, passphrase = "") {
1080
1211
  if (!validateMnemonic2(mnemonic)) {
1081
- throw new Error("Invalid mnemonic phrase");
1212
+ throw new SphereError("Invalid mnemonic phrase", "INVALID_IDENTITY");
1082
1213
  }
1083
1214
  const seedHex = mnemonicToSeedSync2(mnemonic, passphrase);
1084
1215
  return generateMasterKey(seedHex);
@@ -1211,12 +1342,19 @@ function generateHDAddress(masterPriv, chainCode, index) {
1211
1342
  init_network();
1212
1343
 
1213
1344
  // l1/tx.ts
1345
+ init_logger();
1346
+ init_errors();
1214
1347
  init_network();
1215
1348
  init_bech32();
1216
1349
  var import_crypto_js5 = __toESM(require("crypto-js"), 1);
1217
1350
  var import_elliptic2 = __toESM(require("elliptic"), 1);
1218
1351
 
1352
+ // l1/vestingState.ts
1353
+ init_logger();
1354
+ init_errors();
1355
+
1219
1356
  // l1/vesting.ts
1357
+ init_logger();
1220
1358
  init_network();
1221
1359
  var VESTING_THRESHOLD = 28e4;
1222
1360
  var currentBlockHeight = null;
@@ -1459,7 +1597,7 @@ var VestingClassifier = class {
1459
1597
  await new Promise((resolve) => {
1460
1598
  const req = indexedDB.deleteDatabase(this.dbName);
1461
1599
  const timer = setTimeout(() => {
1462
- console.warn(`[VestingClassifier] destroy: deleteDatabase timed out for ${this.dbName}`);
1600
+ logger.warn("L1", ` destroy: deleteDatabase timed out for ${this.dbName}`);
1463
1601
  resolve();
1464
1602
  }, 3e3);
1465
1603
  req.onsuccess = () => {
@@ -1471,7 +1609,7 @@ var VestingClassifier = class {
1471
1609
  resolve();
1472
1610
  };
1473
1611
  req.onblocked = () => {
1474
- console.warn(`[VestingClassifier] destroy: deleteDatabase blocked for ${this.dbName}, waiting...`);
1612
+ logger.warn("L1", ` destroy: deleteDatabase blocked for ${this.dbName}, waiting...`);
1475
1613
  };
1476
1614
  });
1477
1615
  }
@@ -1489,7 +1627,7 @@ var VestingStateManager = class {
1489
1627
  */
1490
1628
  setMode(mode) {
1491
1629
  if (!["all", "vested", "unvested"].includes(mode)) {
1492
- throw new Error(`Invalid vesting mode: ${mode}`);
1630
+ throw new SphereError(`Invalid vesting mode: ${mode}`, "VALIDATION_ERROR");
1493
1631
  }
1494
1632
  this.currentMode = mode;
1495
1633
  }
@@ -1526,10 +1664,10 @@ var VestingStateManager = class {
1526
1664
  }
1527
1665
  });
1528
1666
  if (result.errors.length > 0) {
1529
- console.warn(`Vesting classification errors: ${result.errors.length}`);
1667
+ logger.warn("L1", `Vesting classification errors: ${result.errors.length}`);
1530
1668
  result.errors.slice(0, 5).forEach((err) => {
1531
1669
  const txHash = err.utxo.tx_hash || err.utxo.txid;
1532
- console.warn(` ${txHash}: ${err.error}`);
1670
+ logger.warn("L1", ` ${txHash}: ${err.error}`);
1533
1671
  });
1534
1672
  }
1535
1673
  } finally {
@@ -1606,6 +1744,7 @@ var VestingStateManager = class {
1606
1744
  var vestingState = new VestingStateManager();
1607
1745
 
1608
1746
  // l1/addressHelpers.ts
1747
+ init_errors();
1609
1748
  var WalletAddressHelper = class {
1610
1749
  /**
1611
1750
  * Find address by BIP32 derivation path
@@ -1651,16 +1790,17 @@ var WalletAddressHelper = class {
1651
1790
  */
1652
1791
  static add(wallet, newAddress) {
1653
1792
  if (!newAddress.path) {
1654
- throw new Error("Cannot add address without a path");
1793
+ throw new SphereError("Cannot add address without a path", "INVALID_CONFIG");
1655
1794
  }
1656
1795
  const existing = this.findByPath(wallet, newAddress.path);
1657
1796
  if (existing) {
1658
1797
  if (existing.address !== newAddress.address) {
1659
- throw new Error(
1798
+ throw new SphereError(
1660
1799
  `CRITICAL: Attempted to overwrite address for path ${newAddress.path}
1661
1800
  Existing: ${existing.address}
1662
1801
  New: ${newAddress.address}
1663
- This indicates master key corruption or derivation logic error.`
1802
+ This indicates master key corruption or derivation logic error.`,
1803
+ "INVALID_CONFIG"
1664
1804
  );
1665
1805
  }
1666
1806
  return wallet;
@@ -1719,9 +1859,10 @@ This indicates master key corruption or derivation logic error.`
1719
1859
  const uniquePaths = new Set(paths);
1720
1860
  if (paths.length !== uniquePaths.size) {
1721
1861
  const duplicates = paths.filter((p, i) => paths.indexOf(p) !== i);
1722
- throw new Error(
1862
+ throw new SphereError(
1723
1863
  `CRITICAL: Wallet has duplicate paths: ${duplicates.join(", ")}
1724
- This indicates data corruption. Please restore from backup.`
1864
+ This indicates data corruption. Please restore from backup.`,
1865
+ "INVALID_CONFIG"
1725
1866
  );
1726
1867
  }
1727
1868
  }
@@ -1753,11 +1894,11 @@ var DUST = 546;
1753
1894
  var SAT = 1e8;
1754
1895
  function createScriptPubKey(address) {
1755
1896
  if (!address || typeof address !== "string") {
1756
- throw new Error("Invalid address: must be a string");
1897
+ throw new SphereError("Invalid address: must be a string", "VALIDATION_ERROR");
1757
1898
  }
1758
1899
  const decoded = decodeBech32(address);
1759
1900
  if (!decoded) {
1760
- throw new Error("Invalid bech32 address: " + address);
1901
+ throw new SphereError("Invalid bech32 address: " + address, "VALIDATION_ERROR");
1761
1902
  }
1762
1903
  const dataHex = Array.from(decoded.data).map((byte) => byte.toString(16).padStart(2, "0")).join("");
1763
1904
  return "0014" + dataHex;
@@ -1881,7 +2022,7 @@ function createAndSignTransaction(wallet, txPlan) {
1881
2022
  privateKeyHex = wallet.masterPrivateKey;
1882
2023
  }
1883
2024
  if (!privateKeyHex) {
1884
- throw new Error("No private key available for address: " + fromAddress);
2025
+ throw new SphereError("No private key available for address: " + fromAddress, "INVALID_CONFIG");
1885
2026
  }
1886
2027
  const keyPair = ec2.keyFromPrivate(privateKeyHex, "hex");
1887
2028
  const publicKey = keyPair.getPublic(true, "hex");
@@ -1980,7 +2121,7 @@ function collectUtxosForAmount(utxoList, amountSats, recipientAddress, senderAdd
1980
2121
  }
1981
2122
  async function createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress) {
1982
2123
  if (!decodeBech32(toAddress)) {
1983
- throw new Error("Invalid recipient address");
2124
+ throw new SphereError("Invalid recipient address", "INVALID_RECIPIENT");
1984
2125
  }
1985
2126
  const defaultAddr = WalletAddressHelper.getDefault(wallet);
1986
2127
  const senderAddress = fromAddress || defaultAddr.address;
@@ -1989,21 +2130,21 @@ async function createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress
1989
2130
  const currentMode = vestingState.getMode();
1990
2131
  if (vestingState.hasClassifiedData(senderAddress)) {
1991
2132
  utxos = vestingState.getFilteredUtxos(senderAddress);
1992
- console.log(`Using ${utxos.length} ${currentMode} UTXOs`);
2133
+ logger.debug("L1", `Using ${utxos.length} ${currentMode} UTXOs`);
1993
2134
  } else {
1994
2135
  utxos = await getUtxo(senderAddress);
1995
- console.log(`Using ${utxos.length} UTXOs (vesting not classified yet)`);
2136
+ logger.debug("L1", `Using ${utxos.length} UTXOs (vesting not classified yet)`);
1996
2137
  }
1997
2138
  if (!Array.isArray(utxos) || utxos.length === 0) {
1998
2139
  const modeText = currentMode !== "all" ? ` (${currentMode} coins)` : "";
1999
- throw new Error(`No UTXOs available${modeText} for address: ` + senderAddress);
2140
+ throw new SphereError(`No UTXOs available${modeText} for address: ` + senderAddress, "INSUFFICIENT_BALANCE");
2000
2141
  }
2001
2142
  return collectUtxosForAmount(utxos, amountSats, toAddress, senderAddress);
2002
2143
  }
2003
2144
  async function sendAlpha(wallet, toAddress, amountAlpha, fromAddress) {
2004
2145
  const plan = await createTransactionPlan(wallet, toAddress, amountAlpha, fromAddress);
2005
2146
  if (!plan.success) {
2006
- throw new Error(plan.error || "Transaction planning failed");
2147
+ throw new SphereError(plan.error || "Transaction planning failed", "TRANSFER_FAILED");
2007
2148
  }
2008
2149
  const results = [];
2009
2150
  for (const tx of plan.transactions) {
@@ -2070,7 +2211,7 @@ var L1PaymentsModule = class {
2070
2211
  */
2071
2212
  async ensureConnected() {
2072
2213
  if (this._disabled) {
2073
- throw new Error("L1 provider is disabled");
2214
+ throw new SphereError("L1 provider is disabled", "NOT_INITIALIZED");
2074
2215
  }
2075
2216
  if (!isWebSocketConnected() && this._config.electrumUrl) {
2076
2217
  await connect(this._config.electrumUrl);
@@ -2125,8 +2266,9 @@ var L1PaymentsModule = class {
2125
2266
  const l1Address = await this.resolveNametagToL1Address(recipient);
2126
2267
  return l1Address;
2127
2268
  } catch {
2128
- throw new Error(
2129
- `Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
2269
+ throw new SphereError(
2270
+ `Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`,
2271
+ "INVALID_RECIPIENT"
2130
2272
  );
2131
2273
  }
2132
2274
  }
@@ -2135,15 +2277,16 @@ var L1PaymentsModule = class {
2135
2277
  */
2136
2278
  async resolveNametagToL1Address(nametag) {
2137
2279
  if (!this._transport?.resolve) {
2138
- throw new Error("Transport provider does not support resolution");
2280
+ throw new SphereError("Transport provider does not support resolution", "TRANSPORT_ERROR");
2139
2281
  }
2140
2282
  const info = await this._transport.resolve(nametag);
2141
2283
  if (!info) {
2142
- throw new Error(`Nametag not found: ${nametag}`);
2284
+ throw new SphereError(`Nametag not found: ${nametag}`, "INVALID_RECIPIENT");
2143
2285
  }
2144
2286
  if (!info.l1Address) {
2145
- throw new Error(
2146
- `Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
2287
+ throw new SphereError(
2288
+ `Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`,
2289
+ "INVALID_RECIPIENT"
2147
2290
  );
2148
2291
  }
2149
2292
  return info.l1Address;
@@ -2413,7 +2556,7 @@ var L1PaymentsModule = class {
2413
2556
  }
2414
2557
  ensureInitialized() {
2415
2558
  if (!this._initialized) {
2416
- throw new Error("L1PaymentsModule not initialized");
2559
+ throw new SphereError("L1PaymentsModule not initialized", "NOT_INITIALIZED");
2417
2560
  }
2418
2561
  }
2419
2562
  _getWatchedAddresses() {
@@ -2438,6 +2581,7 @@ function createL1PaymentsModule(config) {
2438
2581
  }
2439
2582
 
2440
2583
  // modules/payments/TokenSplitCalculator.ts
2584
+ init_logger();
2441
2585
  var import_Token = require("@unicitylabs/state-transition-sdk/lib/token/Token");
2442
2586
  var import_CoinId = require("@unicitylabs/state-transition-sdk/lib/token/fungible/CoinId");
2443
2587
  var TokenSplitCalculator = class {
@@ -2460,7 +2604,7 @@ var TokenSplitCalculator = class {
2460
2604
  const sdkToken = await import_Token.Token.fromJSON(parsed);
2461
2605
  const realAmount = this.getTokenBalance(sdkToken, targetCoinIdHex);
2462
2606
  if (realAmount <= 0n) {
2463
- console.warn(`[SplitCalculator] Token ${t.id} has 0 balance for coinId ${targetCoinIdHex}`);
2607
+ logger.warn("TokenSplit", `Token ${t.id} has 0 balance for coinId ${targetCoinIdHex}`);
2464
2608
  continue;
2465
2609
  }
2466
2610
  candidates.push({
@@ -2469,14 +2613,15 @@ var TokenSplitCalculator = class {
2469
2613
  uiToken: t
2470
2614
  });
2471
2615
  } catch (e) {
2472
- console.warn("[SplitCalculator] Failed to parse token", t.id, e);
2616
+ logger.warn("TokenSplit", "Failed to parse token", t.id, e);
2473
2617
  }
2474
2618
  }
2475
2619
  candidates.sort((a, b) => a.amount < b.amount ? -1 : 1);
2476
2620
  const totalAvailable = candidates.reduce((sum, t) => sum + t.amount, 0n);
2477
2621
  if (totalAvailable < targetAmount) {
2478
- console.error(
2479
- `[SplitCalculator] Insufficient funds. Available: ${totalAvailable}, Required: ${targetAmount}`
2622
+ logger.error(
2623
+ "TokenSplit",
2624
+ `Insufficient funds. Available: ${totalAvailable}, Required: ${targetAmount}`
2480
2625
  );
2481
2626
  return null;
2482
2627
  }
@@ -2574,6 +2719,8 @@ var TokenSplitCalculator = class {
2574
2719
  };
2575
2720
 
2576
2721
  // modules/payments/TokenSplitExecutor.ts
2722
+ init_logger();
2723
+ init_errors();
2577
2724
  var import_Token2 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
2578
2725
  var import_TokenId = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
2579
2726
  var import_TokenState = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
@@ -2613,7 +2760,7 @@ var TokenSplitExecutor = class {
2613
2760
  }
2614
2761
  async executeSplit(tokenToSplit, splitAmount, remainderAmount, coinIdHex, recipientAddress) {
2615
2762
  const tokenIdHex = toHex(tokenToSplit.id.bytes);
2616
- console.log(`[TokenSplitExecutor] Splitting token ${tokenIdHex.slice(0, 8)}...`);
2763
+ logger.debug("TokenSplit", `Splitting token ${tokenIdHex.slice(0, 8)}...`);
2617
2764
  const coinId = new import_CoinId2.CoinId(fromHex(coinIdHex));
2618
2765
  const seedString = `${tokenIdHex}_${splitAmount.toString()}_${remainderAmount.toString()}`;
2619
2766
  const recipientTokenId = new import_TokenId.TokenId(await sha2562(seedString));
@@ -2633,23 +2780,23 @@ var TokenSplitExecutor = class {
2633
2780
  const coinDataB = import_TokenCoinData.TokenCoinData.create([[coinId, remainderAmount]]);
2634
2781
  builder.createToken(senderTokenId, tokenToSplit.type, new Uint8Array(0), coinDataB, senderAddress, senderSalt, null);
2635
2782
  const split = await builder.build(tokenToSplit);
2636
- console.log("[TokenSplitExecutor] Step 1: Burning original token...");
2783
+ logger.debug("TokenSplit", "Step 1: Burning original token...");
2637
2784
  const burnSalt = await sha2562(seedString + "_burn_salt");
2638
2785
  const burnCommitment = await split.createBurnCommitment(burnSalt, this.signingService);
2639
2786
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
2640
2787
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
2641
- throw new Error(`Burn failed: ${burnResponse.status}`);
2788
+ throw new SphereError(`Burn failed: ${burnResponse.status}`, "TRANSFER_FAILED");
2642
2789
  }
2643
2790
  const burnInclusionProof = await (0, import_InclusionProofUtils.waitInclusionProof)(this.trustBase, this.client, burnCommitment);
2644
2791
  const burnTransaction = burnCommitment.toTransaction(burnInclusionProof);
2645
- console.log("[TokenSplitExecutor] Original token burned.");
2646
- console.log("[TokenSplitExecutor] Step 2: Minting split tokens...");
2792
+ logger.debug("TokenSplit", "Original token burned.");
2793
+ logger.debug("TokenSplit", "Step 2: Minting split tokens...");
2647
2794
  const mintCommitments = await split.createSplitMintCommitments(this.trustBase, burnTransaction);
2648
2795
  const mintedTokensInfo = [];
2649
2796
  for (const commitment of mintCommitments) {
2650
2797
  const res = await this.client.submitMintCommitment(commitment);
2651
2798
  if (res.status !== "SUCCESS" && res.status !== "REQUEST_ID_EXISTS") {
2652
- throw new Error(`Mint split token failed: ${res.status}`);
2799
+ throw new SphereError(`Mint split token failed: ${res.status}`, "TRANSFER_FAILED");
2653
2800
  }
2654
2801
  const proof = await (0, import_InclusionProofUtils.waitInclusionProof)(this.trustBase, this.client, commitment);
2655
2802
  const commTokenIdHex = toHex(commitment.transactionData.tokenId.bytes);
@@ -2662,7 +2809,7 @@ var TokenSplitExecutor = class {
2662
2809
  salt: commitment.transactionData.salt
2663
2810
  });
2664
2811
  }
2665
- console.log("[TokenSplitExecutor] Split tokens minted.");
2812
+ logger.debug("TokenSplit", "Split tokens minted.");
2666
2813
  const recipientInfo = mintedTokensInfo.find((t) => t.isForRecipient);
2667
2814
  const senderInfo = mintedTokensInfo.find((t) => !t.isForRecipient);
2668
2815
  const createToken = async (info, label) => {
@@ -2670,12 +2817,12 @@ var TokenSplitExecutor = class {
2670
2817
  const state = new import_TokenState.TokenState(predicate, null);
2671
2818
  const token = await import_Token2.Token.mint(this.trustBase, state, info.commitment.toTransaction(info.inclusionProof));
2672
2819
  const verification = await token.verify(this.trustBase);
2673
- if (!verification.isSuccessful) throw new Error(`Token verification failed: ${label}`);
2820
+ if (!verification.isSuccessful) throw new SphereError(`Token verification failed: ${label}`, "TRANSFER_FAILED");
2674
2821
  return token;
2675
2822
  };
2676
2823
  const recipientTokenBeforeTransfer = await createToken(recipientInfo, "Recipient");
2677
2824
  const senderToken = await createToken(senderInfo, "Sender");
2678
- console.log("[TokenSplitExecutor] Step 3: Transferring to recipient...");
2825
+ logger.debug("TokenSplit", "Step 3: Transferring to recipient...");
2679
2826
  const transferSalt = await sha2562(seedString + "_transfer_salt");
2680
2827
  const transferCommitment = await import_TransferCommitment.TransferCommitment.create(
2681
2828
  recipientTokenBeforeTransfer,
@@ -2687,11 +2834,11 @@ var TokenSplitExecutor = class {
2687
2834
  );
2688
2835
  const transferRes = await this.client.submitTransferCommitment(transferCommitment);
2689
2836
  if (transferRes.status !== "SUCCESS" && transferRes.status !== "REQUEST_ID_EXISTS") {
2690
- throw new Error(`Transfer failed: ${transferRes.status}`);
2837
+ throw new SphereError(`Transfer failed: ${transferRes.status}`, "TRANSFER_FAILED");
2691
2838
  }
2692
2839
  const transferProof = await (0, import_InclusionProofUtils.waitInclusionProof)(this.trustBase, this.client, transferCommitment);
2693
2840
  const transferTx = transferCommitment.toTransaction(transferProof);
2694
- console.log("[TokenSplitExecutor] Split transfer complete!");
2841
+ logger.debug("TokenSplit", "Split transfer complete!");
2695
2842
  return {
2696
2843
  tokenForRecipient: recipientTokenBeforeTransfer,
2697
2844
  tokenForSender: senderToken,
@@ -2701,6 +2848,7 @@ var TokenSplitExecutor = class {
2701
2848
  };
2702
2849
 
2703
2850
  // modules/payments/NametagMinter.ts
2851
+ init_logger();
2704
2852
  var import_Token3 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
2705
2853
  var import_TokenId2 = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
2706
2854
  var import_TokenType = require("@unicitylabs/state-transition-sdk/lib/token/TokenType");
@@ -2725,10 +2873,8 @@ var NametagMinter = class {
2725
2873
  this.skipVerification = config.skipVerification ?? false;
2726
2874
  this.debug = config.debug ?? false;
2727
2875
  }
2728
- log(...args) {
2729
- if (this.debug) {
2730
- console.log("[NametagMinter]", ...args);
2731
- }
2876
+ log(message, ...args) {
2877
+ logger.debug("NametagMinter", message, ...args);
2732
2878
  }
2733
2879
  /**
2734
2880
  * Check if a nametag is available (not already minted)
@@ -2915,6 +3061,7 @@ function isValidTokenId(tokenId) {
2915
3061
  }
2916
3062
 
2917
3063
  // registry/TokenRegistry.ts
3064
+ init_logger();
2918
3065
  init_constants();
2919
3066
  var FETCH_TIMEOUT_MS = 1e4;
2920
3067
  var TokenRegistry = class _TokenRegistry {
@@ -3136,14 +3283,12 @@ var TokenRegistry = class _TokenRegistry {
3136
3283
  clearTimeout(timer);
3137
3284
  }
3138
3285
  if (!response.ok) {
3139
- console.warn(
3140
- `[TokenRegistry] Remote fetch failed: HTTP ${response.status} ${response.statusText}`
3141
- );
3286
+ logger.warn("TokenRegistry", `Remote fetch failed: HTTP ${response.status} ${response.statusText}`);
3142
3287
  return false;
3143
3288
  }
3144
3289
  const data = await response.json();
3145
3290
  if (!this.isValidDefinitionsArray(data)) {
3146
- console.warn("[TokenRegistry] Remote data is not a valid token definitions array");
3291
+ logger.warn("TokenRegistry", "Remote data is not a valid token definitions array");
3147
3292
  return false;
3148
3293
  }
3149
3294
  const definitions = data;
@@ -3153,7 +3298,7 @@ var TokenRegistry = class _TokenRegistry {
3153
3298
  return true;
3154
3299
  } catch (error) {
3155
3300
  const message = error instanceof Error ? error.message : String(error);
3156
- console.warn(`[TokenRegistry] Remote refresh failed: ${message}`);
3301
+ logger.warn("TokenRegistry", `Remote refresh failed: ${message}`);
3157
3302
  return false;
3158
3303
  }
3159
3304
  }
@@ -3715,7 +3860,13 @@ function countCommittedTransactions(token) {
3715
3860
  }
3716
3861
  }
3717
3862
 
3863
+ // modules/payments/PaymentsModule.ts
3864
+ init_logger();
3865
+ init_errors();
3866
+
3718
3867
  // modules/payments/InstantSplitExecutor.ts
3868
+ init_logger();
3869
+ init_errors();
3719
3870
  var import_Token4 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
3720
3871
  var import_TokenId3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
3721
3872
  var import_TokenState3 = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
@@ -3771,7 +3922,7 @@ var InstantSplitExecutor = class {
3771
3922
  async buildSplitBundle(tokenToSplit, splitAmount, remainderAmount, coinIdHex, recipientAddress, options) {
3772
3923
  const splitGroupId = crypto.randomUUID();
3773
3924
  const tokenIdHex = toHex2(tokenToSplit.id.bytes);
3774
- console.log(`[InstantSplit] Building V5 bundle for token ${tokenIdHex.slice(0, 8)}...`);
3925
+ logger.debug("InstantSplit", `Building V5 bundle for token ${tokenIdHex.slice(0, 8)}...`);
3775
3926
  const coinId = new import_CoinId3.CoinId(fromHex2(coinIdHex));
3776
3927
  const seedString = `${tokenIdHex}_${splitAmount.toString()}_${remainderAmount.toString()}_${Date.now()}`;
3777
3928
  const recipientTokenId = new import_TokenId3.TokenId(await sha2563(seedString));
@@ -3808,19 +3959,19 @@ var InstantSplitExecutor = class {
3808
3959
  null
3809
3960
  );
3810
3961
  const split = await builder.build(tokenToSplit);
3811
- console.log("[InstantSplit] Step 1: Creating and submitting burn...");
3962
+ logger.debug("InstantSplit", "Step 1: Creating and submitting burn...");
3812
3963
  const burnSalt = await sha2563(seedString + "_burn_salt");
3813
3964
  const burnCommitment = await split.createBurnCommitment(burnSalt, this.signingService);
3814
3965
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
3815
3966
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
3816
- throw new Error(`Burn submission failed: ${burnResponse.status}`);
3967
+ throw new SphereError(`Burn submission failed: ${burnResponse.status}`, "TRANSFER_FAILED");
3817
3968
  }
3818
- console.log("[InstantSplit] Step 2: Waiting for burn proof...");
3969
+ logger.debug("InstantSplit", "Step 2: Waiting for burn proof...");
3819
3970
  const burnProof = this.devMode ? await this.waitInclusionProofWithDevBypass(burnCommitment, options?.burnProofTimeoutMs) : await (0, import_InclusionProofUtils3.waitInclusionProof)(this.trustBase, this.client, burnCommitment);
3820
3971
  const burnTransaction = burnCommitment.toTransaction(burnProof);
3821
- console.log(`[InstantSplit] Burn proof received`);
3972
+ logger.debug("InstantSplit", "Burn proof received");
3822
3973
  options?.onBurnCompleted?.(JSON.stringify(burnTransaction.toJSON()));
3823
- console.log("[InstantSplit] Step 3: Creating mint commitments...");
3974
+ logger.debug("InstantSplit", "Step 3: Creating mint commitments...");
3824
3975
  const mintCommitments = await split.createSplitMintCommitments(this.trustBase, burnTransaction);
3825
3976
  const recipientIdHex = toHex2(recipientTokenId.bytes);
3826
3977
  const senderIdHex = toHex2(senderTokenId.bytes);
@@ -3831,9 +3982,9 @@ var InstantSplitExecutor = class {
3831
3982
  (c) => toHex2(c.transactionData.tokenId.bytes) === senderIdHex
3832
3983
  );
3833
3984
  if (!recipientMintCommitment || !senderMintCommitment) {
3834
- throw new Error("Failed to find expected mint commitments");
3985
+ throw new SphereError("Failed to find expected mint commitments", "TRANSFER_FAILED");
3835
3986
  }
3836
- console.log("[InstantSplit] Step 4: Creating transfer commitment...");
3987
+ logger.debug("InstantSplit", "Step 4: Creating transfer commitment...");
3837
3988
  const transferSalt = await sha2563(seedString + "_transfer_salt");
3838
3989
  const transferCommitment = await this.createTransferCommitmentFromMintData(
3839
3990
  recipientMintCommitment.transactionData,
@@ -3849,7 +4000,7 @@ var InstantSplitExecutor = class {
3849
4000
  recipientSalt
3850
4001
  );
3851
4002
  const mintedState = new import_TokenState3.TokenState(mintedPredicate, null);
3852
- console.log("[InstantSplit] Step 5: Packaging V5 bundle...");
4003
+ logger.debug("InstantSplit", "Step 5: Packaging V5 bundle...");
3853
4004
  const senderPubkey = toHex2(this.signingService.publicKey);
3854
4005
  let nametagTokenJson;
3855
4006
  const recipientAddressStr = recipientAddress.toString();
@@ -3921,7 +4072,7 @@ var InstantSplitExecutor = class {
3921
4072
  recipientAddress,
3922
4073
  options
3923
4074
  );
3924
- console.log("[InstantSplit] Sending via transport...");
4075
+ logger.debug("InstantSplit", "Sending via transport...");
3925
4076
  const senderPubkey = toHex2(this.signingService.publicKey);
3926
4077
  const nostrEventId = await transport.sendTokenTransfer(recipientPubkey, {
3927
4078
  token: JSON.stringify(buildResult.bundle),
@@ -3933,7 +4084,7 @@ var InstantSplitExecutor = class {
3933
4084
  }
3934
4085
  });
3935
4086
  const criticalPathDuration = performance.now() - startTime;
3936
- console.log(`[InstantSplit] V5 complete in ${criticalPathDuration.toFixed(0)}ms`);
4087
+ logger.debug("InstantSplit", `V5 complete in ${criticalPathDuration.toFixed(0)}ms`);
3937
4088
  options?.onNostrDelivered?.(nostrEventId);
3938
4089
  const backgroundPromise = buildResult.startBackground();
3939
4090
  return {
@@ -3947,7 +4098,7 @@ var InstantSplitExecutor = class {
3947
4098
  } catch (error) {
3948
4099
  const duration = performance.now() - startTime;
3949
4100
  const errorMessage = error instanceof Error ? error.message : String(error);
3950
- console.error(`[InstantSplit] Failed after ${duration.toFixed(0)}ms:`, error);
4101
+ logger.error("InstantSplit", `Failed after ${duration.toFixed(0)}ms:`, error);
3951
4102
  return {
3952
4103
  success: false,
3953
4104
  criticalPathDurationMs: duration,
@@ -3996,7 +4147,7 @@ var InstantSplitExecutor = class {
3996
4147
  * Then waits for sender's mint proof, reconstructs change token, and saves it.
3997
4148
  */
3998
4149
  submitBackgroundV5(senderMintCommitment, recipientMintCommitment, transferCommitment, context) {
3999
- console.log("[InstantSplit] Background: Starting parallel mint submission...");
4150
+ logger.debug("InstantSplit", "Background: Starting parallel mint submission...");
4000
4151
  const startTime = performance.now();
4001
4152
  const submissions = Promise.all([
4002
4153
  this.client.submitMintCommitment(senderMintCommitment).then((res) => ({ type: "senderMint", status: res.status })).catch((err) => ({ type: "senderMint", status: "ERROR", error: err })),
@@ -4005,14 +4156,14 @@ var InstantSplitExecutor = class {
4005
4156
  ]);
4006
4157
  return submissions.then(async (results) => {
4007
4158
  const submitDuration = performance.now() - startTime;
4008
- console.log(`[InstantSplit] Background: Submissions complete in ${submitDuration.toFixed(0)}ms`);
4159
+ logger.debug("InstantSplit", `Background: Submissions complete in ${submitDuration.toFixed(0)}ms`);
4009
4160
  context.onProgress?.({
4010
4161
  stage: "MINTS_SUBMITTED",
4011
4162
  message: `All commitments submitted in ${submitDuration.toFixed(0)}ms`
4012
4163
  });
4013
4164
  const senderMintResult = results.find((r) => r.type === "senderMint");
4014
4165
  if (senderMintResult?.status !== "SUCCESS" && senderMintResult?.status !== "REQUEST_ID_EXISTS") {
4015
- console.error("[InstantSplit] Background: Sender mint failed - cannot save change token");
4166
+ logger.error("InstantSplit", "Background: Sender mint failed - cannot save change token");
4016
4167
  context.onProgress?.({
4017
4168
  stage: "FAILED",
4018
4169
  message: "Sender mint submission failed",
@@ -4020,12 +4171,12 @@ var InstantSplitExecutor = class {
4020
4171
  });
4021
4172
  return;
4022
4173
  }
4023
- console.log("[InstantSplit] Background: Waiting for sender mint proof...");
4174
+ logger.debug("InstantSplit", "Background: Waiting for sender mint proof...");
4024
4175
  const proofStartTime = performance.now();
4025
4176
  try {
4026
4177
  const senderMintProof = this.devMode ? await this.waitInclusionProofWithDevBypass(senderMintCommitment) : await (0, import_InclusionProofUtils3.waitInclusionProof)(this.trustBase, this.client, senderMintCommitment);
4027
4178
  const proofDuration = performance.now() - proofStartTime;
4028
- console.log(`[InstantSplit] Background: Sender mint proof received in ${proofDuration.toFixed(0)}ms`);
4179
+ logger.debug("InstantSplit", `Background: Sender mint proof received in ${proofDuration.toFixed(0)}ms`);
4029
4180
  context.onProgress?.({
4030
4181
  stage: "MINTS_PROVEN",
4031
4182
  message: `Mint proof received in ${proofDuration.toFixed(0)}ms`
@@ -4043,38 +4194,38 @@ var InstantSplitExecutor = class {
4043
4194
  if (!this.devMode) {
4044
4195
  const verification = await changeToken.verify(this.trustBase);
4045
4196
  if (!verification.isSuccessful) {
4046
- throw new Error(`Change token verification failed`);
4197
+ throw new SphereError("Change token verification failed", "TRANSFER_FAILED");
4047
4198
  }
4048
4199
  }
4049
- console.log("[InstantSplit] Background: Change token created");
4200
+ logger.debug("InstantSplit", "Background: Change token created");
4050
4201
  context.onProgress?.({
4051
4202
  stage: "CHANGE_TOKEN_SAVED",
4052
4203
  message: "Change token created and verified"
4053
4204
  });
4054
4205
  if (context.onChangeTokenCreated) {
4055
4206
  await context.onChangeTokenCreated(changeToken);
4056
- console.log("[InstantSplit] Background: Change token saved");
4207
+ logger.debug("InstantSplit", "Background: Change token saved");
4057
4208
  }
4058
4209
  if (context.onStorageSync) {
4059
4210
  try {
4060
4211
  const syncSuccess = await context.onStorageSync();
4061
- console.log(`[InstantSplit] Background: Storage sync ${syncSuccess ? "completed" : "deferred"}`);
4212
+ logger.debug("InstantSplit", `Background: Storage sync ${syncSuccess ? "completed" : "deferred"}`);
4062
4213
  context.onProgress?.({
4063
4214
  stage: "STORAGE_SYNCED",
4064
4215
  message: syncSuccess ? "Storage synchronized" : "Sync deferred"
4065
4216
  });
4066
4217
  } catch (syncError) {
4067
- console.warn("[InstantSplit] Background: Storage sync error:", syncError);
4218
+ logger.warn("InstantSplit", "Background: Storage sync error:", syncError);
4068
4219
  }
4069
4220
  }
4070
4221
  const totalDuration = performance.now() - startTime;
4071
- console.log(`[InstantSplit] Background: Complete in ${totalDuration.toFixed(0)}ms`);
4222
+ logger.debug("InstantSplit", `Background: Complete in ${totalDuration.toFixed(0)}ms`);
4072
4223
  context.onProgress?.({
4073
4224
  stage: "COMPLETED",
4074
4225
  message: `Background processing complete in ${totalDuration.toFixed(0)}ms`
4075
4226
  });
4076
4227
  } catch (proofError) {
4077
- console.error("[InstantSplit] Background: Failed to get sender mint proof:", proofError);
4228
+ logger.error("InstantSplit", "Background: Failed to get sender mint proof:", proofError);
4078
4229
  context.onProgress?.({
4079
4230
  stage: "FAILED",
4080
4231
  message: "Failed to get mint proof",
@@ -4082,7 +4233,7 @@ var InstantSplitExecutor = class {
4082
4233
  });
4083
4234
  }
4084
4235
  }).catch((err) => {
4085
- console.error("[InstantSplit] Background: Submission batch failed:", err);
4236
+ logger.error("InstantSplit", "Background: Submission batch failed:", err);
4086
4237
  context.onProgress?.({
4087
4238
  stage: "FAILED",
4088
4239
  message: "Background submission failed",
@@ -4104,7 +4255,7 @@ var InstantSplitExecutor = class {
4104
4255
  )
4105
4256
  ]);
4106
4257
  } catch {
4107
- console.log("[InstantSplit] Dev mode: Using mock proof");
4258
+ logger.debug("InstantSplit", "Dev mode: Using mock proof");
4108
4259
  return {
4109
4260
  toJSON: () => ({ mock: true })
4110
4261
  };
@@ -4115,6 +4266,8 @@ var InstantSplitExecutor = class {
4115
4266
  };
4116
4267
 
4117
4268
  // modules/payments/InstantSplitProcessor.ts
4269
+ init_logger();
4270
+ init_errors();
4118
4271
  var import_Token5 = require("@unicitylabs/state-transition-sdk/lib/token/Token");
4119
4272
  var import_TokenState4 = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
4120
4273
  var import_TokenType2 = require("@unicitylabs/state-transition-sdk/lib/token/TokenType");
@@ -4209,27 +4362,27 @@ var InstantSplitProcessor = class {
4209
4362
  * 5. Create recipient's final state and finalize token
4210
4363
  */
4211
4364
  async processV5Bundle(bundle, signingService, senderPubkey, options) {
4212
- console.log("[InstantSplitProcessor] Processing V5 bundle...");
4365
+ logger.debug("InstantSplit", "Processing V5 bundle...");
4213
4366
  const startTime = performance.now();
4214
4367
  try {
4215
4368
  if (bundle.senderPubkey !== senderPubkey) {
4216
- console.warn("[InstantSplitProcessor] Sender pubkey mismatch (non-fatal)");
4369
+ logger.warn("InstantSplit", "Sender pubkey mismatch (non-fatal)");
4217
4370
  }
4218
4371
  const burnTxJson = JSON.parse(bundle.burnTransaction);
4219
4372
  const _burnTransaction = await import_TransferTransaction.TransferTransaction.fromJSON(burnTxJson);
4220
- console.log("[InstantSplitProcessor] Burn transaction validated");
4373
+ logger.debug("InstantSplit", "Burn transaction validated");
4221
4374
  const mintDataJson = JSON.parse(bundle.recipientMintData);
4222
4375
  const mintData = await import_MintTransactionData2.MintTransactionData.fromJSON(mintDataJson);
4223
4376
  const mintCommitment = await import_MintCommitment2.MintCommitment.create(mintData);
4224
- console.log("[InstantSplitProcessor] Mint commitment recreated");
4377
+ logger.debug("InstantSplit", "Mint commitment recreated");
4225
4378
  const mintResponse = await this.client.submitMintCommitment(mintCommitment);
4226
4379
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
4227
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
4380
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
4228
4381
  }
4229
- console.log(`[InstantSplitProcessor] Mint submitted: ${mintResponse.status}`);
4382
+ logger.debug("InstantSplit", `Mint submitted: ${mintResponse.status}`);
4230
4383
  const mintProof = this.devMode ? await this.waitInclusionProofWithDevBypass(mintCommitment, options?.proofTimeoutMs) : await (0, import_InclusionProofUtils4.waitInclusionProof)(this.trustBase, this.client, mintCommitment);
4231
4384
  const mintTransaction = mintCommitment.toTransaction(mintProof);
4232
- console.log("[InstantSplitProcessor] Mint proof received");
4385
+ logger.debug("InstantSplit", "Mint proof received");
4233
4386
  const tokenType = new import_TokenType2.TokenType(fromHex3(bundle.tokenTypeHex));
4234
4387
  const senderMintedStateJson = JSON.parse(bundle.mintedTokenStateJson);
4235
4388
  const tokenJson = {
@@ -4240,17 +4393,17 @@ var InstantSplitProcessor = class {
4240
4393
  nametags: []
4241
4394
  };
4242
4395
  const mintedToken = await import_Token5.Token.fromJSON(tokenJson);
4243
- console.log("[InstantSplitProcessor] Minted token reconstructed from sender state");
4396
+ logger.debug("InstantSplit", "Minted token reconstructed from sender state");
4244
4397
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
4245
4398
  const transferCommitment = await import_TransferCommitment3.TransferCommitment.fromJSON(transferCommitmentJson);
4246
4399
  const transferResponse = await this.client.submitTransferCommitment(transferCommitment);
4247
4400
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
4248
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
4401
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
4249
4402
  }
4250
- console.log(`[InstantSplitProcessor] Transfer submitted: ${transferResponse.status}`);
4403
+ logger.debug("InstantSplit", `Transfer submitted: ${transferResponse.status}`);
4251
4404
  const transferProof = this.devMode ? await this.waitInclusionProofWithDevBypass(transferCommitment, options?.proofTimeoutMs) : await (0, import_InclusionProofUtils4.waitInclusionProof)(this.trustBase, this.client, transferCommitment);
4252
4405
  const transferTransaction = transferCommitment.toTransaction(transferProof);
4253
- console.log("[InstantSplitProcessor] Transfer proof received");
4406
+ logger.debug("InstantSplit", "Transfer proof received");
4254
4407
  const transferSalt = fromHex3(bundle.transferSaltHex);
4255
4408
  const finalRecipientPredicate = await import_UnmaskedPredicate4.UnmaskedPredicate.create(
4256
4409
  mintData.tokenId,
@@ -4260,42 +4413,43 @@ var InstantSplitProcessor = class {
4260
4413
  transferSalt
4261
4414
  );
4262
4415
  const finalRecipientState = new import_TokenState4.TokenState(finalRecipientPredicate, null);
4263
- console.log("[InstantSplitProcessor] Final recipient state created");
4416
+ logger.debug("InstantSplit", "Final recipient state created");
4264
4417
  let nametagTokens = [];
4265
4418
  const recipientAddressStr = bundle.recipientAddressJson;
4266
4419
  if (recipientAddressStr.startsWith("PROXY://")) {
4267
- console.log("[InstantSplitProcessor] PROXY address detected, finding nametag token...");
4420
+ logger.debug("InstantSplit", "PROXY address detected, finding nametag token...");
4268
4421
  if (bundle.nametagTokenJson) {
4269
4422
  try {
4270
4423
  const nametagToken = await import_Token5.Token.fromJSON(JSON.parse(bundle.nametagTokenJson));
4271
4424
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
4272
4425
  const proxy = await ProxyAddress.fromTokenId(nametagToken.id);
4273
4426
  if (proxy.address !== recipientAddressStr) {
4274
- console.warn("[InstantSplitProcessor] Nametag PROXY address mismatch, ignoring bundle token");
4427
+ logger.warn("InstantSplit", "Nametag PROXY address mismatch, ignoring bundle token");
4275
4428
  } else {
4276
4429
  nametagTokens = [nametagToken];
4277
- console.log("[InstantSplitProcessor] Using nametag token from bundle (address validated)");
4430
+ logger.debug("InstantSplit", "Using nametag token from bundle (address validated)");
4278
4431
  }
4279
4432
  } catch (err) {
4280
- console.warn("[InstantSplitProcessor] Failed to parse nametag token from bundle:", err);
4433
+ logger.warn("InstantSplit", "Failed to parse nametag token from bundle:", err);
4281
4434
  }
4282
4435
  }
4283
4436
  if (nametagTokens.length === 0 && options?.findNametagToken) {
4284
4437
  const token = await options.findNametagToken(recipientAddressStr);
4285
4438
  if (token) {
4286
4439
  nametagTokens = [token];
4287
- console.log("[InstantSplitProcessor] Found nametag token via callback");
4440
+ logger.debug("InstantSplit", "Found nametag token via callback");
4288
4441
  }
4289
4442
  }
4290
4443
  if (nametagTokens.length === 0 && !this.devMode) {
4291
- throw new Error(
4292
- `PROXY address transfer requires nametag token for verification. Address: ${recipientAddressStr}`
4444
+ throw new SphereError(
4445
+ `PROXY address transfer requires nametag token for verification. Address: ${recipientAddressStr}`,
4446
+ "TRANSFER_FAILED"
4293
4447
  );
4294
4448
  }
4295
4449
  }
4296
4450
  let finalToken;
4297
4451
  if (this.devMode) {
4298
- console.log("[InstantSplitProcessor] Dev mode: finalizing without verification");
4452
+ logger.debug("InstantSplit", "Dev mode: finalizing without verification");
4299
4453
  const tokenJson2 = mintedToken.toJSON();
4300
4454
  tokenJson2.state = finalRecipientState.toJSON();
4301
4455
  tokenJson2.transactions = [transferTransaction.toJSON()];
@@ -4309,16 +4463,16 @@ var InstantSplitProcessor = class {
4309
4463
  nametagTokens
4310
4464
  );
4311
4465
  }
4312
- console.log("[InstantSplitProcessor] Token finalized");
4466
+ logger.debug("InstantSplit", "Token finalized");
4313
4467
  if (!this.devMode) {
4314
4468
  const verification = await finalToken.verify(this.trustBase);
4315
4469
  if (!verification.isSuccessful) {
4316
- throw new Error(`Token verification failed`);
4470
+ throw new SphereError(`Token verification failed`, "TRANSFER_FAILED");
4317
4471
  }
4318
- console.log("[InstantSplitProcessor] Token verified");
4472
+ logger.debug("InstantSplit", "Token verified");
4319
4473
  }
4320
4474
  const duration = performance.now() - startTime;
4321
- console.log(`[InstantSplitProcessor] V5 bundle processed in ${duration.toFixed(0)}ms`);
4475
+ logger.debug("InstantSplit", `V5 bundle processed in ${duration.toFixed(0)}ms`);
4322
4476
  return {
4323
4477
  success: true,
4324
4478
  token: finalToken,
@@ -4327,7 +4481,7 @@ var InstantSplitProcessor = class {
4327
4481
  } catch (error) {
4328
4482
  const duration = performance.now() - startTime;
4329
4483
  const errorMessage = error instanceof Error ? error.message : String(error);
4330
- console.error(`[InstantSplitProcessor] V5 processing failed:`, error);
4484
+ logger.error("InstantSplit", "V5 processing failed:", error);
4331
4485
  return {
4332
4486
  success: false,
4333
4487
  error: errorMessage,
@@ -4353,30 +4507,30 @@ var InstantSplitProcessor = class {
4353
4507
  durationMs: 0
4354
4508
  };
4355
4509
  }
4356
- console.log("[InstantSplitProcessor] Processing V4 bundle (dev mode)...");
4510
+ logger.debug("InstantSplit", "Processing V4 bundle (dev mode)...");
4357
4511
  const startTime = performance.now();
4358
4512
  try {
4359
4513
  const burnCommitmentJson = JSON.parse(bundle.burnCommitment);
4360
4514
  const burnCommitment = await import_TransferCommitment3.TransferCommitment.fromJSON(burnCommitmentJson);
4361
4515
  const burnResponse = await this.client.submitTransferCommitment(burnCommitment);
4362
4516
  if (burnResponse.status !== "SUCCESS" && burnResponse.status !== "REQUEST_ID_EXISTS") {
4363
- throw new Error(`Burn submission failed: ${burnResponse.status}`);
4517
+ throw new SphereError(`Burn submission failed: ${burnResponse.status}`, "TRANSFER_FAILED");
4364
4518
  }
4365
4519
  await this.waitInclusionProofWithDevBypass(burnCommitment, options?.proofTimeoutMs);
4366
- console.log("[InstantSplitProcessor] V4: Burn proof received");
4520
+ logger.debug("InstantSplit", "V4: Burn proof received");
4367
4521
  const mintDataJson = JSON.parse(bundle.recipientMintData);
4368
4522
  const mintData = await import_MintTransactionData2.MintTransactionData.fromJSON(mintDataJson);
4369
4523
  const mintCommitment = await import_MintCommitment2.MintCommitment.create(mintData);
4370
4524
  const mintResponse = await this.client.submitMintCommitment(mintCommitment);
4371
4525
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
4372
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
4526
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
4373
4527
  }
4374
4528
  const mintProof = await this.waitInclusionProofWithDevBypass(
4375
4529
  mintCommitment,
4376
4530
  options?.proofTimeoutMs
4377
4531
  );
4378
4532
  const mintTransaction = mintCommitment.toTransaction(mintProof);
4379
- console.log("[InstantSplitProcessor] V4: Mint proof received");
4533
+ logger.debug("InstantSplit", "V4: Mint proof received");
4380
4534
  const tokenType = new import_TokenType2.TokenType(fromHex3(bundle.tokenTypeHex));
4381
4535
  const recipientSalt = fromHex3(bundle.recipientSaltHex);
4382
4536
  const recipientPredicate = await import_UnmaskedPredicate4.UnmaskedPredicate.create(
@@ -4395,19 +4549,19 @@ var InstantSplitProcessor = class {
4395
4549
  nametags: []
4396
4550
  };
4397
4551
  const mintedToken = await import_Token5.Token.fromJSON(tokenJson);
4398
- console.log("[InstantSplitProcessor] V4: Minted token reconstructed");
4552
+ logger.debug("InstantSplit", "V4: Minted token reconstructed");
4399
4553
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
4400
4554
  const transferCommitment = await import_TransferCommitment3.TransferCommitment.fromJSON(transferCommitmentJson);
4401
4555
  const transferResponse = await this.client.submitTransferCommitment(transferCommitment);
4402
4556
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
4403
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
4557
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
4404
4558
  }
4405
4559
  const transferProof = await this.waitInclusionProofWithDevBypass(
4406
4560
  transferCommitment,
4407
4561
  options?.proofTimeoutMs
4408
4562
  );
4409
4563
  const transferTransaction = transferCommitment.toTransaction(transferProof);
4410
- console.log("[InstantSplitProcessor] V4: Transfer proof received");
4564
+ logger.debug("InstantSplit", "V4: Transfer proof received");
4411
4565
  const transferSalt = fromHex3(bundle.transferSaltHex);
4412
4566
  const finalPredicate = await import_UnmaskedPredicate4.UnmaskedPredicate.create(
4413
4567
  mintData.tokenId,
@@ -4421,9 +4575,9 @@ var InstantSplitProcessor = class {
4421
4575
  finalTokenJson.state = finalState.toJSON();
4422
4576
  finalTokenJson.transactions = [transferTransaction.toJSON()];
4423
4577
  const finalToken = await import_Token5.Token.fromJSON(finalTokenJson);
4424
- console.log("[InstantSplitProcessor] V4: Token finalized");
4578
+ logger.debug("InstantSplit", "V4: Token finalized");
4425
4579
  const duration = performance.now() - startTime;
4426
- console.log(`[InstantSplitProcessor] V4 bundle processed in ${duration.toFixed(0)}ms`);
4580
+ logger.debug("InstantSplit", `V4 bundle processed in ${duration.toFixed(0)}ms`);
4427
4581
  return {
4428
4582
  success: true,
4429
4583
  token: finalToken,
@@ -4432,7 +4586,7 @@ var InstantSplitProcessor = class {
4432
4586
  } catch (error) {
4433
4587
  const duration = performance.now() - startTime;
4434
4588
  const errorMessage = error instanceof Error ? error.message : String(error);
4435
- console.error(`[InstantSplitProcessor] V4 processing failed:`, error);
4589
+ logger.error("InstantSplit", "V4 processing failed:", error);
4436
4590
  return {
4437
4591
  success: false,
4438
4592
  error: errorMessage,
@@ -4453,7 +4607,7 @@ var InstantSplitProcessor = class {
4453
4607
  )
4454
4608
  ]);
4455
4609
  } catch {
4456
- console.log("[InstantSplitProcessor] Dev mode: Using mock proof");
4610
+ logger.debug("InstantSplit", "Dev mode: Using mock proof");
4457
4611
  return {
4458
4612
  toJSON: () => ({ mock: true })
4459
4613
  };
@@ -4638,7 +4792,7 @@ async function parseTokenInfo(tokenData) {
4638
4792
  }
4639
4793
  }
4640
4794
  } catch (error) {
4641
- console.warn("[Payments] Failed to parse token info:", error);
4795
+ logger.warn("Payments", "Failed to parse token info:", error);
4642
4796
  }
4643
4797
  return defaultInfo;
4644
4798
  }
@@ -4841,11 +4995,6 @@ var PaymentsModule = class _PaymentsModule {
4841
4995
  }
4842
4996
  /** Price provider (optional) */
4843
4997
  priceProvider = null;
4844
- log(...args) {
4845
- if (this.moduleConfig.debug) {
4846
- console.log("[PaymentsModule]", ...args);
4847
- }
4848
- }
4849
4998
  // ===========================================================================
4850
4999
  // Lifecycle
4851
5000
  // ===========================================================================
@@ -4912,11 +5061,11 @@ var PaymentsModule = class _PaymentsModule {
4912
5061
  if (txfData._history && txfData._history.length > 0) {
4913
5062
  await this.importRemoteHistoryEntries(txfData._history);
4914
5063
  }
4915
- this.log(`Loaded metadata from provider ${id}`);
5064
+ logger.debug("Payments", `Loaded metadata from provider ${id}`);
4916
5065
  break;
4917
5066
  }
4918
5067
  } catch (err) {
4919
- console.error(`[Payments] Failed to load from provider ${id}:`, err);
5068
+ logger.error("Payments", `Failed to load from provider ${id}:`, err);
4920
5069
  }
4921
5070
  }
4922
5071
  for (const [id, token] of this.tokens) {
@@ -4925,14 +5074,14 @@ var PaymentsModule = class _PaymentsModule {
4925
5074
  const data = JSON.parse(token.sdkData);
4926
5075
  if (data?._placeholder) {
4927
5076
  this.tokens.delete(id);
4928
- console.log(`[Payments] Removed stale placeholder token: ${id}`);
5077
+ logger.debug("Payments", `Removed stale placeholder token: ${id}`);
4929
5078
  }
4930
5079
  }
4931
5080
  } catch {
4932
5081
  }
4933
5082
  }
4934
5083
  const loadedTokens = Array.from(this.tokens.values()).map((t) => `${t.id.slice(0, 12)}(${t.status})`);
4935
- console.log(`[Payments][DEBUG] load(): from TXF providers: ${this.tokens.size} tokens [${loadedTokens.join(", ")}]`);
5084
+ logger.debug("Payments", `load(): from TXF providers: ${this.tokens.size} tokens [${loadedTokens.join(", ")}]`);
4936
5085
  await this.loadPendingV5Tokens();
4937
5086
  await this.loadProcessedSplitGroupIds();
4938
5087
  await this.loadProcessedCombinedTransferIds();
@@ -4948,8 +5097,7 @@ var PaymentsModule = class _PaymentsModule {
4948
5097
  };
4949
5098
  this.loadedPromise = doLoad();
4950
5099
  await this.loadedPromise;
4951
- this.resolveUnconfirmed().catch(() => {
4952
- });
5100
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
4953
5101
  this.scheduleResolveUnconfirmed();
4954
5102
  }
4955
5103
  /**
@@ -5002,11 +5150,11 @@ var PaymentsModule = class _PaymentsModule {
5002
5150
  const signingService = await this.createSigningService();
5003
5151
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5004
5152
  if (!stClient) {
5005
- throw new Error("State transition client not available. Oracle provider must implement getStateTransitionClient()");
5153
+ throw new SphereError("State transition client not available. Oracle provider must implement getStateTransitionClient()", "AGGREGATOR_ERROR");
5006
5154
  }
5007
5155
  const trustBase = this.deps.oracle.getTrustBase?.();
5008
5156
  if (!trustBase) {
5009
- throw new Error("Trust base not available. Oracle provider must implement getTrustBase()");
5157
+ throw new SphereError("Trust base not available. Oracle provider must implement getTrustBase()", "AGGREGATOR_ERROR");
5010
5158
  }
5011
5159
  const calculator = new TokenSplitCalculator();
5012
5160
  const availableTokens = Array.from(this.tokens.values());
@@ -5016,7 +5164,7 @@ var PaymentsModule = class _PaymentsModule {
5016
5164
  request.coinId
5017
5165
  );
5018
5166
  if (!splitPlan) {
5019
- throw new Error("Insufficient balance");
5167
+ throw new SphereError("Insufficient balance", "INSUFFICIENT_BALANCE");
5020
5168
  }
5021
5169
  const tokensToSend = splitPlan.tokensToTransferDirectly.map((t) => t.uiToken);
5022
5170
  if (splitPlan.tokenToSplit) {
@@ -5034,7 +5182,7 @@ var PaymentsModule = class _PaymentsModule {
5034
5182
  const transferMode = request.transferMode ?? "instant";
5035
5183
  if (transferMode === "conservative") {
5036
5184
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
5037
- this.log("Executing conservative split...");
5185
+ logger.debug("Payments", "Executing conservative split...");
5038
5186
  const splitExecutor = new TokenSplitExecutor({
5039
5187
  stateTransitionClient: stClient,
5040
5188
  trustBase,
@@ -5062,7 +5210,7 @@ var PaymentsModule = class _PaymentsModule {
5062
5210
  sdkData: JSON.stringify(changeTokenData)
5063
5211
  };
5064
5212
  await this.addToken(changeUiToken);
5065
- this.log(`Conservative split: change token saved: ${changeUiToken.id}`);
5213
+ logger.debug("Payments", `Conservative split: change token saved: ${changeUiToken.id}`);
5066
5214
  await this.deps.transport.sendTokenTransfer(recipientPubkey, {
5067
5215
  sourceToken: JSON.stringify(splitResult.tokenForRecipient.toJSON()),
5068
5216
  transferTx: JSON.stringify(splitResult.recipientTransferTx.toJSON()),
@@ -5076,15 +5224,15 @@ var PaymentsModule = class _PaymentsModule {
5076
5224
  method: "split",
5077
5225
  requestIdHex: splitRequestIdHex
5078
5226
  });
5079
- this.log(`Conservative split transfer completed`);
5227
+ logger.debug("Payments", "Conservative split transfer completed");
5080
5228
  }
5081
5229
  for (const tokenWithAmount of splitPlan.tokensToTransferDirectly) {
5082
5230
  const token = tokenWithAmount.uiToken;
5083
5231
  const commitment = await this.createSdkCommitment(token, recipientAddress, signingService);
5084
- console.log(`[Payments] CONSERVATIVE: Sending direct token ${token.id.slice(0, 8)}... to ${recipientPubkey.slice(0, 8)}...`);
5232
+ logger.debug("Payments", `CONSERVATIVE: Sending direct token ${token.id.slice(0, 8)}... to ${recipientPubkey.slice(0, 8)}...`);
5085
5233
  const submitResponse = await stClient.submitTransferCommitment(commitment);
5086
5234
  if (submitResponse.status !== "SUCCESS" && submitResponse.status !== "REQUEST_ID_EXISTS") {
5087
- throw new Error(`Transfer commitment failed: ${submitResponse.status}`);
5235
+ throw new SphereError(`Transfer commitment failed: ${submitResponse.status}`, "TRANSFER_FAILED");
5088
5236
  }
5089
5237
  const inclusionProof = await (0, import_InclusionProofUtils5.waitInclusionProof)(trustBase, stClient, commitment);
5090
5238
  const transferTx = commitment.toTransaction(inclusionProof);
@@ -5093,7 +5241,7 @@ var PaymentsModule = class _PaymentsModule {
5093
5241
  transferTx: JSON.stringify(transferTx.toJSON()),
5094
5242
  memo: request.memo
5095
5243
  });
5096
- console.log(`[Payments] CONSERVATIVE: Direct token sent successfully`);
5244
+ logger.debug("Payments", "CONSERVATIVE: Direct token sent successfully");
5097
5245
  const requestIdBytes = commitment.requestId;
5098
5246
  const requestIdHex = requestIdBytes instanceof Uint8Array ? Array.from(requestIdBytes).map((b) => b.toString(16).padStart(2, "0")).join("") : String(requestIdBytes);
5099
5247
  result.tokenTransfers.push({
@@ -5101,7 +5249,7 @@ var PaymentsModule = class _PaymentsModule {
5101
5249
  method: "direct",
5102
5250
  requestIdHex
5103
5251
  });
5104
- this.log(`Token ${token.id} sent via CONSERVATIVE, requestId: ${requestIdHex}`);
5252
+ logger.debug("Payments", `Token ${token.id} sent via CONSERVATIVE, requestId: ${requestIdHex}`);
5105
5253
  await this.removeToken(token.id);
5106
5254
  }
5107
5255
  } else {
@@ -5110,7 +5258,7 @@ var PaymentsModule = class _PaymentsModule {
5110
5258
  let changeTokenPlaceholderId = null;
5111
5259
  let builtSplit = null;
5112
5260
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
5113
- this.log("Building instant split bundle...");
5261
+ logger.debug("Payments", "Building instant split bundle...");
5114
5262
  const executor = new InstantSplitExecutor({
5115
5263
  stateTransitionClient: stClient,
5116
5264
  trustBase,
@@ -5144,7 +5292,7 @@ var PaymentsModule = class _PaymentsModule {
5144
5292
  sdkData: JSON.stringify(changeTokenData)
5145
5293
  };
5146
5294
  await this.addToken(uiToken);
5147
- this.log(`Change token saved via background: ${uiToken.id}`);
5295
+ logger.debug("Payments", `Change token saved via background: ${uiToken.id}`);
5148
5296
  },
5149
5297
  onStorageSync: async () => {
5150
5298
  await this.save();
@@ -5152,7 +5300,7 @@ var PaymentsModule = class _PaymentsModule {
5152
5300
  }
5153
5301
  }
5154
5302
  );
5155
- this.log(`Split bundle built: splitGroupId=${builtSplit.splitGroupId}`);
5303
+ logger.debug("Payments", `Split bundle built: splitGroupId=${builtSplit.splitGroupId}`);
5156
5304
  }
5157
5305
  const directCommitments = await Promise.all(
5158
5306
  splitPlan.tokensToTransferDirectly.map(
@@ -5179,8 +5327,9 @@ var PaymentsModule = class _PaymentsModule {
5179
5327
  senderPubkey,
5180
5328
  memo: request.memo
5181
5329
  };
5182
- console.log(
5183
- `[Payments] Sending V6 combined bundle: transfer=${result.id.slice(0, 8)}... split=${!!builtSplit} direct=${directTokenEntries.length}`
5330
+ logger.debug(
5331
+ "Payments",
5332
+ `Sending V6 combined bundle: transfer=${result.id.slice(0, 8)}... split=${!!builtSplit} direct=${directTokenEntries.length}`
5184
5333
  );
5185
5334
  await this.deps.transport.sendTokenTransfer(recipientPubkey, {
5186
5335
  token: JSON.stringify(combinedBundle),
@@ -5188,7 +5337,7 @@ var PaymentsModule = class _PaymentsModule {
5188
5337
  memo: request.memo,
5189
5338
  sender: { transportPubkey: senderPubkey }
5190
5339
  });
5191
- console.log(`[Payments] V6 combined bundle sent successfully`);
5340
+ logger.debug("Payments", "V6 combined bundle sent successfully");
5192
5341
  if (builtSplit) {
5193
5342
  const bgPromise = builtSplit.startBackground();
5194
5343
  this.pendingBackgroundTasks.push(bgPromise);
@@ -5209,11 +5358,11 @@ var PaymentsModule = class _PaymentsModule {
5209
5358
  sdkData: JSON.stringify({ _placeholder: true })
5210
5359
  };
5211
5360
  this.tokens.set(placeholder.id, placeholder);
5212
- this.log(`Placeholder change token created: ${placeholder.id} (${placeholder.amount})`);
5361
+ logger.debug("Payments", `Placeholder change token created: ${placeholder.id} (${placeholder.amount})`);
5213
5362
  }
5214
5363
  for (const commitment of directCommitments) {
5215
5364
  stClient.submitTransferCommitment(commitment).catch(
5216
- (err) => console.error("[Payments] Background commitment submit failed:", err)
5365
+ (err) => logger.error("Payments", "Background commitment submit failed:", err)
5217
5366
  );
5218
5367
  }
5219
5368
  if (splitPlan.requiresSplit && splitPlan.tokenToSplit) {
@@ -5236,7 +5385,7 @@ var PaymentsModule = class _PaymentsModule {
5236
5385
  });
5237
5386
  await this.removeToken(token.id);
5238
5387
  }
5239
- this.log(`V6 combined transfer completed`);
5388
+ logger.debug("Payments", "V6 combined transfer completed");
5240
5389
  }
5241
5390
  result.status = "delivered";
5242
5391
  await this.save();
@@ -5327,11 +5476,11 @@ var PaymentsModule = class _PaymentsModule {
5327
5476
  const signingService = await this.createSigningService();
5328
5477
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5329
5478
  if (!stClient) {
5330
- throw new Error("State transition client not available");
5479
+ throw new SphereError("State transition client not available", "AGGREGATOR_ERROR");
5331
5480
  }
5332
5481
  const trustBase = this.deps.oracle.getTrustBase?.();
5333
5482
  if (!trustBase) {
5334
- throw new Error("Trust base not available");
5483
+ throw new SphereError("Trust base not available", "AGGREGATOR_ERROR");
5335
5484
  }
5336
5485
  const calculator = new TokenSplitCalculator();
5337
5486
  const availableTokens = Array.from(this.tokens.values());
@@ -5341,10 +5490,10 @@ var PaymentsModule = class _PaymentsModule {
5341
5490
  request.coinId
5342
5491
  );
5343
5492
  if (!splitPlan) {
5344
- throw new Error("Insufficient balance");
5493
+ throw new SphereError("Insufficient balance", "INSUFFICIENT_BALANCE");
5345
5494
  }
5346
5495
  if (!splitPlan.requiresSplit || !splitPlan.tokenToSplit) {
5347
- this.log("No split required, falling back to standard send()");
5496
+ logger.debug("Payments", "No split required, falling back to standard send()");
5348
5497
  const result2 = await this.send(request);
5349
5498
  return {
5350
5499
  success: result2.status === "completed",
@@ -5352,7 +5501,7 @@ var PaymentsModule = class _PaymentsModule {
5352
5501
  error: result2.error
5353
5502
  };
5354
5503
  }
5355
- this.log(`InstantSplit: amount=${splitPlan.splitAmount}, remainder=${splitPlan.remainderAmount}`);
5504
+ logger.debug("Payments", `InstantSplit: amount=${splitPlan.splitAmount}, remainder=${splitPlan.remainderAmount}`);
5356
5505
  const tokenToSplit = splitPlan.tokenToSplit.uiToken;
5357
5506
  tokenToSplit.status = "transferring";
5358
5507
  this.tokens.set(tokenToSplit.id, tokenToSplit);
@@ -5390,7 +5539,7 @@ var PaymentsModule = class _PaymentsModule {
5390
5539
  sdkData: JSON.stringify(changeTokenData)
5391
5540
  };
5392
5541
  await this.addToken(uiToken);
5393
- this.log(`Change token saved via background: ${uiToken.id}`);
5542
+ logger.debug("Payments", `Change token saved via background: ${uiToken.id}`);
5394
5543
  },
5395
5544
  onStorageSync: async () => {
5396
5545
  await this.save();
@@ -5445,7 +5594,7 @@ var PaymentsModule = class _PaymentsModule {
5445
5594
  async saveUnconfirmedV5Token(bundle, senderPubkey, deferPersistence = false) {
5446
5595
  const deterministicId = `v5split_${bundle.splitGroupId}`;
5447
5596
  if (this.tokens.has(deterministicId) || this.processedSplitGroupIds.has(bundle.splitGroupId)) {
5448
- console.log(`[Payments] V5 bundle ${bundle.splitGroupId.slice(0, 12)}... already processed, skipping`);
5597
+ logger.debug("Payments", `V5 bundle ${bundle.splitGroupId.slice(0, 12)}... already processed, skipping`);
5449
5598
  return null;
5450
5599
  }
5451
5600
  const registry = TokenRegistry.getInstance();
@@ -5495,7 +5644,7 @@ var PaymentsModule = class _PaymentsModule {
5495
5644
  const nostrTokenId = extractTokenIdFromSdkData(sdkData);
5496
5645
  const nostrStateHash = extractStateHashFromSdkData(sdkData);
5497
5646
  if (nostrTokenId && nostrStateHash && this.isStateTombstoned(nostrTokenId, nostrStateHash)) {
5498
- this.log(`NOSTR-FIRST: Rejecting tombstoned token ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`);
5647
+ logger.debug("Payments", `NOSTR-FIRST: Rejecting tombstoned token ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`);
5499
5648
  return null;
5500
5649
  }
5501
5650
  if (nostrTokenId) {
@@ -5504,14 +5653,16 @@ var PaymentsModule = class _PaymentsModule {
5504
5653
  if (existingTokenId !== nostrTokenId) continue;
5505
5654
  const existingStateHash = extractStateHashFromSdkData(existing.sdkData);
5506
5655
  if (nostrStateHash && existingStateHash === nostrStateHash) {
5507
- console.log(
5508
- `[Payments] NOSTR-FIRST: Skipping duplicate token state ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`
5656
+ logger.debug(
5657
+ "Payments",
5658
+ `NOSTR-FIRST: Skipping duplicate token state ${nostrTokenId.slice(0, 8)}..._${nostrStateHash.slice(0, 8)}...`
5509
5659
  );
5510
5660
  return null;
5511
5661
  }
5512
5662
  if (!skipGenesisDedup) {
5513
- console.log(
5514
- `[Payments] NOSTR-FIRST: Skipping replay of finalized token ${nostrTokenId.slice(0, 8)}...`
5663
+ logger.debug(
5664
+ "Payments",
5665
+ `NOSTR-FIRST: Skipping replay of finalized token ${nostrTokenId.slice(0, 8)}...`
5515
5666
  );
5516
5667
  return null;
5517
5668
  }
@@ -5543,7 +5694,7 @@ var PaymentsModule = class _PaymentsModule {
5543
5694
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5544
5695
  if (stClient) {
5545
5696
  const response = await stClient.submitTransferCommitment(commitment);
5546
- this.log(`NOSTR-FIRST recipient commitment submit: ${response.status}`);
5697
+ logger.debug("Payments", `NOSTR-FIRST recipient commitment submit: ${response.status}`);
5547
5698
  }
5548
5699
  }
5549
5700
  this.addProofPollingJob({
@@ -5558,7 +5709,7 @@ var PaymentsModule = class _PaymentsModule {
5558
5709
  }
5559
5710
  });
5560
5711
  } catch (err) {
5561
- console.error("[Payments] Failed to parse commitment for proof polling:", err);
5712
+ logger.error("Payments", "Failed to parse commitment for proof polling:", err);
5562
5713
  }
5563
5714
  return token;
5564
5715
  }
@@ -5580,11 +5731,12 @@ var PaymentsModule = class _PaymentsModule {
5580
5731
  await this.loadedPromise;
5581
5732
  }
5582
5733
  if (this.processedCombinedTransferIds.has(bundle.transferId)) {
5583
- console.log(`[Payments] V6 combined transfer ${bundle.transferId.slice(0, 12)}... already processed, skipping`);
5734
+ logger.debug("Payments", `V6 combined transfer ${bundle.transferId.slice(0, 12)}... already processed, skipping`);
5584
5735
  return;
5585
5736
  }
5586
- console.log(
5587
- `[Payments] Processing V6 combined transfer ${bundle.transferId.slice(0, 12)}... (split=${!!bundle.splitBundle}, direct=${bundle.directTokens.length})`
5737
+ logger.debug(
5738
+ "Payments",
5739
+ `Processing V6 combined transfer ${bundle.transferId.slice(0, 12)}... (split=${!!bundle.splitBundle}, direct=${bundle.directTokens.length})`
5588
5740
  );
5589
5741
  const allTokens = [];
5590
5742
  const tokenBreakdown = [];
@@ -5598,7 +5750,7 @@ var PaymentsModule = class _PaymentsModule {
5598
5750
  allTokens.push(splitToken);
5599
5751
  tokenBreakdown.push({ id: splitToken.id, amount: splitToken.amount, source: "split" });
5600
5752
  } else {
5601
- console.warn(`[Payments] V6: split token was deduped/failed \u2014 amount=${bundle.splitBundle.amount}`);
5753
+ logger.warn("Payments", `V6: split token was deduped/failed \u2014 amount=${bundle.splitBundle.amount}`);
5602
5754
  }
5603
5755
  }
5604
5756
  const directResults = await Promise.all(
@@ -5613,13 +5765,14 @@ var PaymentsModule = class _PaymentsModule {
5613
5765
  tokenBreakdown.push({ id: token.id, amount: token.amount, source: "direct" });
5614
5766
  } else {
5615
5767
  const entry = bundle.directTokens[i];
5616
- console.warn(
5617
- `[Payments] V6: direct token #${i} dropped (amount=${entry.amount}, tokenId=${entry.tokenId?.slice(0, 12) ?? "N/A"})`
5768
+ logger.warn(
5769
+ "Payments",
5770
+ `V6: direct token #${i} dropped (amount=${entry.amount}, tokenId=${entry.tokenId?.slice(0, 12) ?? "N/A"})`
5618
5771
  );
5619
5772
  }
5620
5773
  }
5621
5774
  if (allTokens.length === 0) {
5622
- console.log(`[Payments] V6 combined transfer: all tokens deduped, nothing to save`);
5775
+ logger.debug("Payments", "V6 combined transfer: all tokens deduped, nothing to save");
5623
5776
  return;
5624
5777
  }
5625
5778
  this.processedCombinedTransferIds.add(bundle.transferId);
@@ -5635,7 +5788,7 @@ var PaymentsModule = class _PaymentsModule {
5635
5788
  import_TransferCommitment4.TransferCommitment.fromJSON(commitment).then(
5636
5789
  (c) => stClient.submitTransferCommitment(c)
5637
5790
  ).catch(
5638
- (err) => console.error("[Payments] V6 background commitment submit failed:", err)
5791
+ (err) => logger.error("Payments", "V6 background commitment submit failed:", err)
5639
5792
  );
5640
5793
  }
5641
5794
  }
@@ -5662,8 +5815,7 @@ var PaymentsModule = class _PaymentsModule {
5662
5815
  tokenIds: tokenBreakdown
5663
5816
  });
5664
5817
  if (bundle.splitBundle) {
5665
- this.resolveUnconfirmed().catch(() => {
5666
- });
5818
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
5667
5819
  this.scheduleResolveUnconfirmed();
5668
5820
  }
5669
5821
  }
@@ -5741,8 +5893,7 @@ var PaymentsModule = class _PaymentsModule {
5741
5893
  receivedAt: Date.now()
5742
5894
  });
5743
5895
  await this.save();
5744
- this.resolveUnconfirmed().catch(() => {
5745
- });
5896
+ this.resolveUnconfirmed().catch((err) => logger.debug("Payments", "resolveUnconfirmed failed", err));
5746
5897
  this.scheduleResolveUnconfirmed();
5747
5898
  return { success: true, durationMs: 0 };
5748
5899
  } catch (error) {
@@ -5763,11 +5914,11 @@ var PaymentsModule = class _PaymentsModule {
5763
5914
  const signingService = await this.createSigningService();
5764
5915
  const stClient = this.deps.oracle.getStateTransitionClient?.();
5765
5916
  if (!stClient) {
5766
- throw new Error("State transition client not available");
5917
+ throw new SphereError("State transition client not available", "AGGREGATOR_ERROR");
5767
5918
  }
5768
5919
  const trustBase = this.deps.oracle.getTrustBase?.();
5769
5920
  if (!trustBase) {
5770
- throw new Error("Trust base not available");
5921
+ throw new SphereError("Trust base not available", "AGGREGATOR_ERROR");
5771
5922
  }
5772
5923
  const devMode = this.deps.oracle.isDevMode?.() ?? false;
5773
5924
  const processor = new InstantSplitProcessor({
@@ -5790,10 +5941,10 @@ var PaymentsModule = class _PaymentsModule {
5790
5941
  if (proxy.address === proxyAddress) {
5791
5942
  return nametagToken;
5792
5943
  }
5793
- this.log(`Nametag PROXY address mismatch: ${proxy.address} !== ${proxyAddress}`);
5944
+ logger.debug("Payments", `Nametag PROXY address mismatch: ${proxy.address} !== ${proxyAddress}`);
5794
5945
  return null;
5795
5946
  } catch (err) {
5796
- this.log("Failed to parse nametag token:", err);
5947
+ logger.debug("Payments", "Failed to parse nametag token:", err);
5797
5948
  return null;
5798
5949
  }
5799
5950
  }
@@ -5901,7 +6052,7 @@ var PaymentsModule = class _PaymentsModule {
5901
6052
  status: "pending"
5902
6053
  };
5903
6054
  this.outgoingPaymentRequests.set(requestId2, outgoingRequest);
5904
- this.log(`Payment request sent: ${eventId}`);
6055
+ logger.debug("Payments", `Payment request sent: ${eventId}`);
5905
6056
  return {
5906
6057
  success: true,
5907
6058
  requestId: requestId2,
@@ -5909,7 +6060,7 @@ var PaymentsModule = class _PaymentsModule {
5909
6060
  };
5910
6061
  } catch (error) {
5911
6062
  const errorMsg = error instanceof Error ? error.message : String(error);
5912
- this.log(`Failed to send payment request: ${errorMsg}`);
6063
+ logger.debug("Payments", `Failed to send payment request: ${errorMsg}`);
5913
6064
  return {
5914
6065
  success: false,
5915
6066
  error: errorMsg
@@ -5998,10 +6149,10 @@ var PaymentsModule = class _PaymentsModule {
5998
6149
  async payPaymentRequest(requestId2, memo) {
5999
6150
  const request = this.paymentRequests.find((r) => r.id === requestId2);
6000
6151
  if (!request) {
6001
- throw new Error(`Payment request not found: ${requestId2}`);
6152
+ throw new SphereError(`Payment request not found: ${requestId2}`, "VALIDATION_ERROR");
6002
6153
  }
6003
6154
  if (request.status !== "pending" && request.status !== "accepted") {
6004
- throw new Error(`Payment request is not pending or accepted: ${request.status}`);
6155
+ throw new SphereError(`Payment request is not pending or accepted: ${request.status}`, "VALIDATION_ERROR");
6005
6156
  }
6006
6157
  this.updatePaymentRequestStatus(requestId2, "accepted");
6007
6158
  try {
@@ -6056,10 +6207,10 @@ var PaymentsModule = class _PaymentsModule {
6056
6207
  try {
6057
6208
  handler(request);
6058
6209
  } catch (error) {
6059
- this.log("Payment request handler error:", error);
6210
+ logger.debug("Payments", "Payment request handler error:", error);
6060
6211
  }
6061
6212
  }
6062
- this.log(`Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
6213
+ logger.debug("Payments", `Incoming payment request: ${request.id} for ${request.amount} ${request.symbol}`);
6063
6214
  }
6064
6215
  // ===========================================================================
6065
6216
  // Public API - Outgoing Payment Requests
@@ -6178,10 +6329,10 @@ var PaymentsModule = class _PaymentsModule {
6178
6329
  try {
6179
6330
  handler(response);
6180
6331
  } catch (error) {
6181
- this.log("Payment request response handler error:", error);
6332
+ logger.debug("Payments", "Payment request response handler error:", error);
6182
6333
  }
6183
6334
  }
6184
- this.log(`Received payment request response: ${response.id} type: ${response.responseType}`);
6335
+ logger.debug("Payments", `Received payment request response: ${response.id} type: ${response.responseType}`);
6185
6336
  }
6186
6337
  /**
6187
6338
  * Send a response to a payment request (used internally by accept/reject/pay methods)
@@ -6190,7 +6341,7 @@ var PaymentsModule = class _PaymentsModule {
6190
6341
  const request = this.paymentRequests.find((r) => r.id === requestId2);
6191
6342
  if (!request) return;
6192
6343
  if (!this.deps?.transport.sendPaymentRequestResponse) {
6193
- this.log("Transport does not support sendPaymentRequestResponse");
6344
+ logger.debug("Payments", "Transport does not support sendPaymentRequestResponse");
6194
6345
  return;
6195
6346
  }
6196
6347
  try {
@@ -6201,9 +6352,9 @@ var PaymentsModule = class _PaymentsModule {
6201
6352
  transferId
6202
6353
  };
6203
6354
  await this.deps.transport.sendPaymentRequestResponse(request.senderPubkey, payload);
6204
- this.log(`Sent payment request response: ${responseType} for ${requestId2}`);
6355
+ logger.debug("Payments", `Sent payment request response: ${responseType} for ${requestId2}`);
6205
6356
  } catch (error) {
6206
- this.log("Failed to send payment request response:", error);
6357
+ logger.debug("Payments", "Failed to send payment request response:", error);
6207
6358
  }
6208
6359
  }
6209
6360
  // ===========================================================================
@@ -6227,7 +6378,7 @@ var PaymentsModule = class _PaymentsModule {
6227
6378
  async receive(options, callback) {
6228
6379
  this.ensureInitialized();
6229
6380
  if (!this.deps.transport.fetchPendingEvents) {
6230
- throw new Error("Transport provider does not support fetchPendingEvents");
6381
+ throw new SphereError("Transport provider does not support fetchPendingEvents", "TRANSPORT_ERROR");
6231
6382
  }
6232
6383
  const opts = options ?? {};
6233
6384
  const tokensBefore = new Set(this.tokens.keys());
@@ -6374,7 +6525,7 @@ var PaymentsModule = class _PaymentsModule {
6374
6525
  });
6375
6526
  }
6376
6527
  } catch (error) {
6377
- console.warn("[Payments] Failed to fetch prices, returning assets without price data:", error);
6528
+ logger.warn("Payments", "Failed to fetch prices, returning assets without price data:", error);
6378
6529
  }
6379
6530
  return rawAssets;
6380
6531
  }
@@ -6496,24 +6647,24 @@ var PaymentsModule = class _PaymentsModule {
6496
6647
  const stClient = this.deps.oracle.getStateTransitionClient?.();
6497
6648
  const trustBase = this.deps.oracle.getTrustBase?.();
6498
6649
  if (!stClient || !trustBase) {
6499
- console.log(`[V5-RESOLVE] resolveUnconfirmed: EARLY EXIT \u2014 stClient=${!!stClient} trustBase=${!!trustBase}`);
6650
+ logger.debug("Payments", `[V5-RESOLVE] resolveUnconfirmed: EARLY EXIT \u2014 stClient=${!!stClient} trustBase=${!!trustBase}`);
6500
6651
  return result;
6501
6652
  }
6502
6653
  const signingService = await this.createSigningService();
6503
6654
  const submittedCount = Array.from(this.tokens.values()).filter((t) => t.status === "submitted").length;
6504
- console.log(`[V5-RESOLVE] resolveUnconfirmed: ${submittedCount} submitted token(s) to process`);
6655
+ logger.debug("Payments", `[V5-RESOLVE] resolveUnconfirmed: ${submittedCount} submitted token(s) to process`);
6505
6656
  for (const [tokenId, token] of this.tokens) {
6506
6657
  if (token.status !== "submitted") continue;
6507
6658
  const pending2 = this.parsePendingFinalization(token.sdkData);
6508
6659
  if (!pending2) {
6509
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 16)}: no pending finalization metadata, skipping`);
6660
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 16)}: no pending finalization metadata, skipping`);
6510
6661
  result.stillPending++;
6511
6662
  continue;
6512
6663
  }
6513
6664
  if (pending2.type === "v5_bundle") {
6514
- console.log(`[V5-RESOLVE] Processing ${tokenId.slice(0, 16)}... stage=${pending2.stage} attempt=${pending2.attemptCount}`);
6665
+ logger.debug("Payments", `[V5-RESOLVE] Processing ${tokenId.slice(0, 16)}... stage=${pending2.stage} attempt=${pending2.attemptCount}`);
6515
6666
  const progress = await this.resolveV5Token(tokenId, token, pending2, stClient, trustBase, signingService);
6516
- console.log(`[V5-RESOLVE] Result for ${tokenId.slice(0, 16)}...: ${progress} (stage now: ${pending2.stage})`);
6667
+ logger.debug("Payments", `[V5-RESOLVE] Result for ${tokenId.slice(0, 16)}...: ${progress} (stage now: ${pending2.stage})`);
6517
6668
  result.details.push({ tokenId, stage: pending2.stage, status: progress });
6518
6669
  if (progress === "resolved") result.resolved++;
6519
6670
  else if (progress === "failed") result.failed++;
@@ -6521,7 +6672,7 @@ var PaymentsModule = class _PaymentsModule {
6521
6672
  }
6522
6673
  }
6523
6674
  if (result.resolved > 0 || result.failed > 0 || result.stillPending > 0) {
6524
- console.log(`[V5-RESOLVE] Saving: resolved=${result.resolved} failed=${result.failed} stillPending=${result.stillPending}`);
6675
+ logger.debug("Payments", `[V5-RESOLVE] Saving: resolved=${result.resolved} failed=${result.failed} stillPending=${result.stillPending}`);
6525
6676
  await this.save();
6526
6677
  }
6527
6678
  return result;
@@ -6537,19 +6688,19 @@ var PaymentsModule = class _PaymentsModule {
6537
6688
  (t) => t.status === "submitted"
6538
6689
  );
6539
6690
  if (!hasUnconfirmed) {
6540
- console.log(`[V5-RESOLVE] scheduleResolveUnconfirmed: no submitted tokens, not starting timer`);
6691
+ logger.debug("Payments", "[V5-RESOLVE] scheduleResolveUnconfirmed: no submitted tokens, not starting timer");
6541
6692
  return;
6542
6693
  }
6543
- console.log(`[V5-RESOLVE] scheduleResolveUnconfirmed: starting periodic retry (every ${_PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS}ms)`);
6694
+ logger.debug("Payments", `[V5-RESOLVE] scheduleResolveUnconfirmed: starting periodic retry (every ${_PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS}ms)`);
6544
6695
  this.resolveUnconfirmedTimer = setInterval(async () => {
6545
6696
  try {
6546
6697
  const result = await this.resolveUnconfirmed();
6547
6698
  if (result.stillPending === 0) {
6548
- console.log(`[V5-RESOLVE] All tokens resolved, stopping periodic retry`);
6699
+ logger.debug("Payments", "[V5-RESOLVE] All tokens resolved, stopping periodic retry");
6549
6700
  this.stopResolveUnconfirmedPolling();
6550
6701
  }
6551
6702
  } catch (err) {
6552
- console.log(`[V5-RESOLVE] Periodic retry error:`, err);
6703
+ logger.debug("Payments", "[V5-RESOLVE] Periodic retry error:", err);
6553
6704
  }
6554
6705
  }, _PaymentsModule.RESOLVE_UNCONFIRMED_INTERVAL_MS);
6555
6706
  }
@@ -6571,57 +6722,57 @@ var PaymentsModule = class _PaymentsModule {
6571
6722
  pending2.lastAttemptAt = Date.now();
6572
6723
  try {
6573
6724
  if (pending2.stage === "RECEIVED") {
6574
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: RECEIVED \u2192 submitting mint commitment...`);
6725
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: RECEIVED \u2192 submitting mint commitment...`);
6575
6726
  const mintDataJson = JSON.parse(bundle.recipientMintData);
6576
6727
  const mintData = await import_MintTransactionData3.MintTransactionData.fromJSON(mintDataJson);
6577
6728
  const mintCommitment = await import_MintCommitment3.MintCommitment.create(mintData);
6578
6729
  const mintResponse = await stClient.submitMintCommitment(mintCommitment);
6579
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint response status=${mintResponse.status}`);
6730
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint response status=${mintResponse.status}`);
6580
6731
  if (mintResponse.status !== "SUCCESS" && mintResponse.status !== "REQUEST_ID_EXISTS") {
6581
- throw new Error(`Mint submission failed: ${mintResponse.status}`);
6732
+ throw new SphereError(`Mint submission failed: ${mintResponse.status}`, "TRANSFER_FAILED");
6582
6733
  }
6583
6734
  pending2.stage = "MINT_SUBMITTED";
6584
6735
  this.updatePendingFinalization(token, pending2);
6585
6736
  }
6586
6737
  if (pending2.stage === "MINT_SUBMITTED") {
6587
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_SUBMITTED \u2192 checking mint proof...`);
6738
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_SUBMITTED \u2192 checking mint proof...`);
6588
6739
  const mintDataJson = JSON.parse(bundle.recipientMintData);
6589
6740
  const mintData = await import_MintTransactionData3.MintTransactionData.fromJSON(mintDataJson);
6590
6741
  const mintCommitment = await import_MintCommitment3.MintCommitment.create(mintData);
6591
6742
  const proof = await this.quickProofCheck(stClient, trustBase, mintCommitment);
6592
6743
  if (!proof) {
6593
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof not yet available, staying MINT_SUBMITTED`);
6744
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof not yet available, staying MINT_SUBMITTED`);
6594
6745
  this.updatePendingFinalization(token, pending2);
6595
6746
  return "pending";
6596
6747
  }
6597
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof obtained!`);
6748
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: mint proof obtained!`);
6598
6749
  pending2.mintProofJson = JSON.stringify(proof);
6599
6750
  pending2.stage = "MINT_PROVEN";
6600
6751
  this.updatePendingFinalization(token, pending2);
6601
6752
  }
6602
6753
  if (pending2.stage === "MINT_PROVEN") {
6603
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_PROVEN \u2192 submitting transfer commitment...`);
6754
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: MINT_PROVEN \u2192 submitting transfer commitment...`);
6604
6755
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
6605
6756
  const transferCommitment = await import_TransferCommitment4.TransferCommitment.fromJSON(transferCommitmentJson);
6606
6757
  const transferResponse = await stClient.submitTransferCommitment(transferCommitment);
6607
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer response status=${transferResponse.status}`);
6758
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer response status=${transferResponse.status}`);
6608
6759
  if (transferResponse.status !== "SUCCESS" && transferResponse.status !== "REQUEST_ID_EXISTS") {
6609
- throw new Error(`Transfer submission failed: ${transferResponse.status}`);
6760
+ throw new SphereError(`Transfer submission failed: ${transferResponse.status}`, "TRANSFER_FAILED");
6610
6761
  }
6611
6762
  pending2.stage = "TRANSFER_SUBMITTED";
6612
6763
  this.updatePendingFinalization(token, pending2);
6613
6764
  }
6614
6765
  if (pending2.stage === "TRANSFER_SUBMITTED") {
6615
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: TRANSFER_SUBMITTED \u2192 checking transfer proof...`);
6766
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: TRANSFER_SUBMITTED \u2192 checking transfer proof...`);
6616
6767
  const transferCommitmentJson = JSON.parse(bundle.transferCommitment);
6617
6768
  const transferCommitment = await import_TransferCommitment4.TransferCommitment.fromJSON(transferCommitmentJson);
6618
6769
  const proof = await this.quickProofCheck(stClient, trustBase, transferCommitment);
6619
6770
  if (!proof) {
6620
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof not yet available, staying TRANSFER_SUBMITTED`);
6771
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof not yet available, staying TRANSFER_SUBMITTED`);
6621
6772
  this.updatePendingFinalization(token, pending2);
6622
6773
  return "pending";
6623
6774
  }
6624
- console.log(`[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof obtained! Finalizing...`);
6775
+ logger.debug("Payments", `[V5-RESOLVE] ${tokenId.slice(0, 12)}: transfer proof obtained! Finalizing...`);
6625
6776
  const finalizedToken = await this.finalizeFromV5Bundle(bundle, pending2, signingService, stClient, trustBase);
6626
6777
  const confirmedToken = {
6627
6778
  id: token.id,
@@ -6643,12 +6794,12 @@ var PaymentsModule = class _PaymentsModule {
6643
6794
  tokens: [confirmedToken],
6644
6795
  tokenTransfers: []
6645
6796
  });
6646
- this.log(`V5 token resolved: ${tokenId.slice(0, 8)}...`);
6797
+ logger.debug("Payments", `V5 token resolved: ${tokenId.slice(0, 8)}...`);
6647
6798
  return "resolved";
6648
6799
  }
6649
6800
  return "pending";
6650
6801
  } catch (error) {
6651
- console.error(`[Payments] resolveV5Token failed for ${tokenId.slice(0, 8)}:`, error);
6802
+ logger.error("Payments", `resolveV5Token failed for ${tokenId.slice(0, 8)}:`, error);
6652
6803
  if (pending2.attemptCount > 50) {
6653
6804
  token.status = "invalid";
6654
6805
  token.updatedAt = Date.now();
@@ -6785,19 +6936,19 @@ var PaymentsModule = class _PaymentsModule {
6785
6936
  }
6786
6937
  if (pendingTokens.length > 0) {
6787
6938
  const json = JSON.stringify(pendingTokens);
6788
- this.log(`[V5-PERSIST] Saving ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")} (${json.length} bytes)`);
6939
+ logger.debug("Payments", `[V5-PERSIST] Saving ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")} (${json.length} bytes)`);
6789
6940
  await this.deps.storage.set(
6790
6941
  STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS,
6791
6942
  json
6792
6943
  );
6793
6944
  const verify = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS);
6794
6945
  if (!verify) {
6795
- console.error("[Payments][V5-PERSIST] CRITICAL: KV write succeeded but read-back is empty!");
6946
+ logger.error("Payments", "[V5-PERSIST] CRITICAL: KV write succeeded but read-back is empty!");
6796
6947
  } else {
6797
- this.log(`[V5-PERSIST] Verified: read-back ${verify.length} bytes`);
6948
+ logger.debug("Payments", `[V5-PERSIST] Verified: read-back ${verify.length} bytes`);
6798
6949
  }
6799
6950
  } else {
6800
- this.log(`[V5-PERSIST] No pending V5 tokens to save (total tokens: ${this.tokens.size}), clearing KV`);
6951
+ logger.debug("Payments", `[V5-PERSIST] No pending V5 tokens to save (total tokens: ${this.tokens.size}), clearing KV`);
6801
6952
  await this.deps.storage.set(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS, "");
6802
6953
  }
6803
6954
  }
@@ -6807,21 +6958,21 @@ var PaymentsModule = class _PaymentsModule {
6807
6958
  */
6808
6959
  async loadPendingV5Tokens() {
6809
6960
  const data = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_V5_TOKENS);
6810
- this.log(`[V5-PERSIST] loadPendingV5Tokens: KV data = ${data ? `${data.length} bytes` : "null/empty"}`);
6961
+ logger.debug("Payments", `[V5-PERSIST] loadPendingV5Tokens: KV data = ${data ? `${data.length} bytes` : "null/empty"}`);
6811
6962
  if (!data) return;
6812
6963
  try {
6813
6964
  const pendingTokens = JSON.parse(data);
6814
- this.log(`[V5-PERSIST] Parsed ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")}`);
6965
+ logger.debug("Payments", `[V5-PERSIST] Parsed ${pendingTokens.length} pending V5 token(s): ${pendingTokens.map((t) => t.id.slice(0, 16)).join(", ")}`);
6815
6966
  for (const token of pendingTokens) {
6816
6967
  if (!this.tokens.has(token.id)) {
6817
6968
  this.tokens.set(token.id, token);
6818
- this.log(`[V5-PERSIST] Restored token ${token.id.slice(0, 16)} (status=${token.status})`);
6969
+ logger.debug("Payments", `[V5-PERSIST] Restored token ${token.id.slice(0, 16)} (status=${token.status})`);
6819
6970
  } else {
6820
- this.log(`[V5-PERSIST] Token ${token.id.slice(0, 16)} already in map, skipping`);
6971
+ logger.debug("Payments", `[V5-PERSIST] Token ${token.id.slice(0, 16)} already in map, skipping`);
6821
6972
  }
6822
6973
  }
6823
6974
  } catch (err) {
6824
- console.error("[Payments][V5-PERSIST] Failed to parse pending V5 tokens:", err);
6975
+ logger.error("Payments", "[V5-PERSIST] Failed to parse pending V5 tokens:", err);
6825
6976
  }
6826
6977
  }
6827
6978
  /**
@@ -6874,13 +7025,13 @@ var PaymentsModule = class _PaymentsModule {
6874
7025
  const incomingStateHash = extractStateHashFromSdkData(token.sdkData);
6875
7026
  const incomingStateKey = incomingTokenId && incomingStateHash ? createTokenStateKey(incomingTokenId, incomingStateHash) : null;
6876
7027
  if (incomingTokenId && incomingStateHash && this.isStateTombstoned(incomingTokenId, incomingStateHash)) {
6877
- this.log(`Rejecting tombstoned token: ${incomingTokenId.slice(0, 8)}..._${incomingStateHash.slice(0, 8)}...`);
7028
+ logger.debug("Payments", `Rejecting tombstoned token: ${incomingTokenId.slice(0, 8)}..._${incomingStateHash.slice(0, 8)}...`);
6878
7029
  return false;
6879
7030
  }
6880
7031
  if (incomingStateKey) {
6881
7032
  for (const [_existingId, existing] of this.tokens) {
6882
7033
  if (isSameTokenState(existing, token)) {
6883
- this.log(`Duplicate token state ignored: ${incomingTokenId?.slice(0, 8)}..._${incomingStateHash?.slice(0, 8)}...`);
7034
+ logger.debug("Payments", `Duplicate token state ignored: ${incomingTokenId?.slice(0, 8)}..._${incomingStateHash?.slice(0, 8)}...`);
6884
7035
  return false;
6885
7036
  }
6886
7037
  }
@@ -6892,19 +7043,19 @@ var PaymentsModule = class _PaymentsModule {
6892
7043
  continue;
6893
7044
  }
6894
7045
  if (existing.status === "spent" || existing.status === "invalid") {
6895
- this.log(`Replacing spent/invalid token ${incomingTokenId?.slice(0, 8)}...`);
7046
+ logger.debug("Payments", `Replacing spent/invalid token ${incomingTokenId?.slice(0, 8)}...`);
6896
7047
  this.tokens.delete(existingId);
6897
7048
  break;
6898
7049
  }
6899
7050
  if (incomingStateHash && existingStateHash && incomingStateHash !== existingStateHash) {
6900
- this.log(`Token ${incomingTokenId?.slice(0, 8)}... state updated: ${existingStateHash.slice(0, 8)}... -> ${incomingStateHash.slice(0, 8)}...`);
7051
+ logger.debug("Payments", `Token ${incomingTokenId?.slice(0, 8)}... state updated: ${existingStateHash.slice(0, 8)}... -> ${incomingStateHash.slice(0, 8)}...`);
6901
7052
  await this.archiveToken(existing);
6902
7053
  this.tokens.delete(existingId);
6903
7054
  break;
6904
7055
  }
6905
7056
  if (!incomingStateHash || !existingStateHash) {
6906
7057
  if (existingId !== token.id) {
6907
- this.log(`Token ${incomingTokenId?.slice(0, 8)}... .id changed, replacing`);
7058
+ logger.debug("Payments", `Token ${incomingTokenId?.slice(0, 8)}... .id changed, replacing`);
6908
7059
  await this.archiveToken(existing);
6909
7060
  this.tokens.delete(existingId);
6910
7061
  break;
@@ -6915,7 +7066,7 @@ var PaymentsModule = class _PaymentsModule {
6915
7066
  this.tokens.set(token.id, token);
6916
7067
  await this.archiveToken(token);
6917
7068
  await this.save();
6918
- this.log(`Added token ${token.id}, total: ${this.tokens.size}`);
7069
+ logger.debug("Payments", `Added token ${token.id}, total: ${this.tokens.size}`);
6919
7070
  return true;
6920
7071
  }
6921
7072
  /**
@@ -6945,7 +7096,7 @@ var PaymentsModule = class _PaymentsModule {
6945
7096
  }
6946
7097
  await this.archiveToken(token);
6947
7098
  await this.save();
6948
- this.log(`Updated token ${token.id}`);
7099
+ logger.debug("Payments", `Updated token ${token.id}`);
6949
7100
  }
6950
7101
  /**
6951
7102
  * Remove a token from the wallet.
@@ -6968,10 +7119,10 @@ var PaymentsModule = class _PaymentsModule {
6968
7119
  );
6969
7120
  if (!alreadyTombstoned) {
6970
7121
  this.tombstones.push(tombstone);
6971
- this.log(`Created tombstone for ${tombstone.tokenId.slice(0, 8)}..._${tombstone.stateHash.slice(0, 8)}...`);
7122
+ logger.debug("Payments", `Created tombstone for ${tombstone.tokenId.slice(0, 8)}..._${tombstone.stateHash.slice(0, 8)}...`);
6972
7123
  }
6973
7124
  } else {
6974
- this.log(`Warning: Could not create tombstone for token ${tokenId.slice(0, 8)}... (missing tokenId or stateHash)`);
7125
+ logger.debug("Payments", `Warning: Could not create tombstone for token ${tokenId.slice(0, 8)}... (missing tokenId or stateHash)`);
6975
7126
  }
6976
7127
  this.tokens.delete(tokenId);
6977
7128
  await this.save();
@@ -7028,7 +7179,7 @@ var PaymentsModule = class _PaymentsModule {
7028
7179
  }
7029
7180
  for (const token of tokensToRemove) {
7030
7181
  this.tokens.delete(token.id);
7031
- this.log(`Removed tombstoned token ${token.id.slice(0, 8)}...`);
7182
+ logger.debug("Payments", `Removed tombstoned token ${token.id.slice(0, 8)}...`);
7032
7183
  removedCount++;
7033
7184
  }
7034
7185
  for (const remoteTombstone of remoteTombstones) {
@@ -7054,7 +7205,7 @@ var PaymentsModule = class _PaymentsModule {
7054
7205
  this.tombstones = pruneTombstonesByAge(this.tombstones, maxAge);
7055
7206
  if (this.tombstones.length < originalCount) {
7056
7207
  await this.save();
7057
- this.log(`Pruned tombstones from ${originalCount} to ${this.tombstones.length}`);
7208
+ logger.debug("Payments", `Pruned tombstones from ${originalCount} to ${this.tombstones.length}`);
7058
7209
  }
7059
7210
  }
7060
7211
  // ===========================================================================
@@ -7126,7 +7277,7 @@ var PaymentsModule = class _PaymentsModule {
7126
7277
  const originalCount = this.archivedTokens.size;
7127
7278
  this.archivedTokens = pruneMapByCount(this.archivedTokens, maxCount);
7128
7279
  await this.save();
7129
- this.log(`Pruned archived tokens from ${originalCount} to ${this.archivedTokens.size}`);
7280
+ logger.debug("Payments", `Pruned archived tokens from ${originalCount} to ${this.archivedTokens.size}`);
7130
7281
  }
7131
7282
  // ===========================================================================
7132
7283
  // Public API - Forked Tokens
@@ -7155,7 +7306,7 @@ var PaymentsModule = class _PaymentsModule {
7155
7306
  const key = `${tokenId}_${stateHash}`;
7156
7307
  if (this.forkedTokens.has(key)) return;
7157
7308
  this.forkedTokens.set(key, txfToken);
7158
- this.log(`Stored forked token ${tokenId.slice(0, 8)}... state ${stateHash.slice(0, 12)}...`);
7309
+ logger.debug("Payments", `Stored forked token ${tokenId.slice(0, 8)}... state ${stateHash.slice(0, 12)}...`);
7159
7310
  await this.save();
7160
7311
  }
7161
7312
  /**
@@ -7187,7 +7338,7 @@ var PaymentsModule = class _PaymentsModule {
7187
7338
  const originalCount = this.forkedTokens.size;
7188
7339
  this.forkedTokens = pruneMapByCount(this.forkedTokens, maxCount);
7189
7340
  await this.save();
7190
- this.log(`Pruned forked tokens from ${originalCount} to ${this.forkedTokens.size}`);
7341
+ logger.debug("Payments", `Pruned forked tokens from ${originalCount} to ${this.forkedTokens.size}`);
7191
7342
  }
7192
7343
  // ===========================================================================
7193
7344
  // Public API - Transaction History
@@ -7267,7 +7418,7 @@ var PaymentsModule = class _PaymentsModule {
7267
7418
  const imported = await provider.importHistoryEntries?.(records) ?? 0;
7268
7419
  if (imported > 0) {
7269
7420
  this._historyCache = await provider.getHistoryEntries();
7270
- this.log(`Migrated ${imported} history entries from KV to history store`);
7421
+ logger.debug("Payments", `Migrated ${imported} history entries from KV to history store`);
7271
7422
  }
7272
7423
  await this.deps.storage.remove(STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY);
7273
7424
  } catch {
@@ -7343,7 +7494,7 @@ var PaymentsModule = class _PaymentsModule {
7343
7494
  this.nametags.push(nametag);
7344
7495
  }
7345
7496
  await this.save();
7346
- this.log(`Nametag set: ${nametag.name}`);
7497
+ logger.debug("Payments", `Nametag set: ${nametag.name}`);
7347
7498
  }
7348
7499
  /**
7349
7500
  * Get the current (first) nametag data.
@@ -7392,7 +7543,7 @@ var PaymentsModule = class _PaymentsModule {
7392
7543
  const parsed = parseTxfStorageData(result.data);
7393
7544
  if (parsed.nametags.length > 0) {
7394
7545
  this.nametags = parsed.nametags;
7395
- this.log(`Reloaded ${parsed.nametags.length} nametag(s) from storage`);
7546
+ logger.debug("Payments", `Reloaded ${parsed.nametags.length} nametag(s) from storage`);
7396
7547
  return;
7397
7548
  }
7398
7549
  }
@@ -7445,7 +7596,7 @@ var PaymentsModule = class _PaymentsModule {
7445
7596
  const result = await minter.mintNametag(nametag, ownerAddress);
7446
7597
  if (result.success && result.nametagData) {
7447
7598
  await this.setNametag(result.nametagData);
7448
- this.log(`Nametag minted and saved: ${result.nametagData.name}`);
7599
+ logger.debug("Payments", `Nametag minted and saved: ${result.nametagData.name}`);
7449
7600
  this.deps.emitEvent("nametag:registered", {
7450
7601
  nametag: result.nametagData.name,
7451
7602
  addressIndex: 0
@@ -7455,7 +7606,7 @@ var PaymentsModule = class _PaymentsModule {
7455
7606
  return result;
7456
7607
  } catch (error) {
7457
7608
  const errorMsg = error instanceof Error ? error.message : String(error);
7458
- this.log("mintNametag failed:", errorMsg);
7609
+ logger.debug("Payments", "mintNametag failed:", errorMsg);
7459
7610
  return {
7460
7611
  success: false,
7461
7612
  error: errorMsg
@@ -7553,7 +7704,7 @@ var PaymentsModule = class _PaymentsModule {
7553
7704
  restoredCount++;
7554
7705
  }
7555
7706
  if (restoredCount > 0) {
7556
- console.log(`[Payments] Sync: restored ${restoredCount} token(s) lost by loadFromStorageData`);
7707
+ logger.debug("Payments", `Sync: restored ${restoredCount} token(s) lost by loadFromStorageData`);
7557
7708
  }
7558
7709
  if (this.nametags.length === 0 && savedNametags.length > 0) {
7559
7710
  this.nametags = savedNametags;
@@ -7562,7 +7713,7 @@ var PaymentsModule = class _PaymentsModule {
7562
7713
  if (txfData._history && txfData._history.length > 0) {
7563
7714
  const imported = await this.importRemoteHistoryEntries(txfData._history);
7564
7715
  if (imported > 0) {
7565
- this.log(`Imported ${imported} history entries from IPFS sync`);
7716
+ logger.debug("Payments", `Imported ${imported} history entries from IPFS sync`);
7566
7717
  }
7567
7718
  }
7568
7719
  totalAdded += result.added;
@@ -7575,7 +7726,7 @@ var PaymentsModule = class _PaymentsModule {
7575
7726
  removed: result.removed
7576
7727
  });
7577
7728
  } catch (providerError) {
7578
- console.warn(`[PaymentsModule] Sync failed for provider ${providerId}:`, providerError);
7729
+ logger.warn("Payments", `Sync failed for provider ${providerId}:`, providerError);
7579
7730
  this.deps.emitEvent("sync:provider", {
7580
7731
  providerId,
7581
7732
  success: false,
@@ -7613,7 +7764,7 @@ var PaymentsModule = class _PaymentsModule {
7613
7764
  if (provider.onEvent) {
7614
7765
  const unsub = provider.onEvent((event) => {
7615
7766
  if (event.type === "storage:remote-updated") {
7616
- this.log("Remote update detected from provider", providerId, event.data);
7767
+ logger.debug("Payments", "Remote update detected from provider", providerId, event.data);
7617
7768
  this.debouncedSyncFromRemoteUpdate(providerId, event.data);
7618
7769
  }
7619
7770
  });
@@ -7655,7 +7806,7 @@ var PaymentsModule = class _PaymentsModule {
7655
7806
  removed: result.removed
7656
7807
  });
7657
7808
  }).catch((err) => {
7658
- this.log("Auto-sync from remote update failed:", err);
7809
+ logger.debug("Payments", "Auto-sync from remote update failed:", err);
7659
7810
  });
7660
7811
  }, _PaymentsModule.SYNC_DEBOUNCE_MS);
7661
7812
  }
@@ -7760,8 +7911,9 @@ var PaymentsModule = class _PaymentsModule {
7760
7911
  }
7761
7912
  return recipient;
7762
7913
  }
7763
- throw new Error(
7764
- `Cannot resolve transport pubkey for "${recipient}". No binding event found. The recipient must publish their identity first.`
7914
+ throw new SphereError(
7915
+ `Cannot resolve transport pubkey for "${recipient}". No binding event found. The recipient must publish their identity first.`,
7916
+ "INVALID_RECIPIENT"
7765
7917
  );
7766
7918
  }
7767
7919
  /**
@@ -7832,32 +7984,33 @@ var PaymentsModule = class _PaymentsModule {
7832
7984
  return AddressFactory.createAddress(recipient);
7833
7985
  }
7834
7986
  if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
7835
- this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
7987
+ logger.debug("Payments", "Creating DirectAddress from 33-byte compressed pubkey");
7836
7988
  return this.createDirectAddressFromPubkey(recipient);
7837
7989
  }
7838
7990
  const info = peerInfo ?? await this.deps?.transport.resolve?.(recipient) ?? null;
7839
7991
  if (!info) {
7840
- throw new Error(
7841
- `Recipient "${recipient}" not found. Use @nametag, a valid PROXY:/DIRECT: address, or a 33-byte hex pubkey.`
7992
+ throw new SphereError(
7993
+ `Recipient "${recipient}" not found. Use @nametag, a valid PROXY:/DIRECT: address, or a 33-byte hex pubkey.`,
7994
+ "INVALID_RECIPIENT"
7842
7995
  );
7843
7996
  }
7844
7997
  const nametag = recipient.startsWith("@") ? recipient.slice(1) : info.nametag || recipient;
7845
7998
  if (addressMode === "proxy") {
7846
- console.log(`[Payments] Using PROXY address for "${nametag}" (forced)`);
7999
+ logger.debug("Payments", `Using PROXY address for "${nametag}" (forced)`);
7847
8000
  return ProxyAddress.fromNameTag(nametag);
7848
8001
  }
7849
8002
  if (addressMode === "direct") {
7850
8003
  if (!info.directAddress) {
7851
- throw new Error(`"${nametag}" has no DirectAddress stored. It may be a legacy registration.`);
8004
+ throw new SphereError(`"${nametag}" has no DirectAddress stored. It may be a legacy registration.`, "INVALID_RECIPIENT");
7852
8005
  }
7853
- console.log(`[Payments] Using DirectAddress for "${nametag}" (forced): ${info.directAddress.slice(0, 30)}...`);
8006
+ logger.debug("Payments", `Using DirectAddress for "${nametag}" (forced): ${info.directAddress.slice(0, 30)}...`);
7854
8007
  return AddressFactory.createAddress(info.directAddress);
7855
8008
  }
7856
8009
  if (info.directAddress) {
7857
- this.log(`Using DirectAddress for "${nametag}": ${info.directAddress.slice(0, 30)}...`);
8010
+ logger.debug("Payments", `Using DirectAddress for "${nametag}": ${info.directAddress.slice(0, 30)}...`);
7858
8011
  return AddressFactory.createAddress(info.directAddress);
7859
8012
  }
7860
- this.log(`Using PROXY address for legacy nametag "${nametag}"`);
8013
+ logger.debug("Payments", `Using PROXY address for legacy nametag "${nametag}"`);
7861
8014
  return ProxyAddress.fromNameTag(nametag);
7862
8015
  }
7863
8016
  /**
@@ -7870,7 +8023,7 @@ var PaymentsModule = class _PaymentsModule {
7870
8023
  const sourceTokenInput = typeof payload.sourceToken === "string" ? JSON.parse(payload.sourceToken) : payload.sourceToken;
7871
8024
  const commitmentInput = typeof payload.commitmentData === "string" ? JSON.parse(payload.commitmentData) : payload.commitmentData;
7872
8025
  if (!sourceTokenInput || !commitmentInput) {
7873
- console.warn("[Payments] Invalid NOSTR-FIRST transfer format");
8026
+ logger.warn("Payments", "Invalid NOSTR-FIRST transfer format");
7874
8027
  return;
7875
8028
  }
7876
8029
  const token = await this.saveCommitmentOnlyToken(
@@ -7901,7 +8054,7 @@ var PaymentsModule = class _PaymentsModule {
7901
8054
  tokenId: nostrTokenId || token.id
7902
8055
  });
7903
8056
  } catch (error) {
7904
- console.error("[Payments] Failed to process NOSTR-FIRST transfer:", error);
8057
+ logger.error("Payments", "Failed to process NOSTR-FIRST transfer:", error);
7905
8058
  }
7906
8059
  }
7907
8060
  /**
@@ -7926,18 +8079,19 @@ var PaymentsModule = class _PaymentsModule {
7926
8079
  const { ProxyAddress } = await import("@unicitylabs/state-transition-sdk/lib/address/ProxyAddress");
7927
8080
  let proxyNametag = this.getNametag();
7928
8081
  if (!proxyNametag?.token) {
7929
- this.log("Nametag missing in memory, attempting reload from storage...");
8082
+ logger.debug("Payments", "Nametag missing in memory, attempting reload from storage...");
7930
8083
  await this.reloadNametagsFromStorage();
7931
8084
  proxyNametag = this.getNametag();
7932
8085
  }
7933
8086
  if (!proxyNametag?.token) {
7934
- throw new Error("Cannot finalize PROXY transfer - no nametag token");
8087
+ throw new SphereError("Cannot finalize PROXY transfer - no nametag token", "VALIDATION_ERROR");
7935
8088
  }
7936
8089
  const nametagToken = await import_Token6.Token.fromJSON(proxyNametag.token);
7937
8090
  const proxy = await ProxyAddress.fromTokenId(nametagToken.id);
7938
8091
  if (proxy.address !== recipientAddress.address) {
7939
- throw new Error(
7940
- `PROXY address mismatch: nametag resolves to ${proxy.address} but transfer targets ${recipientAddress.address}`
8092
+ throw new SphereError(
8093
+ `PROXY address mismatch: nametag resolves to ${proxy.address} but transfer targets ${recipientAddress.address}`,
8094
+ "VALIDATION_ERROR"
7941
8095
  );
7942
8096
  }
7943
8097
  nametagTokens = [nametagToken];
@@ -7957,12 +8111,12 @@ var PaymentsModule = class _PaymentsModule {
7957
8111
  try {
7958
8112
  const token = this.tokens.get(tokenId);
7959
8113
  if (!token) {
7960
- this.log(`Token ${tokenId} not found for finalization`);
8114
+ logger.debug("Payments", `Token ${tokenId} not found for finalization`);
7961
8115
  return;
7962
8116
  }
7963
8117
  const commitment = await import_TransferCommitment4.TransferCommitment.fromJSON(commitmentInput);
7964
8118
  if (!this.deps.oracle.waitForProofSdk) {
7965
- this.log("Cannot finalize - no waitForProofSdk");
8119
+ logger.debug("Payments", "Cannot finalize - no waitForProofSdk");
7966
8120
  token.status = "confirmed";
7967
8121
  token.updatedAt = Date.now();
7968
8122
  await this.save();
@@ -7974,7 +8128,7 @@ var PaymentsModule = class _PaymentsModule {
7974
8128
  const stClient = this.deps.oracle.getStateTransitionClient?.();
7975
8129
  const trustBase = this.deps.oracle.getTrustBase?.();
7976
8130
  if (!stClient || !trustBase) {
7977
- this.log("Cannot finalize - missing state transition client or trust base");
8131
+ logger.debug("Payments", "Cannot finalize - missing state transition client or trust base");
7978
8132
  token.status = "confirmed";
7979
8133
  token.updatedAt = Date.now();
7980
8134
  await this.save();
@@ -7994,7 +8148,7 @@ var PaymentsModule = class _PaymentsModule {
7994
8148
  };
7995
8149
  this.tokens.set(tokenId, finalizedToken);
7996
8150
  await this.save();
7997
- this.log(`NOSTR-FIRST: Token ${tokenId.slice(0, 8)}... finalized and confirmed`);
8151
+ logger.debug("Payments", `NOSTR-FIRST: Token ${tokenId.slice(0, 8)}... finalized and confirmed`);
7998
8152
  this.deps.emitEvent("transfer:confirmed", {
7999
8153
  id: crypto.randomUUID(),
8000
8154
  status: "completed",
@@ -8002,7 +8156,7 @@ var PaymentsModule = class _PaymentsModule {
8002
8156
  tokenTransfers: []
8003
8157
  });
8004
8158
  } catch (error) {
8005
- console.error("[Payments] Failed to finalize received token:", error);
8159
+ logger.error("Payments", "Failed to finalize received token:", error);
8006
8160
  const token = this.tokens.get(tokenId);
8007
8161
  if (token && token.status === "submitted") {
8008
8162
  token.status = "confirmed";
@@ -8017,7 +8171,7 @@ var PaymentsModule = class _PaymentsModule {
8017
8171
  }
8018
8172
  try {
8019
8173
  const payload = transfer.payload;
8020
- console.log("[Payments][DEBUG] handleIncomingTransfer: keys=", Object.keys(payload).join(","));
8174
+ logger.debug("Payments", "handleIncomingTransfer: keys=", Object.keys(payload).join(","));
8021
8175
  let combinedBundle = null;
8022
8176
  if (isCombinedTransferBundleV6(payload)) {
8023
8177
  combinedBundle = payload;
@@ -8031,12 +8185,12 @@ var PaymentsModule = class _PaymentsModule {
8031
8185
  }
8032
8186
  }
8033
8187
  if (combinedBundle) {
8034
- this.log("Processing COMBINED_TRANSFER V6 bundle...");
8188
+ logger.debug("Payments", "Processing COMBINED_TRANSFER V6 bundle...");
8035
8189
  try {
8036
8190
  await this.processCombinedTransferBundle(combinedBundle, transfer.senderTransportPubkey);
8037
- this.log("COMBINED_TRANSFER V6 processed successfully");
8191
+ logger.debug("Payments", "COMBINED_TRANSFER V6 processed successfully");
8038
8192
  } catch (err) {
8039
- console.error("[Payments] COMBINED_TRANSFER V6 processing error:", err);
8193
+ logger.error("Payments", "COMBINED_TRANSFER V6 processing error:", err);
8040
8194
  }
8041
8195
  return;
8042
8196
  }
@@ -8053,7 +8207,7 @@ var PaymentsModule = class _PaymentsModule {
8053
8207
  }
8054
8208
  }
8055
8209
  if (instantBundle) {
8056
- this.log("Processing INSTANT_SPLIT bundle...");
8210
+ logger.debug("Payments", "Processing INSTANT_SPLIT bundle...");
8057
8211
  try {
8058
8212
  const result = await this.processInstantSplitBundle(
8059
8213
  instantBundle,
@@ -8061,28 +8215,28 @@ var PaymentsModule = class _PaymentsModule {
8061
8215
  payload.memo
8062
8216
  );
8063
8217
  if (result.success) {
8064
- this.log("INSTANT_SPLIT processed successfully");
8218
+ logger.debug("Payments", "INSTANT_SPLIT processed successfully");
8065
8219
  } else {
8066
- console.warn("[Payments] INSTANT_SPLIT processing failed:", result.error);
8220
+ logger.warn("Payments", "INSTANT_SPLIT processing failed:", result.error);
8067
8221
  }
8068
8222
  } catch (err) {
8069
- console.error("[Payments] INSTANT_SPLIT processing error:", err);
8223
+ logger.error("Payments", "INSTANT_SPLIT processing error:", err);
8070
8224
  }
8071
8225
  return;
8072
8226
  }
8073
8227
  if (payload.sourceToken && payload.commitmentData && !payload.transferTx) {
8074
- console.log("[Payments][DEBUG] >>> NOSTR-FIRST commitment-only transfer detected");
8228
+ logger.debug("Payments", "NOSTR-FIRST commitment-only transfer detected");
8075
8229
  await this.handleCommitmentOnlyTransfer(transfer, payload);
8076
8230
  return;
8077
8231
  }
8078
8232
  let tokenData;
8079
8233
  let finalizedSdkToken = null;
8080
8234
  if (payload.sourceToken && payload.transferTx) {
8081
- this.log("Processing Sphere wallet format transfer...");
8235
+ logger.debug("Payments", "Processing Sphere wallet format transfer...");
8082
8236
  const sourceTokenInput = typeof payload.sourceToken === "string" ? JSON.parse(payload.sourceToken) : payload.sourceToken;
8083
8237
  const transferTxInput = typeof payload.transferTx === "string" ? JSON.parse(payload.transferTx) : payload.transferTx;
8084
8238
  if (!sourceTokenInput || !transferTxInput) {
8085
- console.warn("[Payments] Invalid Sphere wallet transfer format");
8239
+ logger.warn("Payments", "Invalid Sphere wallet transfer format");
8086
8240
  return;
8087
8241
  }
8088
8242
  let sourceToken;
@@ -8090,7 +8244,7 @@ var PaymentsModule = class _PaymentsModule {
8090
8244
  try {
8091
8245
  sourceToken = await import_Token6.Token.fromJSON(sourceTokenInput);
8092
8246
  } catch (err) {
8093
- console.error("[Payments] Failed to parse sourceToken:", err);
8247
+ logger.error("Payments", "Failed to parse sourceToken:", err);
8094
8248
  return;
8095
8249
  }
8096
8250
  try {
@@ -8104,16 +8258,16 @@ var PaymentsModule = class _PaymentsModule {
8104
8258
  const commitment = await import_TransferCommitment4.TransferCommitment.fromJSON(transferTxInput);
8105
8259
  const stClient = this.deps.oracle.getStateTransitionClient?.();
8106
8260
  if (!stClient) {
8107
- console.error("[Payments] Cannot process commitment - no state transition client");
8261
+ logger.error("Payments", "Cannot process commitment - no state transition client");
8108
8262
  return;
8109
8263
  }
8110
8264
  const response = await stClient.submitTransferCommitment(commitment);
8111
8265
  if (response.status !== "SUCCESS" && response.status !== "REQUEST_ID_EXISTS") {
8112
- console.error("[Payments] Transfer commitment submission failed:", response.status);
8266
+ logger.error("Payments", "Transfer commitment submission failed:", response.status);
8113
8267
  return;
8114
8268
  }
8115
8269
  if (!this.deps.oracle.waitForProofSdk) {
8116
- console.error("[Payments] Cannot wait for proof - missing oracle method");
8270
+ logger.error("Payments", "Cannot wait for proof - missing oracle method");
8117
8271
  return;
8118
8272
  }
8119
8273
  const inclusionProof = await this.deps.oracle.waitForProofSdk(commitment);
@@ -8125,7 +8279,7 @@ var PaymentsModule = class _PaymentsModule {
8125
8279
  const commitment = await import_TransferCommitment4.TransferCommitment.fromJSON(transferTxInput);
8126
8280
  const stClient = this.deps.oracle.getStateTransitionClient?.();
8127
8281
  if (!stClient || !this.deps.oracle.waitForProofSdk) {
8128
- throw new Error("Cannot submit commitment - missing oracle methods");
8282
+ throw new SphereError("Cannot submit commitment - missing oracle methods", "AGGREGATOR_ERROR");
8129
8283
  }
8130
8284
  await stClient.submitTransferCommitment(commitment);
8131
8285
  const inclusionProof = await this.deps.oracle.waitForProofSdk(commitment);
@@ -8133,33 +8287,33 @@ var PaymentsModule = class _PaymentsModule {
8133
8287
  }
8134
8288
  }
8135
8289
  } catch (err) {
8136
- console.error("[Payments] Failed to parse transferTx:", err);
8290
+ logger.error("Payments", "Failed to parse transferTx:", err);
8137
8291
  return;
8138
8292
  }
8139
8293
  try {
8140
8294
  const stClient = this.deps.oracle.getStateTransitionClient?.();
8141
8295
  const trustBase = this.deps.oracle.getTrustBase?.();
8142
8296
  if (!stClient || !trustBase) {
8143
- console.error("[Payments] Cannot finalize - missing state transition client or trust base. Token rejected.");
8297
+ logger.error("Payments", "Cannot finalize - missing state transition client or trust base. Token rejected.");
8144
8298
  return;
8145
8299
  }
8146
8300
  finalizedSdkToken = await this.finalizeTransferToken(sourceToken, transferTx, stClient, trustBase);
8147
8301
  tokenData = finalizedSdkToken.toJSON();
8148
8302
  const addressScheme = transferTx.data.recipient.scheme;
8149
- this.log(`${addressScheme === import_AddressScheme.AddressScheme.PROXY ? "PROXY" : "DIRECT"} finalization successful`);
8303
+ logger.debug("Payments", `${addressScheme === import_AddressScheme.AddressScheme.PROXY ? "PROXY" : "DIRECT"} finalization successful`);
8150
8304
  } catch (finalizeError) {
8151
- console.error(`[Payments] Finalization FAILED - token rejected:`, finalizeError);
8305
+ logger.error("Payments", "Finalization FAILED - token rejected:", finalizeError);
8152
8306
  return;
8153
8307
  }
8154
8308
  } else if (payload.token) {
8155
8309
  tokenData = payload.token;
8156
8310
  } else {
8157
- console.warn("[Payments] Unknown transfer payload format");
8311
+ logger.warn("Payments", "Unknown transfer payload format");
8158
8312
  return;
8159
8313
  }
8160
8314
  const validation = await this.deps.oracle.validateToken(tokenData);
8161
8315
  if (!validation.valid) {
8162
- console.warn("[Payments] Received invalid token");
8316
+ logger.warn("Payments", "Received invalid token");
8163
8317
  return;
8164
8318
  }
8165
8319
  const tokenInfo = await parseTokenInfo(tokenData);
@@ -8200,12 +8354,12 @@ var PaymentsModule = class _PaymentsModule {
8200
8354
  receivedAt: transfer.timestamp
8201
8355
  };
8202
8356
  this.deps.emitEvent("transfer:incoming", incomingTransfer);
8203
- this.log(`Incoming transfer processed: ${token.id}, ${token.amount} ${token.symbol}`);
8357
+ logger.debug("Payments", `Incoming transfer processed: ${token.id}, ${token.amount} ${token.symbol}`);
8204
8358
  } else {
8205
- this.log(`Duplicate transfer ignored: ${token.id}, ${token.amount} ${token.symbol}`);
8359
+ logger.debug("Payments", `Duplicate transfer ignored: ${token.id}, ${token.amount} ${token.symbol}`);
8206
8360
  }
8207
8361
  } catch (error) {
8208
- console.error("[Payments] Failed to process incoming transfer:", error);
8362
+ logger.error("Payments", "Failed to process incoming transfer:", error);
8209
8363
  }
8210
8364
  }
8211
8365
  // ===========================================================================
@@ -8220,15 +8374,15 @@ var PaymentsModule = class _PaymentsModule {
8220
8374
  if (existingArchive) {
8221
8375
  if (isIncrementalUpdate(existingArchive, txf)) {
8222
8376
  this.archivedTokens.set(tokenId, txf);
8223
- this.log(`Updated archived token ${tokenId.slice(0, 8)}...`);
8377
+ logger.debug("Payments", `Updated archived token ${tokenId.slice(0, 8)}...`);
8224
8378
  } else {
8225
8379
  const stateHash = getCurrentStateHash(txf) || "";
8226
8380
  await this.storeForkedToken(tokenId, stateHash, txf);
8227
- this.log(`Archived token ${tokenId.slice(0, 8)}... is a fork`);
8381
+ logger.debug("Payments", `Archived token ${tokenId.slice(0, 8)}... is a fork`);
8228
8382
  }
8229
8383
  } else {
8230
8384
  this.archivedTokens.set(tokenId, txf);
8231
- this.log(`Archived token ${tokenId.slice(0, 8)}...`);
8385
+ logger.debug("Payments", `Archived token ${tokenId.slice(0, 8)}...`);
8232
8386
  }
8233
8387
  }
8234
8388
  // ===========================================================================
@@ -8240,20 +8394,20 @@ var PaymentsModule = class _PaymentsModule {
8240
8394
  const txf = tokenToTxf(t);
8241
8395
  return `${t.id.slice(0, 12)}(${t.status},txf=${!!txf})`;
8242
8396
  });
8243
- console.log(`[Payments][DEBUG] save(): providers=${providers.size}, tokens=[${tokenStats.join(", ")}]`);
8397
+ logger.debug("Payments", `save(): providers=${providers.size}, tokens=[${tokenStats.join(", ")}]`);
8244
8398
  if (providers.size > 0) {
8245
8399
  const data = await this.createStorageData();
8246
8400
  const dataKeys = Object.keys(data).filter((k) => k.startsWith("token-"));
8247
- console.log(`[Payments][DEBUG] save(): TXF keys=${dataKeys.length} (${dataKeys.join(", ")})`);
8401
+ logger.debug("Payments", `save(): TXF keys=${dataKeys.length} (${dataKeys.join(", ")})`);
8248
8402
  for (const [id, provider] of providers) {
8249
8403
  try {
8250
8404
  await provider.save(data);
8251
8405
  } catch (err) {
8252
- console.error(`[Payments] Failed to save to provider ${id}:`, err);
8406
+ logger.error("Payments", `Failed to save to provider ${id}:`, err);
8253
8407
  }
8254
8408
  }
8255
8409
  } else {
8256
- console.log("[Payments][DEBUG] save(): No token storage providers - TXF not persisted");
8410
+ logger.debug("Payments", "save(): No token storage providers - TXF not persisted");
8257
8411
  }
8258
8412
  await this.savePendingV5Tokens();
8259
8413
  }
@@ -8291,14 +8445,14 @@ var PaymentsModule = class _PaymentsModule {
8291
8445
  }
8292
8446
  loadFromStorageData(data) {
8293
8447
  const parsed = parseTxfStorageData(data);
8294
- console.log(`[Payments][DEBUG] loadFromStorageData: parsed ${parsed.tokens.length} tokens, ${parsed.tombstones.length} tombstones, errors=[${parsed.validationErrors.join("; ")}]`);
8448
+ logger.debug("Payments", `loadFromStorageData: parsed ${parsed.tokens.length} tokens, ${parsed.tombstones.length} tombstones, errors=[${parsed.validationErrors.join("; ")}]`);
8295
8449
  this.tombstones = parsed.tombstones;
8296
8450
  this.tokens.clear();
8297
8451
  for (const token of parsed.tokens) {
8298
8452
  const sdkTokenId = extractTokenIdFromSdkData(token.sdkData);
8299
8453
  const stateHash = extractStateHashFromSdkData(token.sdkData);
8300
8454
  if (sdkTokenId && stateHash && this.isStateTombstoned(sdkTokenId, stateHash)) {
8301
- this.log(`Skipping tombstoned token ${sdkTokenId.slice(0, 8)}... during load (exact state match)`);
8455
+ logger.debug("Payments", `Skipping tombstoned token ${sdkTokenId.slice(0, 8)}... during load (exact state match)`);
8302
8456
  continue;
8303
8457
  }
8304
8458
  this.tokens.set(token.id, token);
@@ -8318,12 +8472,12 @@ var PaymentsModule = class _PaymentsModule {
8318
8472
  try {
8319
8473
  const stClient = this.deps.oracle.getStateTransitionClient?.();
8320
8474
  if (!stClient) {
8321
- this.log("Cannot submit commitment - no state transition client");
8475
+ logger.debug("Payments", "Cannot submit commitment - no state transition client");
8322
8476
  return;
8323
8477
  }
8324
8478
  const response = await stClient.submitTransferCommitment(commitment);
8325
8479
  if (response.status !== "SUCCESS" && response.status !== "REQUEST_ID_EXISTS") {
8326
- this.log(`Transfer commitment submission failed: ${response.status}`);
8480
+ logger.debug("Payments", `Transfer commitment submission failed: ${response.status}`);
8327
8481
  const token = this.tokens.get(tokenId);
8328
8482
  if (token) {
8329
8483
  token.status = "invalid";
@@ -8343,7 +8497,7 @@ var PaymentsModule = class _PaymentsModule {
8343
8497
  onProofReceived
8344
8498
  });
8345
8499
  } catch (error) {
8346
- this.log("submitAndPollForProof error:", error);
8500
+ logger.debug("Payments", "submitAndPollForProof error:", error);
8347
8501
  }
8348
8502
  }
8349
8503
  /**
@@ -8351,7 +8505,7 @@ var PaymentsModule = class _PaymentsModule {
8351
8505
  */
8352
8506
  addProofPollingJob(job) {
8353
8507
  this.proofPollingJobs.set(job.tokenId, job);
8354
- this.log(`Added proof polling job for token ${job.tokenId.slice(0, 8)}...`);
8508
+ logger.debug("Payments", `Added proof polling job for token ${job.tokenId.slice(0, 8)}...`);
8355
8509
  this.startProofPolling();
8356
8510
  }
8357
8511
  /**
@@ -8360,7 +8514,7 @@ var PaymentsModule = class _PaymentsModule {
8360
8514
  startProofPolling() {
8361
8515
  if (this.proofPollingInterval) return;
8362
8516
  if (this.proofPollingJobs.size === 0) return;
8363
- this.log("Starting proof polling...");
8517
+ logger.debug("Payments", "Starting proof polling...");
8364
8518
  this.proofPollingInterval = setInterval(
8365
8519
  () => this.processProofPollingQueue(),
8366
8520
  _PaymentsModule.PROOF_POLLING_INTERVAL_MS
@@ -8373,7 +8527,7 @@ var PaymentsModule = class _PaymentsModule {
8373
8527
  if (this.proofPollingInterval) {
8374
8528
  clearInterval(this.proofPollingInterval);
8375
8529
  this.proofPollingInterval = null;
8376
- this.log("Stopped proof polling");
8530
+ logger.debug("Payments", "Stopped proof polling");
8377
8531
  }
8378
8532
  }
8379
8533
  /**
@@ -8390,7 +8544,7 @@ var PaymentsModule = class _PaymentsModule {
8390
8544
  job.attemptCount++;
8391
8545
  job.lastAttemptAt = Date.now();
8392
8546
  if (job.attemptCount >= _PaymentsModule.PROOF_POLLING_MAX_ATTEMPTS) {
8393
- this.log(`Proof polling timeout for token ${tokenId.slice(0, 8)}...`);
8547
+ logger.debug("Payments", `Proof polling timeout for token ${tokenId.slice(0, 8)}...`);
8394
8548
  const token2 = this.tokens.get(tokenId);
8395
8549
  if (token2 && token2.status === "submitted") {
8396
8550
  token2.status = "invalid";
@@ -8429,12 +8583,12 @@ var PaymentsModule = class _PaymentsModule {
8429
8583
  token.updatedAt = Date.now();
8430
8584
  this.tokens.set(tokenId, token);
8431
8585
  await this.save();
8432
- this.log(`Proof received for token ${tokenId.slice(0, 8)}..., status: spent`);
8586
+ logger.debug("Payments", `Proof received for token ${tokenId.slice(0, 8)}..., status: spent`);
8433
8587
  }
8434
8588
  job.onProofReceived?.(tokenId);
8435
8589
  completedJobs.push(tokenId);
8436
8590
  } catch (error) {
8437
- this.log(`Proof polling attempt ${job.attemptCount} for ${tokenId.slice(0, 8)}...: ${error}`);
8591
+ logger.debug("Payments", `Proof polling attempt ${job.attemptCount} for ${tokenId.slice(0, 8)}...: ${error}`);
8438
8592
  }
8439
8593
  }
8440
8594
  for (const tokenId of completedJobs) {
@@ -8449,7 +8603,7 @@ var PaymentsModule = class _PaymentsModule {
8449
8603
  // ===========================================================================
8450
8604
  ensureInitialized() {
8451
8605
  if (!this.deps) {
8452
- throw new Error("PaymentsModule not initialized");
8606
+ throw new SphereError("PaymentsModule not initialized", "NOT_INITIALIZED");
8453
8607
  }
8454
8608
  }
8455
8609
  };
@@ -8457,7 +8611,12 @@ function createPaymentsModule(config) {
8457
8611
  return new PaymentsModule(config);
8458
8612
  }
8459
8613
 
8614
+ // modules/payments/BackgroundCommitmentService.ts
8615
+ init_logger();
8616
+ init_errors();
8617
+
8460
8618
  // modules/payments/TokenRecoveryService.ts
8619
+ init_logger();
8461
8620
  var import_TokenId4 = require("@unicitylabs/state-transition-sdk/lib/token/TokenId");
8462
8621
  var import_TokenState6 = require("@unicitylabs/state-transition-sdk/lib/token/TokenState");
8463
8622
  var import_TokenType4 = require("@unicitylabs/state-transition-sdk/lib/token/TokenType");
@@ -8466,6 +8625,8 @@ var import_HashAlgorithm6 = require("@unicitylabs/state-transition-sdk/lib/hash/
8466
8625
  var import_UnmaskedPredicate6 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate");
8467
8626
 
8468
8627
  // modules/communications/CommunicationsModule.ts
8628
+ init_logger();
8629
+ init_errors();
8469
8630
  init_constants();
8470
8631
  var CommunicationsModule = class {
8471
8632
  config;
@@ -8560,7 +8721,7 @@ var CommunicationsModule = class {
8560
8721
  }
8561
8722
  if (myMessages.length > 0) {
8562
8723
  await this.save();
8563
- console.log(`[Communications] Migrated ${myMessages.length} messages to per-address storage`);
8724
+ logger.debug("Communications", `Migrated ${myMessages.length} messages to per-address storage`);
8564
8725
  }
8565
8726
  }
8566
8727
  }
@@ -8646,7 +8807,7 @@ var CommunicationsModule = class {
8646
8807
  const msg = this.messages.get(id);
8647
8808
  if (msg && msg.senderPubkey !== this.deps.identity.chainPubkey) {
8648
8809
  this.deps.transport.sendReadReceipt(msg.senderPubkey, id).catch((err) => {
8649
- console.warn("[Communications] Failed to send read receipt:", err);
8810
+ logger.warn("Communications", "Failed to send read receipt:", err);
8650
8811
  });
8651
8812
  }
8652
8813
  }
@@ -8846,7 +9007,7 @@ var CommunicationsModule = class {
8846
9007
  try {
8847
9008
  handler(message);
8848
9009
  } catch (error) {
8849
- console.error("[Communications] Handler error:", error);
9010
+ logger.error("Communications", "Handler error:", error);
8850
9011
  }
8851
9012
  }
8852
9013
  if (this.config.autoSave) {
@@ -8865,7 +9026,7 @@ var CommunicationsModule = class {
8865
9026
  try {
8866
9027
  handler(composing);
8867
9028
  } catch (error) {
8868
- console.error("[Communications] Composing handler error:", error);
9029
+ logger.error("Communications", "Composing handler error:", error);
8869
9030
  }
8870
9031
  }
8871
9032
  }
@@ -8883,7 +9044,7 @@ var CommunicationsModule = class {
8883
9044
  try {
8884
9045
  handler(message);
8885
9046
  } catch (error) {
8886
- console.error("[Communications] Handler error:", error);
9047
+ logger.error("Communications", "Handler error:", error);
8887
9048
  }
8888
9049
  }
8889
9050
  }
@@ -8924,7 +9085,7 @@ var CommunicationsModule = class {
8924
9085
  const nametag = recipient.slice(1);
8925
9086
  const pubkey = await this.deps.transport.resolveNametag?.(nametag);
8926
9087
  if (!pubkey) {
8927
- throw new Error(`Nametag not found: ${recipient}`);
9088
+ throw new SphereError(`Nametag not found: ${recipient}`, "INVALID_RECIPIENT");
8928
9089
  }
8929
9090
  return { pubkey, nametag };
8930
9091
  }
@@ -8932,7 +9093,7 @@ var CommunicationsModule = class {
8932
9093
  }
8933
9094
  ensureInitialized() {
8934
9095
  if (!this.deps) {
8935
- throw new Error("CommunicationsModule not initialized");
9096
+ throw new SphereError("CommunicationsModule not initialized", "NOT_INITIALIZED");
8936
9097
  }
8937
9098
  }
8938
9099
  };
@@ -8942,6 +9103,8 @@ function createCommunicationsModule(config) {
8942
9103
 
8943
9104
  // modules/groupchat/GroupChatModule.ts
8944
9105
  var import_nostr_js_sdk2 = require("@unicitylabs/nostr-js-sdk");
9106
+ init_logger();
9107
+ init_errors();
8945
9108
  init_constants();
8946
9109
 
8947
9110
  // modules/groupchat/types.ts
@@ -9087,13 +9250,15 @@ var GroupChatModule = class {
9087
9250
  for (const subId of this.subscriptionIds) {
9088
9251
  try {
9089
9252
  this.client.unsubscribe(subId);
9090
- } catch {
9253
+ } catch (err) {
9254
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
9091
9255
  }
9092
9256
  }
9093
9257
  this.subscriptionIds = [];
9094
9258
  try {
9095
9259
  this.client.disconnect();
9096
- } catch {
9260
+ } catch (err) {
9261
+ logger.debug("GroupChat", "Failed to disconnect", err);
9097
9262
  }
9098
9263
  this.client = null;
9099
9264
  }
@@ -9133,7 +9298,8 @@ var GroupChatModule = class {
9133
9298
  for (const subId of this.subscriptionIds) {
9134
9299
  try {
9135
9300
  this.client.unsubscribe(subId);
9136
- } catch {
9301
+ } catch (err) {
9302
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
9137
9303
  }
9138
9304
  }
9139
9305
  this.subscriptionIds = [];
@@ -9168,21 +9334,21 @@ var GroupChatModule = class {
9168
9334
  }
9169
9335
  this.deps.emitEvent("groupchat:connection", { connected: true });
9170
9336
  } catch (error) {
9171
- console.error("[GroupChat] Failed to connect to relays", error);
9337
+ logger.error("GroupChat", "Failed to connect to relays", error);
9172
9338
  this.deps.emitEvent("groupchat:connection", { connected: false });
9173
9339
  this.scheduleReconnect();
9174
9340
  }
9175
9341
  }
9176
9342
  scheduleReconnect() {
9177
9343
  if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
9178
- console.error("[GroupChat] Max reconnection attempts reached");
9344
+ logger.error("GroupChat", "Max reconnection attempts reached");
9179
9345
  return;
9180
9346
  }
9181
9347
  this.reconnectAttempts++;
9182
9348
  this.reconnectTimer = setTimeout(() => {
9183
9349
  this.reconnectTimer = null;
9184
9350
  if (this.deps) {
9185
- this.connect().catch(console.error);
9351
+ this.connect().catch((err) => logger.error("GroupChat", "Reconnect failed:", err));
9186
9352
  }
9187
9353
  }, this.config.reconnectDelayMs);
9188
9354
  }
@@ -9417,7 +9583,8 @@ var GroupChatModule = class {
9417
9583
  },
9418
9584
  onComplete: () => {
9419
9585
  },
9420
- timeoutMs: 15e3
9586
+ timeoutMs: 15e3,
9587
+ timeoutLabel: "restoreJoinedGroups"
9421
9588
  }
9422
9589
  );
9423
9590
  if (groupIdsWithMembership.size === 0) return [];
@@ -9434,7 +9601,8 @@ var GroupChatModule = class {
9434
9601
  this.fetchMessages(groupId)
9435
9602
  ]);
9436
9603
  }
9437
- } catch {
9604
+ } catch (error) {
9605
+ logger.warn("GroupChat", "Failed to restore group", groupId, error);
9438
9606
  }
9439
9607
  }
9440
9608
  if (restoredGroups.length > 0) {
@@ -9467,7 +9635,8 @@ var GroupChatModule = class {
9467
9635
  },
9468
9636
  onComplete: () => {
9469
9637
  },
9470
- timeoutMs: 1e4
9638
+ timeoutMs: 1e4,
9639
+ timeoutLabel: "fetchAvailableGroups(metadata)"
9471
9640
  }
9472
9641
  ),
9473
9642
  this.oneshotSubscription(
@@ -9482,7 +9651,8 @@ var GroupChatModule = class {
9482
9651
  },
9483
9652
  onComplete: () => {
9484
9653
  },
9485
- timeoutMs: 1e4
9654
+ timeoutMs: 1e4,
9655
+ timeoutLabel: "fetchAvailableGroups(members)"
9486
9656
  }
9487
9657
  )
9488
9658
  ]);
@@ -9541,7 +9711,7 @@ var GroupChatModule = class {
9541
9711
  return true;
9542
9712
  }
9543
9713
  }
9544
- console.error("[GroupChat] Failed to join group", error);
9714
+ logger.error("GroupChat", "Failed to join group", error);
9545
9715
  return false;
9546
9716
  }
9547
9717
  }
@@ -9571,7 +9741,7 @@ var GroupChatModule = class {
9571
9741
  this.persistAll();
9572
9742
  return true;
9573
9743
  }
9574
- console.error("[GroupChat] Failed to leave group", error);
9744
+ logger.error("GroupChat", "Failed to leave group", error);
9575
9745
  return false;
9576
9746
  }
9577
9747
  }
@@ -9622,10 +9792,8 @@ var GroupChatModule = class {
9622
9792
  kind: NIP29_KINDS.JOIN_REQUEST,
9623
9793
  tags: [["h", group.id]],
9624
9794
  content: ""
9625
- }).catch(() => {
9626
- });
9627
- await this.fetchAndSaveMembers(group.id).catch(() => {
9628
- });
9795
+ }).catch((err) => logger.debug("GroupChat", "Background operation failed", err));
9796
+ await this.fetchAndSaveMembers(group.id).catch((err) => logger.debug("GroupChat", "Failed to fetch members", group.id, err));
9629
9797
  this.saveMemberToMemory({
9630
9798
  pubkey: creatorPubkey,
9631
9799
  groupId: group.id,
@@ -9637,7 +9805,7 @@ var GroupChatModule = class {
9637
9805
  this.schedulePersist();
9638
9806
  return group;
9639
9807
  } catch (error) {
9640
- console.error("[GroupChat] Failed to create group", error);
9808
+ logger.error("GroupChat", "Failed to create group", error);
9641
9809
  return null;
9642
9810
  }
9643
9811
  }
@@ -9664,7 +9832,7 @@ var GroupChatModule = class {
9664
9832
  }
9665
9833
  return false;
9666
9834
  } catch (error) {
9667
- console.error("[GroupChat] Failed to delete group", error);
9835
+ logger.error("GroupChat", "Failed to delete group", error);
9668
9836
  return false;
9669
9837
  }
9670
9838
  }
@@ -9684,7 +9852,7 @@ var GroupChatModule = class {
9684
9852
  });
9685
9853
  return eventId ? inviteCode : null;
9686
9854
  } catch (error) {
9687
- console.error("[GroupChat] Failed to create invite", error);
9855
+ logger.error("GroupChat", "Failed to create invite", error);
9688
9856
  return null;
9689
9857
  }
9690
9858
  }
@@ -9734,7 +9902,7 @@ var GroupChatModule = class {
9734
9902
  }
9735
9903
  return null;
9736
9904
  } catch (error) {
9737
- console.error("[GroupChat] Failed to send message", error);
9905
+ logger.error("GroupChat", "Failed to send message", error);
9738
9906
  return null;
9739
9907
  }
9740
9908
  }
@@ -9773,7 +9941,8 @@ var GroupChatModule = class {
9773
9941
  this.schedulePersist();
9774
9942
  return fetchedMessages;
9775
9943
  },
9776
- timeoutMs: 1e4
9944
+ timeoutMs: 1e4,
9945
+ timeoutLabel: `fetchMessages(${groupId})`
9777
9946
  });
9778
9947
  }
9779
9948
  // ===========================================================================
@@ -9834,7 +10003,7 @@ var GroupChatModule = class {
9834
10003
  }
9835
10004
  return false;
9836
10005
  } catch (error) {
9837
- console.error("[GroupChat] Failed to kick user", error);
10006
+ logger.error("GroupChat", "Failed to kick user", error);
9838
10007
  return false;
9839
10008
  }
9840
10009
  }
@@ -9857,7 +10026,7 @@ var GroupChatModule = class {
9857
10026
  }
9858
10027
  return false;
9859
10028
  } catch (error) {
9860
- console.error("[GroupChat] Failed to delete message", error);
10029
+ logger.error("GroupChat", "Failed to delete message", error);
9861
10030
  return false;
9862
10031
  }
9863
10032
  }
@@ -10142,7 +10311,7 @@ var GroupChatModule = class {
10142
10311
  this.persistTimer = setTimeout(() => {
10143
10312
  this.persistTimer = null;
10144
10313
  this.persistPromise = this.doPersistAll().catch((err) => {
10145
- console.error("[GroupChat] Persistence error:", err);
10314
+ logger.error("GroupChat", "Persistence error:", err);
10146
10315
  }).finally(() => {
10147
10316
  this.persistPromise = null;
10148
10317
  });
@@ -10322,7 +10491,8 @@ var GroupChatModule = class {
10322
10491
  if (state.subId) {
10323
10492
  try {
10324
10493
  this.client.unsubscribe(state.subId);
10325
- } catch {
10494
+ } catch (err) {
10495
+ logger.debug("GroupChat", "Failed to unsubscribe", err);
10326
10496
  }
10327
10497
  const idx = this.subscriptionIds.indexOf(state.subId);
10328
10498
  if (idx >= 0) this.subscriptionIds.splice(idx, 1);
@@ -10337,12 +10507,17 @@ var GroupChatModule = class {
10337
10507
  });
10338
10508
  state.subId = subId;
10339
10509
  this.subscriptionIds.push(subId);
10340
- setTimeout(finish, opts.timeoutMs ?? 5e3);
10510
+ setTimeout(() => {
10511
+ if (!done && opts.timeoutLabel) {
10512
+ logger.warn("GroupChat", `${opts.timeoutLabel} timed out`);
10513
+ }
10514
+ finish();
10515
+ }, opts.timeoutMs ?? 5e3);
10341
10516
  });
10342
10517
  }
10343
10518
  ensureInitialized() {
10344
10519
  if (!this.deps) {
10345
- throw new Error("GroupChatModule not initialized");
10520
+ throw new SphereError("GroupChatModule not initialized", "NOT_INITIALIZED");
10346
10521
  }
10347
10522
  }
10348
10523
  async ensureConnected() {
@@ -12511,6 +12686,7 @@ var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {
12511
12686
  var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha2564);
12512
12687
 
12513
12688
  // modules/market/MarketModule.ts
12689
+ init_errors();
12514
12690
  var DEFAULT_MARKET_API_URL = "https://market-api.unicity.network";
12515
12691
  function hexToBytes3(hex) {
12516
12692
  const len = hex.length >> 1;
@@ -12700,7 +12876,7 @@ var MarketModule = class {
12700
12876
  // ---------------------------------------------------------------------------
12701
12877
  ensureIdentity() {
12702
12878
  if (!this.identity) {
12703
- throw new Error("MarketModule not initialized \u2014 call initialize() first");
12879
+ throw new SphereError("MarketModule not initialized \u2014 call initialize() first", "NOT_INITIALIZED");
12704
12880
  }
12705
12881
  }
12706
12882
  /** Register the agent's public key with the server (idempotent) */
@@ -12726,7 +12902,7 @@ var MarketModule = class {
12726
12902
  data = JSON.parse(text);
12727
12903
  } catch {
12728
12904
  }
12729
- throw new Error(data?.error ?? `Agent registration failed: HTTP ${res.status}`);
12905
+ throw new SphereError(data?.error ?? `Agent registration failed: HTTP ${res.status}`, "NETWORK_ERROR");
12730
12906
  }
12731
12907
  async parseResponse(res) {
12732
12908
  const text = await res.text();
@@ -12734,9 +12910,9 @@ var MarketModule = class {
12734
12910
  try {
12735
12911
  data = JSON.parse(text);
12736
12912
  } catch {
12737
- throw new Error(`Market API error: HTTP ${res.status} \u2014 unexpected response (not JSON)`);
12913
+ throw new SphereError(`Market API error: HTTP ${res.status} \u2014 unexpected response (not JSON)`, "NETWORK_ERROR");
12738
12914
  }
12739
- if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
12915
+ if (!res.ok) throw new SphereError(data.error ?? `HTTP ${res.status}`, "NETWORK_ERROR");
12740
12916
  return data;
12741
12917
  }
12742
12918
  async apiPost(path, body) {
@@ -12792,6 +12968,8 @@ init_constants();
12792
12968
 
12793
12969
  // core/encryption.ts
12794
12970
  var import_crypto_js6 = __toESM(require("crypto-js"), 1);
12971
+ init_errors();
12972
+ init_logger();
12795
12973
  function encryptSimple(plaintext, password) {
12796
12974
  return import_crypto_js6.default.AES.encrypt(plaintext, password).toString();
12797
12975
  }
@@ -12799,7 +12977,7 @@ function decryptSimple(ciphertext, password) {
12799
12977
  const decrypted = import_crypto_js6.default.AES.decrypt(ciphertext, password);
12800
12978
  const result = decrypted.toString(import_crypto_js6.default.enc.Utf8);
12801
12979
  if (!result) {
12802
- throw new Error("Decryption failed: invalid password or corrupted data");
12980
+ throw new SphereError("Decryption failed: invalid password or corrupted data", "DECRYPTION_ERROR");
12803
12981
  }
12804
12982
  return result;
12805
12983
  }
@@ -12813,12 +12991,14 @@ function decryptWithSalt(ciphertext, password, salt) {
12813
12991
  const decrypted = import_crypto_js6.default.AES.decrypt(ciphertext, key);
12814
12992
  const result = decrypted.toString(import_crypto_js6.default.enc.Utf8);
12815
12993
  return result || null;
12816
- } catch {
12994
+ } catch (err) {
12995
+ logger.debug("Encryption", "decryptWithSalt failed", err);
12817
12996
  return null;
12818
12997
  }
12819
12998
  }
12820
12999
 
12821
13000
  // core/scan.ts
13001
+ init_logger();
12822
13002
  async function scanAddressesImpl(deriveAddress, options = {}) {
12823
13003
  const maxAddresses = options.maxAddresses ?? 50;
12824
13004
  const gapLimit = options.gapLimit ?? 20;
@@ -12857,7 +13037,8 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
12857
13037
  nametag = tag;
12858
13038
  nametagsFoundCount++;
12859
13039
  }
12860
- } catch {
13040
+ } catch (err) {
13041
+ logger.debug("Sphere", "Nametag resolution failed during scan", err);
12861
13042
  }
12862
13043
  }
12863
13044
  foundAddresses.push({
@@ -12874,7 +13055,7 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
12874
13055
  consecutiveEmpty++;
12875
13056
  }
12876
13057
  } catch (err) {
12877
- console.warn(`[scanAddresses] Error checking ${addrInfo.address}:`, err);
13058
+ logger.warn("Sphere", `scanAddresses: Error checking ${addrInfo.address}:`, err);
12878
13059
  consecutiveEmpty++;
12879
13060
  }
12880
13061
  if (consecutiveEmpty >= gapLimit) {
@@ -12966,6 +13147,7 @@ init_network();
12966
13147
  var import_crypto_js7 = __toESM(require("crypto-js"), 1);
12967
13148
 
12968
13149
  // core/utils.ts
13150
+ init_errors();
12969
13151
  var SECP256K1_ORDER = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
12970
13152
  var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
12971
13153
  function isValidPrivateKey(hex) {
@@ -13005,7 +13187,7 @@ function base58Decode(str) {
13005
13187
  for (let i = 0; i < str.length; i++) {
13006
13188
  const char = str[i];
13007
13189
  if (!(char in ALPHABET_MAP)) {
13008
- throw new Error("Invalid base58 character: " + char);
13190
+ throw new SphereError("Invalid base58 character: " + char, "VALIDATION_ERROR");
13009
13191
  }
13010
13192
  num = num * BigInt(58) + BigInt(ALPHABET_MAP[char]);
13011
13193
  }
@@ -13288,6 +13470,7 @@ function parseAndDecryptWalletText(content, password) {
13288
13470
 
13289
13471
  // serialization/wallet-dat.ts
13290
13472
  var import_crypto_js8 = __toESM(require("crypto-js"), 1);
13473
+ init_errors();
13291
13474
  function uint8ArrayToWordArray(u8arr) {
13292
13475
  const hex = bytesToHex2(u8arr);
13293
13476
  return import_crypto_js8.default.enc.Hex.parse(hex);
@@ -13472,7 +13655,7 @@ async function decryptCMasterKey(cmk, password, onProgress) {
13472
13655
  );
13473
13656
  const result = import_crypto_js8.default.enc.Hex.stringify(decrypted);
13474
13657
  if (!result || result.length !== 64) {
13475
- throw new Error("Master key decryption failed - incorrect password");
13658
+ throw new SphereError("Master key decryption failed - incorrect password", "DECRYPTION_ERROR");
13476
13659
  }
13477
13660
  return result;
13478
13661
  }
@@ -13767,6 +13950,7 @@ var Sphere = class _Sphere {
13767
13950
  * ```
13768
13951
  */
13769
13952
  static async init(options) {
13953
+ if (options.debug) logger.configure({ debug: true });
13770
13954
  _Sphere.configureTokenRegistry(options.storage, options.network);
13771
13955
  const groupChat = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
13772
13956
  const market = _Sphere.resolveMarketConfig(options.market);
@@ -13794,8 +13978,9 @@ var Sphere = class _Sphere {
13794
13978
  mnemonic = _Sphere.generateMnemonic();
13795
13979
  generatedMnemonic = mnemonic;
13796
13980
  } else {
13797
- throw new Error(
13798
- "No wallet exists and no mnemonic provided. Provide a mnemonic or set autoGenerate: true."
13981
+ throw new SphereError(
13982
+ "No wallet exists and no mnemonic provided. Provide a mnemonic or set autoGenerate: true.",
13983
+ "INVALID_CONFIG"
13799
13984
  );
13800
13985
  }
13801
13986
  }
@@ -13868,11 +14053,12 @@ var Sphere = class _Sphere {
13868
14053
  * Create new wallet with mnemonic
13869
14054
  */
13870
14055
  static async create(options) {
14056
+ if (options.debug) logger.configure({ debug: true });
13871
14057
  if (!options.mnemonic || !_Sphere.validateMnemonic(options.mnemonic)) {
13872
- throw new Error("Invalid mnemonic");
14058
+ throw new SphereError("Invalid mnemonic", "INVALID_IDENTITY");
13873
14059
  }
13874
14060
  if (await _Sphere.exists(options.storage)) {
13875
- throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
14061
+ throw new SphereError("Wallet already exists. Use Sphere.load() or Sphere.clear() first.", "ALREADY_INITIALIZED");
13876
14062
  }
13877
14063
  const progress = options.onProgress;
13878
14064
  if (!options.storage.isConnected()) {
@@ -13918,10 +14104,10 @@ var Sphere = class _Sphere {
13918
14104
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13919
14105
  const result = await sphere.discoverAddresses(discoverOpts);
13920
14106
  if (result.addresses.length > 0) {
13921
- console.log(`[Sphere.create] Address discovery: found ${result.addresses.length} address(es)`);
14107
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
13922
14108
  }
13923
14109
  } catch (err) {
13924
- console.warn("[Sphere.create] Address discovery failed (non-fatal):", err);
14110
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
13925
14111
  }
13926
14112
  }
13927
14113
  progress?.({ step: "complete", message: "Wallet created" });
@@ -13931,8 +14117,9 @@ var Sphere = class _Sphere {
13931
14117
  * Load existing wallet from storage
13932
14118
  */
13933
14119
  static async load(options) {
14120
+ if (options.debug) logger.configure({ debug: true });
13934
14121
  if (!await _Sphere.exists(options.storage)) {
13935
- throw new Error("No wallet found. Use Sphere.create() to create a new wallet.");
14122
+ throw new SphereError("No wallet found. Use Sphere.create() to create a new wallet.", "NOT_INITIALIZED");
13936
14123
  }
13937
14124
  const progress = options.onProgress;
13938
14125
  _Sphere.configureTokenRegistry(options.storage, options.network);
@@ -13963,16 +14150,16 @@ var Sphere = class _Sphere {
13963
14150
  _Sphere.instance = sphere;
13964
14151
  if (sphere._identity?.nametag && !sphere._payments.hasNametag()) {
13965
14152
  progress?.({ step: "registering_nametag", message: "Restoring nametag token..." });
13966
- console.log(`[Sphere] Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
14153
+ logger.debug("Sphere", `Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
13967
14154
  try {
13968
14155
  const result = await sphere.mintNametag(sphere._identity.nametag);
13969
14156
  if (result.success) {
13970
- console.log(`[Sphere] Nametag token minted successfully on load`);
14157
+ logger.debug("Sphere", `Nametag token minted successfully on load`);
13971
14158
  } else {
13972
- console.warn(`[Sphere] Could not mint nametag token: ${result.error}`);
14159
+ logger.warn("Sphere", `Could not mint nametag token: ${result.error}`);
13973
14160
  }
13974
14161
  } catch (err) {
13975
- console.warn(`[Sphere] Nametag token mint failed:`, err);
14162
+ logger.warn("Sphere", `Nametag token mint failed:`, err);
13976
14163
  }
13977
14164
  }
13978
14165
  if (options.discoverAddresses !== false && sphere._transport.discoverAddresses && sphere._masterKey) {
@@ -13981,10 +14168,10 @@ var Sphere = class _Sphere {
13981
14168
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13982
14169
  const result = await sphere.discoverAddresses(discoverOpts);
13983
14170
  if (result.addresses.length > 0) {
13984
- console.log(`[Sphere.load] Address discovery: found ${result.addresses.length} address(es)`);
14171
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
13985
14172
  }
13986
14173
  } catch (err) {
13987
- console.warn("[Sphere.load] Address discovery failed (non-fatal):", err);
14174
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
13988
14175
  }
13989
14176
  }
13990
14177
  progress?.({ step: "complete", message: "Wallet loaded" });
@@ -13994,24 +14181,25 @@ var Sphere = class _Sphere {
13994
14181
  * Import wallet from mnemonic or master key
13995
14182
  */
13996
14183
  static async import(options) {
14184
+ if (options.debug) logger.configure({ debug: true });
13997
14185
  if (!options.mnemonic && !options.masterKey) {
13998
- throw new Error("Either mnemonic or masterKey is required");
14186
+ throw new SphereError("Either mnemonic or masterKey is required", "INVALID_CONFIG");
13999
14187
  }
14000
14188
  const progress = options.onProgress;
14001
- console.log("[Sphere.import] Starting import...");
14189
+ logger.debug("Sphere", "Starting import...");
14002
14190
  const needsClear = _Sphere.instance !== null || await _Sphere.exists(options.storage);
14003
14191
  if (needsClear) {
14004
14192
  progress?.({ step: "clearing", message: "Clearing previous wallet data..." });
14005
- console.log("[Sphere.import] Clearing existing wallet data...");
14193
+ logger.debug("Sphere", "Clearing existing wallet data...");
14006
14194
  await _Sphere.clear({ storage: options.storage, tokenStorage: options.tokenStorage });
14007
- console.log("[Sphere.import] Clear done");
14195
+ logger.debug("Sphere", "Clear done");
14008
14196
  } else {
14009
- console.log("[Sphere.import] No existing wallet \u2014 skipping clear");
14197
+ logger.debug("Sphere", "No existing wallet \u2014 skipping clear");
14010
14198
  }
14011
14199
  if (!options.storage.isConnected()) {
14012
- console.log("[Sphere.import] Reconnecting storage...");
14200
+ logger.debug("Sphere", "Reconnecting storage...");
14013
14201
  await options.storage.connect();
14014
- console.log("[Sphere.import] Storage reconnected");
14202
+ logger.debug("Sphere", "Storage reconnected");
14015
14203
  }
14016
14204
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat);
14017
14205
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -14029,14 +14217,14 @@ var Sphere = class _Sphere {
14029
14217
  progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
14030
14218
  if (options.mnemonic) {
14031
14219
  if (!_Sphere.validateMnemonic(options.mnemonic)) {
14032
- throw new Error("Invalid mnemonic");
14220
+ throw new SphereError("Invalid mnemonic", "INVALID_IDENTITY");
14033
14221
  }
14034
- console.log("[Sphere.import] Storing mnemonic...");
14222
+ logger.debug("Sphere", "Storing mnemonic...");
14035
14223
  await sphere.storeMnemonic(options.mnemonic, options.derivationPath, options.basePath);
14036
- console.log("[Sphere.import] Initializing identity from mnemonic...");
14224
+ logger.debug("Sphere", "Initializing identity from mnemonic...");
14037
14225
  await sphere.initializeIdentityFromMnemonic(options.mnemonic, options.derivationPath);
14038
14226
  } else if (options.masterKey) {
14039
- console.log("[Sphere.import] Storing master key...");
14227
+ logger.debug("Sphere", "Storing master key...");
14040
14228
  await sphere.storeMasterKey(
14041
14229
  options.masterKey,
14042
14230
  options.chainCode,
@@ -14044,7 +14232,7 @@ var Sphere = class _Sphere {
14044
14232
  options.basePath,
14045
14233
  options.derivationMode
14046
14234
  );
14047
- console.log("[Sphere.import] Initializing identity from master key...");
14235
+ logger.debug("Sphere", "Initializing identity from master key...");
14048
14236
  await sphere.initializeIdentityFromMasterKey(
14049
14237
  options.masterKey,
14050
14238
  options.chainCode,
@@ -14052,38 +14240,38 @@ var Sphere = class _Sphere {
14052
14240
  );
14053
14241
  }
14054
14242
  progress?.({ step: "initializing", message: "Initializing wallet..." });
14055
- console.log("[Sphere.import] Initializing providers...");
14243
+ logger.debug("Sphere", "Initializing providers...");
14056
14244
  await sphere.initializeProviders();
14057
- console.log("[Sphere.import] Providers initialized. Initializing modules...");
14245
+ logger.debug("Sphere", "Providers initialized. Initializing modules...");
14058
14246
  await sphere.initializeModules();
14059
- console.log("[Sphere.import] Modules initialized");
14247
+ logger.debug("Sphere", "Modules initialized");
14060
14248
  if (!options.nametag) {
14061
14249
  progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
14062
- console.log("[Sphere.import] Recovering nametag from transport...");
14250
+ logger.debug("Sphere", "Recovering nametag from transport...");
14063
14251
  await sphere.recoverNametagFromTransport();
14064
- console.log("[Sphere.import] Nametag recovery done");
14252
+ logger.debug("Sphere", "Nametag recovery done");
14065
14253
  progress?.({ step: "syncing_identity", message: "Publishing identity..." });
14066
14254
  await sphere.syncIdentityWithTransport();
14067
14255
  }
14068
14256
  progress?.({ step: "finalizing", message: "Finalizing wallet..." });
14069
- console.log("[Sphere.import] Finalizing wallet creation...");
14257
+ logger.debug("Sphere", "Finalizing wallet creation...");
14070
14258
  await sphere.finalizeWalletCreation();
14071
14259
  sphere._initialized = true;
14072
14260
  _Sphere.instance = sphere;
14073
- console.log("[Sphere.import] Tracking address 0...");
14261
+ logger.debug("Sphere", "Tracking address 0...");
14074
14262
  await sphere.ensureAddressTracked(0);
14075
14263
  if (options.nametag) {
14076
14264
  progress?.({ step: "registering_nametag", message: "Registering nametag..." });
14077
- console.log("[Sphere.import] Registering nametag...");
14265
+ logger.debug("Sphere", "Registering nametag...");
14078
14266
  await sphere.registerNametag(options.nametag);
14079
14267
  }
14080
14268
  if (sphere._tokenStorageProviders.size > 0) {
14081
14269
  progress?.({ step: "syncing_tokens", message: "Syncing tokens..." });
14082
14270
  try {
14083
14271
  const syncResult = await sphere._payments.sync();
14084
- console.log(`[Sphere.import] Auto-sync: +${syncResult.added} -${syncResult.removed}`);
14272
+ logger.debug("Sphere", `Auto-sync: +${syncResult.added} -${syncResult.removed}`);
14085
14273
  } catch (err) {
14086
- console.warn("[Sphere.import] Auto-sync failed (non-fatal):", err);
14274
+ logger.warn("Sphere", "Auto-sync failed (non-fatal):", err);
14087
14275
  }
14088
14276
  }
14089
14277
  if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
@@ -14092,14 +14280,14 @@ var Sphere = class _Sphere {
14092
14280
  const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
14093
14281
  const result = await sphere.discoverAddresses(discoverOpts);
14094
14282
  if (result.addresses.length > 0) {
14095
- console.log(`[Sphere.import] Address discovery: found ${result.addresses.length} address(es)`);
14283
+ logger.debug("Sphere", `Address discovery: found ${result.addresses.length} address(es)`);
14096
14284
  }
14097
14285
  } catch (err) {
14098
- console.warn("[Sphere.import] Address discovery failed (non-fatal):", err);
14286
+ logger.warn("Sphere", "Address discovery failed (non-fatal):", err);
14099
14287
  }
14100
14288
  }
14101
14289
  progress?.({ step: "complete", message: "Import complete" });
14102
- console.log("[Sphere.import] Import complete");
14290
+ logger.debug("Sphere", "Import complete");
14103
14291
  return sphere;
14104
14292
  }
14105
14293
  /**
@@ -14125,26 +14313,26 @@ var Sphere = class _Sphere {
14125
14313
  const storage = "get" in storageOrOptions ? storageOrOptions : storageOrOptions.storage;
14126
14314
  const tokenStorage = "get" in storageOrOptions ? void 0 : storageOrOptions.tokenStorage;
14127
14315
  if (_Sphere.instance) {
14128
- console.log("[Sphere.clear] Destroying Sphere instance...");
14316
+ logger.debug("Sphere", "Destroying Sphere instance...");
14129
14317
  await _Sphere.instance.destroy();
14130
- console.log("[Sphere.clear] Sphere instance destroyed");
14318
+ logger.debug("Sphere", "Sphere instance destroyed");
14131
14319
  }
14132
- console.log("[Sphere.clear] Clearing L1 vesting cache...");
14320
+ logger.debug("Sphere", "Clearing L1 vesting cache...");
14133
14321
  await vestingClassifier.destroy();
14134
- console.log("[Sphere.clear] Yielding 50ms for IDB transaction settlement...");
14322
+ logger.debug("Sphere", "Yielding 50ms for IDB transaction settlement...");
14135
14323
  await new Promise((r) => setTimeout(r, 50));
14136
14324
  if (tokenStorage?.clear) {
14137
- console.log("[Sphere.clear] Clearing token storage...");
14325
+ logger.debug("Sphere", "Clearing token storage...");
14138
14326
  try {
14139
14327
  await tokenStorage.clear();
14140
- console.log("[Sphere.clear] Token storage cleared");
14328
+ logger.debug("Sphere", "Token storage cleared");
14141
14329
  } catch (err) {
14142
- console.warn("[Sphere.clear] Token storage clear failed:", err);
14330
+ logger.warn("Sphere", "Token storage clear failed:", err);
14143
14331
  }
14144
14332
  } else {
14145
- console.log("[Sphere.clear] No token storage provider to clear");
14333
+ logger.debug("Sphere", "No token storage provider to clear");
14146
14334
  }
14147
- console.log("[Sphere.clear] Clearing KV storage...");
14335
+ logger.debug("Sphere", "Clearing KV storage...");
14148
14336
  if (!storage.isConnected()) {
14149
14337
  try {
14150
14338
  await storage.connect();
@@ -14153,11 +14341,11 @@ var Sphere = class _Sphere {
14153
14341
  }
14154
14342
  if (storage.isConnected()) {
14155
14343
  await storage.clear();
14156
- console.log("[Sphere.clear] KV storage cleared");
14344
+ logger.debug("Sphere", "KV storage cleared");
14157
14345
  } else {
14158
- console.log("[Sphere.clear] KV storage not connected, skipping");
14346
+ logger.debug("Sphere", "KV storage not connected, skipping");
14159
14347
  }
14160
- console.log("[Sphere.clear] Done");
14348
+ logger.debug("Sphere", "Done");
14161
14349
  }
14162
14350
  /**
14163
14351
  * Get current instance
@@ -14249,7 +14437,7 @@ var Sphere = class _Sphere {
14249
14437
  */
14250
14438
  async addTokenStorageProvider(provider) {
14251
14439
  if (this._tokenStorageProviders.has(provider.id)) {
14252
- throw new Error(`Token storage provider '${provider.id}' already exists`);
14440
+ throw new SphereError(`Token storage provider '${provider.id}' already exists`, "INVALID_CONFIG");
14253
14441
  }
14254
14442
  if (this._identity) {
14255
14443
  provider.setIdentity(this._identity);
@@ -14369,7 +14557,7 @@ var Sphere = class _Sphere {
14369
14557
  exportToJSON(options = {}) {
14370
14558
  this.ensureReady();
14371
14559
  if (!this._masterKey && !this._identity) {
14372
- throw new Error("Wallet not initialized");
14560
+ throw new SphereError("Wallet not initialized", "NOT_INITIALIZED");
14373
14561
  }
14374
14562
  const addressCount = options.addressCount || 1;
14375
14563
  const addresses = [];
@@ -14449,7 +14637,7 @@ var Sphere = class _Sphere {
14449
14637
  exportToTxt(options = {}) {
14450
14638
  this.ensureReady();
14451
14639
  if (!this._masterKey && !this._identity) {
14452
- throw new Error("Wallet not initialized");
14640
+ throw new SphereError("Wallet not initialized", "NOT_INITIALIZED");
14453
14641
  }
14454
14642
  const addressCount = options.addressCount || 1;
14455
14643
  const addresses = [];
@@ -14888,7 +15076,7 @@ var Sphere = class _Sphere {
14888
15076
  this.ensureReady();
14889
15077
  const entry = this._trackedAddresses.get(index);
14890
15078
  if (!entry) {
14891
- throw new Error(`Address at index ${index} is not tracked. Switch to it first.`);
15079
+ throw new SphereError(`Address at index ${index} is not tracked. Switch to it first.`, "INVALID_CONFIG");
14892
15080
  }
14893
15081
  if (entry.hidden === hidden) return;
14894
15082
  entry.hidden = hidden;
@@ -14918,14 +15106,14 @@ var Sphere = class _Sphere {
14918
15106
  async switchToAddress(index, options) {
14919
15107
  this.ensureReady();
14920
15108
  if (!this._masterKey) {
14921
- throw new Error("HD derivation requires master key with chain code. Cannot switch addresses.");
15109
+ throw new SphereError("HD derivation requires master key with chain code. Cannot switch addresses.", "INVALID_CONFIG");
14922
15110
  }
14923
15111
  if (index < 0) {
14924
- throw new Error("Address index must be non-negative");
15112
+ throw new SphereError("Address index must be non-negative", "INVALID_CONFIG");
14925
15113
  }
14926
15114
  const newNametag = options?.nametag ? this.cleanNametag(options.nametag) : void 0;
14927
15115
  if (newNametag && !isValidNametag(newNametag)) {
14928
- throw new Error("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.");
15116
+ throw new SphereError("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.", "VALIDATION_ERROR");
14929
15117
  }
14930
15118
  const addressInfo = this.deriveAddress(index, false);
14931
15119
  const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
@@ -14935,7 +15123,7 @@ var Sphere = class _Sphere {
14935
15123
  if (newNametag) {
14936
15124
  const existing = await this._transport.resolveNametag?.(newNametag);
14937
15125
  if (existing) {
14938
- throw new Error(`Nametag @${newNametag} is already taken`);
15126
+ throw new SphereError(`Nametag @${newNametag} is already taken`, "VALIDATION_ERROR");
14939
15127
  }
14940
15128
  let nametags = this._addressNametags.get(addressId);
14941
15129
  if (!nametags) {
@@ -14958,12 +15146,12 @@ var Sphere = class _Sphere {
14958
15146
  await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
14959
15147
  this._storage.setIdentity(this._identity);
14960
15148
  await this._transport.setIdentity(this._identity);
14961
- console.log(`[Sphere] switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
15149
+ logger.debug("Sphere", `switchToAddress(${index}): re-initializing ${this._tokenStorageProviders.size} token storage provider(s)`);
14962
15150
  for (const [providerId, provider] of this._tokenStorageProviders.entries()) {
14963
- console.log(`[Sphere] switchToAddress(${index}): shutdown provider=${providerId}`);
15151
+ logger.debug("Sphere", `switchToAddress(${index}): shutdown provider=${providerId}`);
14964
15152
  await provider.shutdown();
14965
15153
  provider.setIdentity(this._identity);
14966
- console.log(`[Sphere] switchToAddress(${index}): initialize provider=${providerId}`);
15154
+ logger.debug("Sphere", `switchToAddress(${index}): initialize provider=${providerId}`);
14967
15155
  await provider.initialize();
14968
15156
  }
14969
15157
  await this.reinitializeModulesForNewAddress();
@@ -14974,9 +15162,9 @@ var Sphere = class _Sphere {
14974
15162
  nametag: this._identity.nametag,
14975
15163
  addressIndex: index
14976
15164
  });
14977
- console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
15165
+ logger.debug("Sphere", `Switched to address ${index}:`, this._identity.l1Address);
14978
15166
  this.postSwitchSync(index, newNametag).catch((err) => {
14979
- console.warn(`[Sphere] Post-switch sync failed for address ${index}:`, err);
15167
+ logger.warn("Sphere", `Post-switch sync failed for address ${index}:`, err);
14980
15168
  });
14981
15169
  }
14982
15170
  /**
@@ -14990,16 +15178,16 @@ var Sphere = class _Sphere {
14990
15178
  if (newNametag) {
14991
15179
  await this.persistAddressNametags();
14992
15180
  if (!this._payments.hasNametag()) {
14993
- console.log(`[Sphere] Minting nametag token for @${newNametag}...`);
15181
+ logger.debug("Sphere", `Minting nametag token for @${newNametag}...`);
14994
15182
  try {
14995
15183
  const result = await this.mintNametag(newNametag);
14996
15184
  if (result.success) {
14997
- console.log(`[Sphere] Nametag token minted successfully`);
15185
+ logger.debug("Sphere", `Nametag token minted successfully`);
14998
15186
  } else {
14999
- console.warn(`[Sphere] Could not mint nametag token: ${result.error}`);
15187
+ logger.warn("Sphere", `Could not mint nametag token: ${result.error}`);
15000
15188
  }
15001
15189
  } catch (err) {
15002
- console.warn(`[Sphere] Nametag token mint failed:`, err);
15190
+ logger.warn("Sphere", `Nametag token mint failed:`, err);
15003
15191
  }
15004
15192
  }
15005
15193
  this.emitEvent("nametag:registered", {
@@ -15007,16 +15195,16 @@ var Sphere = class _Sphere {
15007
15195
  addressIndex: index
15008
15196
  });
15009
15197
  } else if (this._identity?.nametag && !this._payments.hasNametag()) {
15010
- console.log(`[Sphere] Nametag @${this._identity.nametag} has no token after switch, minting...`);
15198
+ logger.debug("Sphere", `Nametag @${this._identity.nametag} has no token after switch, minting...`);
15011
15199
  try {
15012
15200
  const result = await this.mintNametag(this._identity.nametag);
15013
15201
  if (result.success) {
15014
- console.log(`[Sphere] Nametag token minted successfully after switch`);
15202
+ logger.debug("Sphere", `Nametag token minted successfully after switch`);
15015
15203
  } else {
15016
- console.warn(`[Sphere] Could not mint nametag token after switch: ${result.error}`);
15204
+ logger.warn("Sphere", `Could not mint nametag token after switch: ${result.error}`);
15017
15205
  }
15018
15206
  } catch (err) {
15019
- console.warn(`[Sphere] Nametag token mint failed after switch:`, err);
15207
+ logger.warn("Sphere", `Nametag token mint failed after switch:`, err);
15020
15208
  }
15021
15209
  }
15022
15210
  }
@@ -15055,7 +15243,7 @@ var Sphere = class _Sphere {
15055
15243
  await this._groupChat?.load();
15056
15244
  await this._market?.load();
15057
15245
  this._payments.sync().catch((err) => {
15058
- console.warn("[Sphere] Post-switch sync failed:", err);
15246
+ logger.warn("Sphere", "Post-switch sync failed:", err);
15059
15247
  });
15060
15248
  }
15061
15249
  /**
@@ -15089,7 +15277,7 @@ var Sphere = class _Sphere {
15089
15277
  */
15090
15278
  _deriveAddressInternal(index, isChange = false) {
15091
15279
  if (!this._masterKey) {
15092
- throw new Error("HD derivation requires master key with chain code");
15280
+ throw new SphereError("HD derivation requires master key with chain code", "INVALID_CONFIG");
15093
15281
  }
15094
15282
  if (this._derivationMode === "wif_hmac") {
15095
15283
  return generateAddressFromMasterKey(this._masterKey.privateKey, index);
@@ -15119,7 +15307,7 @@ var Sphere = class _Sphere {
15119
15307
  deriveAddressAtPath(path) {
15120
15308
  this.ensureReady();
15121
15309
  if (!this._masterKey) {
15122
- throw new Error("HD derivation requires master key with chain code");
15310
+ throw new SphereError("HD derivation requires master key with chain code", "INVALID_CONFIG");
15123
15311
  }
15124
15312
  const match = path.match(/\/(\d+)$/);
15125
15313
  const index = match ? parseInt(match[1], 10) : 0;
@@ -15186,13 +15374,14 @@ var Sphere = class _Sphere {
15186
15374
  async scanAddresses(options = {}) {
15187
15375
  this.ensureReady();
15188
15376
  if (!this._masterKey) {
15189
- throw new Error("Address scanning requires HD master key");
15377
+ throw new SphereError("Address scanning requires HD master key", "INVALID_CONFIG");
15190
15378
  }
15191
15379
  const resolveNametag = options.resolveNametag ?? (this._transport.resolveAddressInfo ? async (l1Address) => {
15192
15380
  try {
15193
15381
  const info = await this._transport.resolveAddressInfo(l1Address);
15194
15382
  return info?.nametag ?? null;
15195
- } catch {
15383
+ } catch (err) {
15384
+ logger.debug("Sphere", "Nametag resolution failed during scan", err);
15196
15385
  return null;
15197
15386
  }
15198
15387
  } : void 0);
@@ -15243,10 +15432,10 @@ var Sphere = class _Sphere {
15243
15432
  async discoverAddresses(options = {}) {
15244
15433
  this.ensureReady();
15245
15434
  if (!this._masterKey) {
15246
- throw new Error("Address discovery requires HD master key");
15435
+ throw new SphereError("Address discovery requires HD master key", "INVALID_CONFIG");
15247
15436
  }
15248
15437
  if (!this._transport.discoverAddresses) {
15249
- throw new Error("Transport provider does not support address discovery");
15438
+ throw new SphereError("Transport provider does not support address discovery", "INVALID_CONFIG");
15250
15439
  }
15251
15440
  const includeL1Scan = options.includeL1Scan ?? true;
15252
15441
  const transportResult = await discoverAddressesImpl(
@@ -15302,7 +15491,7 @@ var Sphere = class _Sphere {
15302
15491
  }
15303
15492
  transportResult.addresses.sort((a, b) => a.index - b.index);
15304
15493
  } catch (err) {
15305
- console.warn("[Sphere] L1 scan failed during discovery (non-fatal):", err);
15494
+ logger.warn("Sphere", "L1 scan failed during discovery (non-fatal):", err);
15306
15495
  }
15307
15496
  }
15308
15497
  if (options.autoTrack && transportResult.addresses.length > 0) {
@@ -15400,7 +15589,7 @@ var Sphere = class _Sphere {
15400
15589
  */
15401
15590
  async disableProvider(providerId) {
15402
15591
  if (providerId === this._storage.id) {
15403
- throw new Error("Cannot disable the main storage provider");
15592
+ throw new SphereError("Cannot disable the main storage provider", "INVALID_CONFIG");
15404
15593
  }
15405
15594
  const provider = this.findProviderById(providerId);
15406
15595
  if (!provider) return false;
@@ -15603,10 +15792,10 @@ var Sphere = class _Sphere {
15603
15792
  this.ensureReady();
15604
15793
  const cleanNametag = this.cleanNametag(nametag);
15605
15794
  if (!isValidNametag(cleanNametag)) {
15606
- throw new Error("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.");
15795
+ throw new SphereError("Invalid nametag format. Use lowercase alphanumeric, underscore, or hyphen (3-20 chars), or a valid phone number.", "VALIDATION_ERROR");
15607
15796
  }
15608
15797
  if (this._identity?.nametag) {
15609
- throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
15798
+ throw new SphereError(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`, "ALREADY_INITIALIZED");
15610
15799
  }
15611
15800
  if (this._transport.publishIdentityBinding) {
15612
15801
  const success = await this._transport.publishIdentityBinding(
@@ -15616,7 +15805,7 @@ var Sphere = class _Sphere {
15616
15805
  cleanNametag
15617
15806
  );
15618
15807
  if (!success) {
15619
- throw new Error("Failed to register nametag. It may already be taken.");
15808
+ throw new SphereError("Failed to register nametag. It may already be taken.", "VALIDATION_ERROR");
15620
15809
  }
15621
15810
  }
15622
15811
  this._identity.nametag = cleanNametag;
@@ -15632,19 +15821,19 @@ var Sphere = class _Sphere {
15632
15821
  }
15633
15822
  await this.persistAddressNametags();
15634
15823
  if (!this._payments.hasNametag()) {
15635
- console.log(`[Sphere] Minting nametag token for @${cleanNametag}...`);
15824
+ logger.debug("Sphere", `Minting nametag token for @${cleanNametag}...`);
15636
15825
  const result = await this.mintNametag(cleanNametag);
15637
15826
  if (!result.success) {
15638
- console.warn(`[Sphere] Failed to mint nametag token: ${result.error}`);
15827
+ logger.warn("Sphere", `Failed to mint nametag token: ${result.error}`);
15639
15828
  } else {
15640
- console.log(`[Sphere] Nametag token minted successfully`);
15829
+ logger.debug("Sphere", `Nametag token minted successfully`);
15641
15830
  }
15642
15831
  }
15643
15832
  this.emitEvent("nametag:registered", {
15644
15833
  nametag: cleanNametag,
15645
15834
  addressIndex: this._currentAddressIndex
15646
15835
  });
15647
- console.log(`[Sphere] Nametag registered for address ${this._currentAddressIndex}:`, cleanNametag);
15836
+ logger.debug("Sphere", `Nametag registered for address ${this._currentAddressIndex}:`, cleanNametag);
15648
15837
  }
15649
15838
  /**
15650
15839
  * Persist tracked addresses to storage (only minimal fields via StorageProvider)
@@ -15884,13 +16073,13 @@ var Sphere = class _Sphere {
15884
16073
  this._identity.directAddress || "",
15885
16074
  recoveredNametag
15886
16075
  );
15887
- console.log(`[Sphere] Migrated legacy binding with nametag @${recoveredNametag}`);
16076
+ logger.debug("Sphere", `Migrated legacy binding with nametag @${recoveredNametag}`);
15888
16077
  return;
15889
16078
  }
15890
16079
  }
15891
16080
  const needsUpdate = !existing.directAddress || !existing.l1Address || !existing.chainPubkey || this._identity?.nametag && !existing.nametag;
15892
16081
  if (needsUpdate) {
15893
- console.log("[Sphere] Existing binding incomplete, re-publishing with full data");
16082
+ logger.debug("Sphere", "Existing binding incomplete, re-publishing with full data");
15894
16083
  await this._transport.publishIdentityBinding(
15895
16084
  this._identity.chainPubkey,
15896
16085
  this._identity.l1Address,
@@ -15899,11 +16088,11 @@ var Sphere = class _Sphere {
15899
16088
  );
15900
16089
  return;
15901
16090
  }
15902
- console.log("[Sphere] Existing binding found, skipping re-publish");
16091
+ logger.debug("Sphere", "Existing binding found, skipping re-publish");
15903
16092
  return;
15904
16093
  }
15905
16094
  } catch (e) {
15906
- console.warn("[Sphere] resolve() failed, skipping publish to avoid overwrite", e);
16095
+ logger.warn("Sphere", "resolve() failed, skipping publish to avoid overwrite", e);
15907
16096
  return;
15908
16097
  }
15909
16098
  }
@@ -15915,12 +16104,12 @@ var Sphere = class _Sphere {
15915
16104
  nametag || void 0
15916
16105
  );
15917
16106
  if (success) {
15918
- console.log(`[Sphere] Identity binding published${nametag ? ` with nametag @${nametag}` : ""}`);
16107
+ logger.debug("Sphere", `Identity binding published${nametag ? ` with nametag @${nametag}` : ""}`);
15919
16108
  } else if (nametag) {
15920
- console.warn(`[Sphere] Nametag @${nametag} is taken by another pubkey`);
16109
+ logger.warn("Sphere", `Nametag @${nametag} is taken by another pubkey`);
15921
16110
  }
15922
16111
  } catch (error) {
15923
- console.warn(`[Sphere] Identity binding sync failed:`, error);
16112
+ logger.warn("Sphere", `Identity binding sync failed:`, error);
15924
16113
  }
15925
16114
  }
15926
16115
  /**
@@ -16073,7 +16262,7 @@ var Sphere = class _Sphere {
16073
16262
  if (encryptedMnemonic) {
16074
16263
  const mnemonic = this.decrypt(encryptedMnemonic);
16075
16264
  if (!mnemonic) {
16076
- throw new Error("Failed to decrypt mnemonic");
16265
+ throw new SphereError("Failed to decrypt mnemonic", "STORAGE_ERROR");
16077
16266
  }
16078
16267
  this._mnemonic = mnemonic;
16079
16268
  this._source = "mnemonic";
@@ -16081,7 +16270,7 @@ var Sphere = class _Sphere {
16081
16270
  } else if (encryptedMasterKey) {
16082
16271
  const masterKey = this.decrypt(encryptedMasterKey);
16083
16272
  if (!masterKey) {
16084
- throw new Error("Failed to decrypt master key");
16273
+ throw new SphereError("Failed to decrypt master key", "STORAGE_ERROR");
16085
16274
  }
16086
16275
  this._mnemonic = null;
16087
16276
  if (this._source === "unknown") {
@@ -16093,7 +16282,7 @@ var Sphere = class _Sphere {
16093
16282
  derivationPath ?? void 0
16094
16283
  );
16095
16284
  } else {
16096
- throw new Error("No wallet data found in storage");
16285
+ throw new SphereError("No wallet data found in storage", "NOT_INITIALIZED");
16097
16286
  }
16098
16287
  if (this._identity) {
16099
16288
  this._storage.setIdentity(this._identity);
@@ -16115,7 +16304,7 @@ var Sphere = class _Sphere {
16115
16304
  nametag
16116
16305
  };
16117
16306
  this._storage.setIdentity(this._identity);
16118
- console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
16307
+ logger.debug("Sphere", `Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
16119
16308
  } else if (this._identity && nametag) {
16120
16309
  this._identity.nametag = nametag;
16121
16310
  }
@@ -16306,7 +16495,7 @@ var Sphere = class _Sphere {
16306
16495
  // ===========================================================================
16307
16496
  ensureReady() {
16308
16497
  if (!this._initialized) {
16309
- throw new Error("Sphere not initialized");
16498
+ throw new SphereError("Sphere not initialized", "NOT_INITIALIZED");
16310
16499
  }
16311
16500
  }
16312
16501
  emitEvent(type, data) {
@@ -16316,7 +16505,7 @@ var Sphere = class _Sphere {
16316
16505
  try {
16317
16506
  handler(data);
16318
16507
  } catch (error) {
16319
- console.error("[Sphere] Event handler error:", error);
16508
+ logger.error("Sphere", "Event handler error:", error);
16320
16509
  }
16321
16510
  }
16322
16511
  }
@@ -16353,6 +16542,7 @@ var getSphere = Sphere.getInstance.bind(Sphere);
16353
16542
  var sphereExists = Sphere.exists.bind(Sphere);
16354
16543
 
16355
16544
  // core/currency.ts
16545
+ init_logger();
16356
16546
  var DEFAULT_TOKEN_DECIMALS = 18;
16357
16547
  function toSmallestUnit(amount, decimals = DEFAULT_TOKEN_DECIMALS) {
16358
16548
  if (!amount) return 0n;
@@ -16361,7 +16551,8 @@ function toSmallestUnit(amount, decimals = DEFAULT_TOKEN_DECIMALS) {
16361
16551
  const [integer, fraction = ""] = str.split(".");
16362
16552
  const paddedFraction = fraction.padEnd(decimals, "0").slice(0, decimals);
16363
16553
  return BigInt(integer + paddedFraction);
16364
- } catch {
16554
+ } catch (err) {
16555
+ logger.debug("Currency", "toSmallestUnit conversion failed", err);
16365
16556
  return 0n;
16366
16557
  }
16367
16558
  }
@@ -16385,6 +16576,8 @@ function formatAmount(amount, options = {}) {
16385
16576
 
16386
16577
  // core/index.ts
16387
16578
  init_bech32();
16579
+ init_logger();
16580
+ init_errors();
16388
16581
 
16389
16582
  // core/network-health.ts
16390
16583
  init_constants();
@@ -16576,6 +16769,9 @@ async function runCustomCheck(name, checkFn, timeoutMs) {
16576
16769
  // index.ts
16577
16770
  init_constants();
16578
16771
 
16772
+ // types/index.ts
16773
+ init_errors();
16774
+
16579
16775
  // types/payment-session.ts
16580
16776
  function createPaymentSession(params) {
16581
16777
  const now = Date.now();
@@ -16635,22 +16831,11 @@ function createPaymentSessionError(code, message, recoverable = false, details)
16635
16831
  };
16636
16832
  }
16637
16833
 
16638
- // types/index.ts
16639
- var SphereError = class extends Error {
16640
- code;
16641
- cause;
16642
- constructor(message, code, cause) {
16643
- super(message);
16644
- this.name = "SphereError";
16645
- this.code = code;
16646
- this.cause = cause;
16647
- }
16648
- };
16649
-
16650
16834
  // index.ts
16651
16835
  init_constants();
16652
16836
 
16653
16837
  // validation/token-validator.ts
16838
+ init_logger();
16654
16839
  var TokenValidator = class {
16655
16840
  aggregatorClient = null;
16656
16841
  trustBase = null;
@@ -16775,7 +16960,7 @@ var TokenValidator = class {
16775
16960
  };
16776
16961
  }
16777
16962
  } catch (err) {
16778
- console.warn("SDK verification skipped:", err instanceof Error ? err.message : err);
16963
+ logger.warn("Validation", "SDK verification skipped:", err instanceof Error ? err.message : err);
16779
16964
  }
16780
16965
  }
16781
16966
  return { isValid: true };
@@ -16820,7 +17005,7 @@ var TokenValidator = class {
16820
17005
  });
16821
17006
  return isSpent;
16822
17007
  } catch (err) {
16823
- console.warn("Error checking token state:", err);
17008
+ logger.warn("Validation", "Error checking token state:", err);
16824
17009
  return false;
16825
17010
  }
16826
17011
  }
@@ -16978,6 +17163,8 @@ function createTokenValidator(options) {
16978
17163
  var import_nostr_js_sdk4 = require("@unicitylabs/nostr-js-sdk");
16979
17164
 
16980
17165
  // price/CoinGeckoPriceProvider.ts
17166
+ init_logger();
17167
+ init_errors();
16981
17168
  init_constants();
16982
17169
  var CoinGeckoPriceProvider = class {
16983
17170
  platform = "coingecko";
@@ -17029,7 +17216,7 @@ var CoinGeckoPriceProvider = class {
17029
17216
  const allCovered = uncachedNames.every((n) => this.fetchNames.has(n));
17030
17217
  if (allCovered) {
17031
17218
  if (this.debug) {
17032
- console.log(`[CoinGecko] Deduplicating request, reusing in-flight fetch`);
17219
+ logger.debug("CoinGecko", "Deduplicating request, reusing in-flight fetch");
17033
17220
  }
17034
17221
  const fetched = await this.fetchPromise;
17035
17222
  for (const name of uncachedNames) {
@@ -17068,7 +17255,7 @@ var CoinGeckoPriceProvider = class {
17068
17255
  headers["x-cg-pro-api-key"] = this.apiKey;
17069
17256
  }
17070
17257
  if (this.debug) {
17071
- console.log(`[CoinGecko] Fetching prices for: ${uncachedNames.join(", ")}`);
17258
+ logger.debug("CoinGecko", `Fetching prices for: ${uncachedNames.join(", ")}`);
17072
17259
  }
17073
17260
  const response = await fetch(url, {
17074
17261
  headers,
@@ -17078,7 +17265,7 @@ var CoinGeckoPriceProvider = class {
17078
17265
  if (response.status === 429) {
17079
17266
  this.extendCacheOnRateLimit(uncachedNames);
17080
17267
  }
17081
- throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`);
17268
+ throw new SphereError(`CoinGecko API error: ${response.status} ${response.statusText}`, "NETWORK_ERROR");
17082
17269
  }
17083
17270
  const data = await response.json();
17084
17271
  for (const [name, values] of Object.entries(data)) {
@@ -17108,12 +17295,12 @@ var CoinGeckoPriceProvider = class {
17108
17295
  }
17109
17296
  }
17110
17297
  if (this.debug) {
17111
- console.log(`[CoinGecko] Fetched ${result.size} prices`);
17298
+ logger.debug("CoinGecko", `Fetched ${result.size} prices`);
17112
17299
  }
17113
17300
  this.saveToStorage();
17114
17301
  } catch (error) {
17115
17302
  if (this.debug) {
17116
- console.warn("[CoinGecko] Fetch failed, using stale cache:", error);
17303
+ logger.warn("CoinGecko", "Fetch failed, using stale cache:", error);
17117
17304
  }
17118
17305
  for (const name of uncachedNames) {
17119
17306
  const stale = this.cache.get(name);
@@ -17163,7 +17350,7 @@ var CoinGeckoPriceProvider = class {
17163
17350
  }
17164
17351
  }
17165
17352
  if (this.debug) {
17166
- console.log(`[CoinGecko] Loaded ${Object.keys(data).length} prices from persistent cache`);
17353
+ logger.debug("CoinGecko", `Loaded ${Object.keys(data).length} prices from persistent cache`);
17167
17354
  }
17168
17355
  } catch {
17169
17356
  }
@@ -17180,8 +17367,7 @@ var CoinGeckoPriceProvider = class {
17180
17367
  Promise.all([
17181
17368
  this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE, JSON.stringify(data)),
17182
17369
  this.storage.set(STORAGE_KEYS_GLOBAL.PRICE_CACHE_TS, String(Date.now()))
17183
- ]).catch(() => {
17184
- });
17370
+ ]).catch((err) => logger.debug("Price", "Cache save failed (non-critical)", err));
17185
17371
  }
17186
17372
  // ===========================================================================
17187
17373
  // Rate-limit handling
@@ -17200,7 +17386,7 @@ var CoinGeckoPriceProvider = class {
17200
17386
  }
17201
17387
  }
17202
17388
  if (this.debug) {
17203
- console.warn(`[CoinGecko] Rate-limited (429), extended cache TTL by ${backoffMs / 1e3}s`);
17389
+ logger.warn("CoinGecko", `Rate-limited (429), extended cache TTL by ${backoffMs / 1e3}s`);
17204
17390
  }
17205
17391
  }
17206
17392
  async getPrice(tokenName) {
@@ -17213,12 +17399,13 @@ var CoinGeckoPriceProvider = class {
17213
17399
  };
17214
17400
 
17215
17401
  // price/index.ts
17402
+ init_errors();
17216
17403
  function createPriceProvider(config) {
17217
17404
  switch (config.platform) {
17218
17405
  case "coingecko":
17219
17406
  return new CoinGeckoPriceProvider(config);
17220
17407
  default:
17221
- throw new Error(`Unsupported price platform: ${String(config.platform)}`);
17408
+ throw new SphereError(`Unsupported price platform: ${String(config.platform)}`, "INVALID_CONFIG");
17222
17409
  }
17223
17410
  }
17224
17411
  // Annotate the CommonJS export names for ESM import in node:
@@ -17328,6 +17515,7 @@ function createPriceProvider(config) {
17328
17515
  isPaymentSessionTimedOut,
17329
17516
  isPhoneNumber,
17330
17517
  isSQLiteDatabase,
17518
+ isSphereError,
17331
17519
  isTextWalletEncrypted,
17332
17520
  isTokenKey,
17333
17521
  isValidBech32,
@@ -17338,6 +17526,7 @@ function createPriceProvider(config) {
17338
17526
  isWalletTextFormat,
17339
17527
  keyFromTokenId,
17340
17528
  loadSphere,
17529
+ logger,
17341
17530
  mnemonicToSeedSync,
17342
17531
  normalizeNametag,
17343
17532
  normalizeSdkTokenToStorage,