@unicitylabs/sphere-sdk 0.5.6 → 0.5.8

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.
@@ -93,7 +93,7 @@ interface CreateGroupOptions {
93
93
  * }
94
94
  * ```
95
95
  */
96
- type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'STORAGE_ERROR' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE';
96
+ type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'STORAGE_ERROR' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'SIGNING_ERROR';
97
97
  declare class SphereError extends Error {
98
98
  readonly code: SphereErrorCode;
99
99
  readonly cause?: unknown;
@@ -261,6 +261,34 @@ declare function deriveAddressInfo(masterKey: MasterKey, basePath: string, index
261
261
  * (L1 SDK compatibility)
262
262
  */
263
263
  declare function generateAddressInfo(privateKey: string, index: number, path: string, prefix?: string): AddressInfo;
264
+ /** Prefix prepended to all signed messages (Bitcoin-like signed message format) */
265
+ declare const SIGN_MESSAGE_PREFIX = "Sphere Signed Message:\n";
266
+ /**
267
+ * Hash a message for signing using the Bitcoin-like double-SHA256 scheme:
268
+ * SHA256(SHA256(varint(prefix.length) + prefix + varint(msg.length) + msg))
269
+ *
270
+ * @returns 64-char lowercase hex hash
271
+ */
272
+ declare function hashSignMessage(message: string): string;
273
+ /**
274
+ * Sign a message with a secp256k1 private key.
275
+ *
276
+ * Returns a 130-character hex string: v (2 chars) + r (64 chars) + s (64 chars).
277
+ * The recovery byte `v` is `31 + recoveryParam` (0-3).
278
+ *
279
+ * @param privateKeyHex - 64-char hex private key
280
+ * @param message - plaintext message to sign
281
+ */
282
+ declare function signMessage(privateKeyHex: string, message: string): string;
283
+ /**
284
+ * Verify a signed message against a compressed secp256k1 public key.
285
+ *
286
+ * @param message - The original plaintext message
287
+ * @param signature - 130-char hex signature (v + r + s)
288
+ * @param expectedPubkey - 66-char compressed public key hex
289
+ * @returns `true` if the signature is valid and matches the expected public key
290
+ */
291
+ declare function verifySignedMessage(message: string, signature: string, expectedPubkey: string): boolean;
264
292
 
265
293
  /**
266
294
  * TXF (Token eXchange Format) Type Definitions
@@ -3696,6 +3724,15 @@ declare class Sphere {
3696
3724
  get identity(): Identity | null;
3697
3725
  /** Is ready */
3698
3726
  get isReady(): boolean;
3727
+ /**
3728
+ * Sign a plaintext message with the wallet's secp256k1 private key.
3729
+ *
3730
+ * Returns a 130-character hex string: v (2) + r (64) + s (64).
3731
+ * The private key never leaves the SDK boundary.
3732
+ *
3733
+ * @throws SphereError if the wallet is not initialized or identity is missing
3734
+ */
3735
+ signMessage(message: string): string;
3699
3736
  getStorage(): StorageProvider;
3700
3737
  /**
3701
3738
  * Get first token storage provider (for backward compatibility)
@@ -4687,4 +4724,4 @@ interface CheckNetworkHealthOptions {
4687
4724
  */
4688
4725
  declare function checkNetworkHealth(network?: NetworkType, options?: CheckNetworkHealthOptions): Promise<NetworkHealthResult>;
4689
4726
 
4690
- export { type AddressInfo, CHARSET, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type L1Config, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isSphereError, isValidBech32, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic };
4727
+ export { type AddressInfo, CHARSET, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type L1Config, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, SIGN_MESSAGE_PREFIX, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isSphereError, isValidBech32, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic, verifySignedMessage };
@@ -93,7 +93,7 @@ interface CreateGroupOptions {
93
93
  * }
94
94
  * ```
95
95
  */
96
- type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'STORAGE_ERROR' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE';
96
+ type SphereErrorCode = 'NOT_INITIALIZED' | 'ALREADY_INITIALIZED' | 'INVALID_CONFIG' | 'INVALID_IDENTITY' | 'INSUFFICIENT_BALANCE' | 'INVALID_RECIPIENT' | 'TRANSFER_FAILED' | 'STORAGE_ERROR' | 'TRANSPORT_ERROR' | 'AGGREGATOR_ERROR' | 'VALIDATION_ERROR' | 'NETWORK_ERROR' | 'TIMEOUT' | 'DECRYPTION_ERROR' | 'MODULE_NOT_AVAILABLE' | 'SIGNING_ERROR';
97
97
  declare class SphereError extends Error {
98
98
  readonly code: SphereErrorCode;
99
99
  readonly cause?: unknown;
@@ -261,6 +261,34 @@ declare function deriveAddressInfo(masterKey: MasterKey, basePath: string, index
261
261
  * (L1 SDK compatibility)
262
262
  */
263
263
  declare function generateAddressInfo(privateKey: string, index: number, path: string, prefix?: string): AddressInfo;
264
+ /** Prefix prepended to all signed messages (Bitcoin-like signed message format) */
265
+ declare const SIGN_MESSAGE_PREFIX = "Sphere Signed Message:\n";
266
+ /**
267
+ * Hash a message for signing using the Bitcoin-like double-SHA256 scheme:
268
+ * SHA256(SHA256(varint(prefix.length) + prefix + varint(msg.length) + msg))
269
+ *
270
+ * @returns 64-char lowercase hex hash
271
+ */
272
+ declare function hashSignMessage(message: string): string;
273
+ /**
274
+ * Sign a message with a secp256k1 private key.
275
+ *
276
+ * Returns a 130-character hex string: v (2 chars) + r (64 chars) + s (64 chars).
277
+ * The recovery byte `v` is `31 + recoveryParam` (0-3).
278
+ *
279
+ * @param privateKeyHex - 64-char hex private key
280
+ * @param message - plaintext message to sign
281
+ */
282
+ declare function signMessage(privateKeyHex: string, message: string): string;
283
+ /**
284
+ * Verify a signed message against a compressed secp256k1 public key.
285
+ *
286
+ * @param message - The original plaintext message
287
+ * @param signature - 130-char hex signature (v + r + s)
288
+ * @param expectedPubkey - 66-char compressed public key hex
289
+ * @returns `true` if the signature is valid and matches the expected public key
290
+ */
291
+ declare function verifySignedMessage(message: string, signature: string, expectedPubkey: string): boolean;
264
292
 
265
293
  /**
266
294
  * TXF (Token eXchange Format) Type Definitions
@@ -3696,6 +3724,15 @@ declare class Sphere {
3696
3724
  get identity(): Identity | null;
3697
3725
  /** Is ready */
3698
3726
  get isReady(): boolean;
3727
+ /**
3728
+ * Sign a plaintext message with the wallet's secp256k1 private key.
3729
+ *
3730
+ * Returns a 130-character hex string: v (2) + r (64) + s (64).
3731
+ * The private key never leaves the SDK boundary.
3732
+ *
3733
+ * @throws SphereError if the wallet is not initialized or identity is missing
3734
+ */
3735
+ signMessage(message: string): string;
3699
3736
  getStorage(): StorageProvider;
3700
3737
  /**
3701
3738
  * Get first token storage provider (for backward compatibility)
@@ -4687,4 +4724,4 @@ interface CheckNetworkHealthOptions {
4687
4724
  */
4688
4725
  declare function checkNetworkHealth(network?: NetworkType, options?: CheckNetworkHealthOptions): Promise<NetworkHealthResult>;
4689
4726
 
4690
- export { type AddressInfo, CHARSET, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type L1Config, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isSphereError, isValidBech32, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic };
4727
+ export { type AddressInfo, CHARSET, type CheckNetworkHealthOptions, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type DiscoverAddressProgress, type DiscoverAddressesOptions, type DiscoverAddressesResult, type DiscoveredAddress, type EncryptedData, type EncryptionOptions, type InitProgress, type InitProgressCallback, type InitProgressStep, type KeyPair, type L1Config, type LogHandler, type LogLevel, type LoggerConfig, type MasterKey, SIGN_MESSAGE_PREFIX, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, checkNetworkHealth, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, discoverAddressesImpl, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hashSignMessage, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isSphereError, isValidBech32, isValidNametag, isValidPrivateKey, loadSphere, logger, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, signMessage, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic, verifySignedMessage };
@@ -955,6 +955,73 @@ function generateAddressInfo(privateKey, index, path, prefix = "alpha") {
955
955
  index
956
956
  };
957
957
  }
958
+ var SIGN_MESSAGE_PREFIX = "Sphere Signed Message:\n";
959
+ function varint(n) {
960
+ if (n < 253) return new Uint8Array([n]);
961
+ const buf = new Uint8Array(3);
962
+ buf[0] = 253;
963
+ buf[1] = n & 255;
964
+ buf[2] = n >> 8 & 255;
965
+ return buf;
966
+ }
967
+ function hashSignMessage(message) {
968
+ const prefix = new TextEncoder().encode(SIGN_MESSAGE_PREFIX);
969
+ const msg = new TextEncoder().encode(message);
970
+ const prefixLen = varint(prefix.length);
971
+ const msgLen = varint(msg.length);
972
+ const full = new Uint8Array(prefixLen.length + prefix.length + msgLen.length + msg.length);
973
+ let off = 0;
974
+ full.set(prefixLen, off);
975
+ off += prefixLen.length;
976
+ full.set(prefix, off);
977
+ off += prefix.length;
978
+ full.set(msgLen, off);
979
+ off += msgLen.length;
980
+ full.set(msg, off);
981
+ const hex = Array.from(full).map((b) => b.toString(16).padStart(2, "0")).join("");
982
+ const h1 = CryptoJS2.SHA256(CryptoJS2.enc.Hex.parse(hex)).toString();
983
+ return CryptoJS2.SHA256(CryptoJS2.enc.Hex.parse(h1)).toString();
984
+ }
985
+ function signMessage(privateKeyHex, message) {
986
+ const keyPair = ec.keyFromPrivate(privateKeyHex, "hex");
987
+ const hashHex = hashSignMessage(message);
988
+ const hashBytes = Buffer.from(hashHex, "hex");
989
+ const sig = keyPair.sign(hashBytes, { canonical: true });
990
+ const pub = keyPair.getPublic();
991
+ let recoveryParam = -1;
992
+ for (let i = 0; i < 4; i++) {
993
+ try {
994
+ if (ec.recoverPubKey(hashBytes, sig, i).eq(pub)) {
995
+ recoveryParam = i;
996
+ break;
997
+ }
998
+ } catch {
999
+ }
1000
+ }
1001
+ if (recoveryParam === -1) {
1002
+ throw new SphereError("Could not find recovery parameter", "SIGNING_ERROR");
1003
+ }
1004
+ const v = (31 + recoveryParam).toString(16).padStart(2, "0");
1005
+ const r = sig.r.toString("hex").padStart(64, "0");
1006
+ const s = sig.s.toString("hex").padStart(64, "0");
1007
+ return v + r + s;
1008
+ }
1009
+ function verifySignedMessage(message, signature, expectedPubkey) {
1010
+ if (signature.length !== 130) return false;
1011
+ const v = parseInt(signature.slice(0, 2), 16) - 31;
1012
+ const r = signature.slice(2, 66);
1013
+ const s = signature.slice(66, 130);
1014
+ if (v < 0 || v > 3) return false;
1015
+ const hashHex = hashSignMessage(message);
1016
+ const hashBytes = Buffer.from(hashHex, "hex");
1017
+ try {
1018
+ const recovered = ec.recoverPubKey(hashBytes, { r, s }, v);
1019
+ const recoveredHex = recovered.encode("hex", true);
1020
+ return recoveredHex === expectedPubkey;
1021
+ } catch {
1022
+ return false;
1023
+ }
1024
+ }
958
1025
 
959
1026
  // l1/crypto.ts
960
1027
  import CryptoJS3 from "crypto-js";
@@ -8889,13 +8956,16 @@ var GroupChatModule = class {
8889
8956
  logger.error("GroupChat", "Max reconnection attempts reached");
8890
8957
  return;
8891
8958
  }
8959
+ const maxDelay = this.config.reconnectDelayMs * 16;
8960
+ const delay = Math.min(this.config.reconnectDelayMs * Math.pow(2, this.reconnectAttempts), maxDelay);
8892
8961
  this.reconnectAttempts++;
8962
+ logger.debug("GroupChat", `Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`);
8893
8963
  this.reconnectTimer = setTimeout(() => {
8894
8964
  this.reconnectTimer = null;
8895
8965
  if (this.deps) {
8896
8966
  this.connect().catch((err) => logger.error("GroupChat", "Reconnect failed:", err));
8897
8967
  }
8898
- }, this.config.reconnectDelayMs);
8968
+ }, delay);
8899
8969
  }
8900
8970
  // ===========================================================================
8901
8971
  // Subscription Management
@@ -12232,6 +12302,7 @@ var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha2564);
12232
12302
 
12233
12303
  // modules/market/MarketModule.ts
12234
12304
  init_errors();
12305
+ init_logger();
12235
12306
  var DEFAULT_MARKET_API_URL = "https://market-api.unicity.network";
12236
12307
  function hexToBytes3(hex) {
12237
12308
  const len = hex.length >> 1;
@@ -12404,16 +12475,54 @@ var MarketModule = class {
12404
12475
  */
12405
12476
  subscribeFeed(listener) {
12406
12477
  const wsUrl = this.apiUrl.replace(/^http/, "ws") + "/ws/feed";
12407
- const ws2 = new WebSocket(wsUrl);
12408
- ws2.onmessage = (event) => {
12409
- try {
12410
- const raw = JSON.parse(typeof event.data === "string" ? event.data : event.data.toString());
12411
- listener(mapFeedMessage(raw));
12412
- } catch {
12478
+ const BASE_DELAY2 = 2e3;
12479
+ const MAX_DELAY2 = 3e4;
12480
+ const MAX_ATTEMPTS = 10;
12481
+ let ws2 = null;
12482
+ let reconnectAttempts2 = 0;
12483
+ let reconnectTimer = null;
12484
+ let destroyed = false;
12485
+ function connect2() {
12486
+ if (destroyed) return;
12487
+ ws2 = new WebSocket(wsUrl);
12488
+ ws2.onopen = () => {
12489
+ reconnectAttempts2 = 0;
12490
+ logger.debug("Market", "Feed WebSocket connected");
12491
+ };
12492
+ ws2.onmessage = (event) => {
12493
+ try {
12494
+ const raw = JSON.parse(typeof event.data === "string" ? event.data : event.data.toString());
12495
+ listener(mapFeedMessage(raw));
12496
+ } catch {
12497
+ }
12498
+ };
12499
+ ws2.onclose = () => {
12500
+ if (destroyed) return;
12501
+ scheduleReconnect();
12502
+ };
12503
+ ws2.onerror = () => {
12504
+ };
12505
+ }
12506
+ function scheduleReconnect() {
12507
+ if (destroyed) return;
12508
+ if (reconnectAttempts2 >= MAX_ATTEMPTS) {
12509
+ logger.warn("Market", `Feed WebSocket: gave up after ${MAX_ATTEMPTS} reconnect attempts`);
12510
+ return;
12413
12511
  }
12414
- };
12512
+ const delay = Math.min(BASE_DELAY2 * Math.pow(2, reconnectAttempts2), MAX_DELAY2);
12513
+ reconnectAttempts2++;
12514
+ logger.debug("Market", `Feed WebSocket reconnecting in ${delay}ms (attempt ${reconnectAttempts2}/${MAX_ATTEMPTS})`);
12515
+ reconnectTimer = setTimeout(connect2, delay);
12516
+ }
12517
+ connect2();
12415
12518
  return () => {
12416
- ws2.close();
12519
+ destroyed = true;
12520
+ if (reconnectTimer) {
12521
+ clearTimeout(reconnectTimer);
12522
+ reconnectTimer = null;
12523
+ }
12524
+ ws2?.close();
12525
+ ws2 = null;
12417
12526
  };
12418
12527
  }
12419
12528
  // ---------------------------------------------------------------------------
@@ -14042,6 +14151,23 @@ var Sphere = class _Sphere {
14042
14151
  return this._initialized;
14043
14152
  }
14044
14153
  // ===========================================================================
14154
+ // Public Methods - Signing
14155
+ // ===========================================================================
14156
+ /**
14157
+ * Sign a plaintext message with the wallet's secp256k1 private key.
14158
+ *
14159
+ * Returns a 130-character hex string: v (2) + r (64) + s (64).
14160
+ * The private key never leaves the SDK boundary.
14161
+ *
14162
+ * @throws SphereError if the wallet is not initialized or identity is missing
14163
+ */
14164
+ signMessage(message) {
14165
+ if (!this._identity?.privateKey) {
14166
+ throw new SphereError("Wallet not initialized \u2014 cannot sign", "NOT_INITIALIZED");
14167
+ }
14168
+ return signMessage(this._identity.privateKey, message);
14169
+ }
14170
+ // ===========================================================================
14045
14171
  // Public Methods - Providers Access
14046
14172
  // ===========================================================================
14047
14173
  getStorage() {
@@ -16405,6 +16531,7 @@ export {
16405
16531
  CurrencyUtils,
16406
16532
  DEFAULT_DERIVATION_PATH2 as DEFAULT_DERIVATION_PATH,
16407
16533
  DEFAULT_TOKEN_DECIMALS,
16534
+ SIGN_MESSAGE_PREFIX,
16408
16535
  Sphere,
16409
16536
  SphereError,
16410
16537
  base58Decode,
@@ -16447,6 +16574,7 @@ export {
16447
16574
  getSphere,
16448
16575
  hash160,
16449
16576
  hash160ToBytes,
16577
+ hashSignMessage,
16450
16578
  hexToBytes,
16451
16579
  identityFromMnemonic,
16452
16580
  identityFromMnemonicSync,
@@ -16471,11 +16599,13 @@ export {
16471
16599
  scanAddressesImpl,
16472
16600
  serializeEncrypted,
16473
16601
  sha256,
16602
+ signMessage,
16474
16603
  sleep,
16475
16604
  sphereExists,
16476
16605
  toHumanReadable,
16477
16606
  toSmallestUnit,
16478
- validateMnemonic2 as validateMnemonic
16607
+ validateMnemonic2 as validateMnemonic,
16608
+ verifySignedMessage
16479
16609
  };
16480
16610
  /*! Bundled license information:
16481
16611