@unicitylabs/sphere-sdk 0.4.7 → 0.4.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.
package/dist/index.js CHANGED
@@ -14,6 +14,228 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
+ // constants.ts
18
+ function getAddressStorageKey(addressId, key) {
19
+ return `${addressId}_${key}`;
20
+ }
21
+ function getAddressId(directAddress) {
22
+ let hash = directAddress;
23
+ if (hash.startsWith("DIRECT://")) {
24
+ hash = hash.slice(9);
25
+ } else if (hash.startsWith("DIRECT:")) {
26
+ hash = hash.slice(7);
27
+ }
28
+ const first = hash.slice(0, 6).toLowerCase();
29
+ const last = hash.slice(-6).toLowerCase();
30
+ return `DIRECT_${first}_${last}`;
31
+ }
32
+ var STORAGE_PREFIX, DEFAULT_ENCRYPTION_KEY, STORAGE_KEYS_GLOBAL, STORAGE_KEYS_ADDRESS, STORAGE_KEYS, DEFAULT_NOSTR_RELAYS, NOSTR_EVENT_KINDS, NIP29_KINDS, DEFAULT_AGGREGATOR_URL, DEV_AGGREGATOR_URL, TEST_AGGREGATOR_URL, DEFAULT_AGGREGATOR_TIMEOUT, DEFAULT_IPFS_GATEWAYS, DEFAULT_IPFS_BOOTSTRAP_PEERS, DEFAULT_BASE_PATH, DEFAULT_DERIVATION_PATH, COIN_TYPES, DEFAULT_ELECTRUM_URL, TEST_ELECTRUM_URL, TOKEN_REGISTRY_URL, TOKEN_REGISTRY_REFRESH_INTERVAL, TEST_NOSTR_RELAYS, DEFAULT_GROUP_RELAYS, NETWORKS, TIMEOUTS, LIMITS;
33
+ var init_constants = __esm({
34
+ "constants.ts"() {
35
+ "use strict";
36
+ STORAGE_PREFIX = "sphere_";
37
+ DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
38
+ STORAGE_KEYS_GLOBAL = {
39
+ /** Encrypted BIP39 mnemonic */
40
+ MNEMONIC: "mnemonic",
41
+ /** Encrypted master private key */
42
+ MASTER_KEY: "master_key",
43
+ /** BIP32 chain code */
44
+ CHAIN_CODE: "chain_code",
45
+ /** HD derivation path (full path like m/44'/0'/0'/0/0) */
46
+ DERIVATION_PATH: "derivation_path",
47
+ /** Base derivation path (like m/44'/0'/0' without chain/index) */
48
+ BASE_PATH: "base_path",
49
+ /** Derivation mode: bip32, wif_hmac, legacy_hmac */
50
+ DERIVATION_MODE: "derivation_mode",
51
+ /** Wallet source: mnemonic, file, unknown */
52
+ WALLET_SOURCE: "wallet_source",
53
+ /** Wallet existence flag */
54
+ WALLET_EXISTS: "wallet_exists",
55
+ /** Current active address index */
56
+ CURRENT_ADDRESS_INDEX: "current_address_index",
57
+ /** Nametag cache per address (separate from tracked addresses registry) */
58
+ ADDRESS_NAMETAGS: "address_nametags",
59
+ /** Active addresses registry (JSON: TrackedAddressesStorage) */
60
+ TRACKED_ADDRESSES: "tracked_addresses",
61
+ /** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
62
+ LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
63
+ /** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
64
+ GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
65
+ /** Cached token registry JSON (fetched from remote) */
66
+ TOKEN_REGISTRY_CACHE: "token_registry_cache",
67
+ /** Timestamp of last token registry cache update (ms since epoch) */
68
+ TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
69
+ /** Cached price data JSON (from CoinGecko or other provider) */
70
+ PRICE_CACHE: "price_cache",
71
+ /** Timestamp of last price cache update (ms since epoch) */
72
+ PRICE_CACHE_TS: "price_cache_ts"
73
+ };
74
+ STORAGE_KEYS_ADDRESS = {
75
+ /** Pending transfers for this address */
76
+ PENDING_TRANSFERS: "pending_transfers",
77
+ /** Transfer outbox for this address */
78
+ OUTBOX: "outbox",
79
+ /** Conversations for this address */
80
+ CONVERSATIONS: "conversations",
81
+ /** Messages for this address */
82
+ MESSAGES: "messages",
83
+ /** Transaction history for this address */
84
+ TRANSACTION_HISTORY: "transaction_history",
85
+ /** Pending V5 finalization tokens (unconfirmed instant split tokens) */
86
+ PENDING_V5_TOKENS: "pending_v5_tokens",
87
+ /** Group chat: joined groups for this address */
88
+ GROUP_CHAT_GROUPS: "group_chat_groups",
89
+ /** Group chat: messages for this address */
90
+ GROUP_CHAT_MESSAGES: "group_chat_messages",
91
+ /** Group chat: members for this address */
92
+ GROUP_CHAT_MEMBERS: "group_chat_members",
93
+ /** Group chat: processed event IDs for deduplication */
94
+ GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
95
+ };
96
+ STORAGE_KEYS = {
97
+ ...STORAGE_KEYS_GLOBAL,
98
+ ...STORAGE_KEYS_ADDRESS
99
+ };
100
+ DEFAULT_NOSTR_RELAYS = [
101
+ "wss://relay.unicity.network",
102
+ "wss://relay.damus.io",
103
+ "wss://nos.lol",
104
+ "wss://relay.nostr.band"
105
+ ];
106
+ NOSTR_EVENT_KINDS = {
107
+ /** NIP-04 encrypted direct message */
108
+ DIRECT_MESSAGE: 4,
109
+ /** Token transfer (Unicity custom - 31113) */
110
+ TOKEN_TRANSFER: 31113,
111
+ /** Payment request (Unicity custom - 31115) */
112
+ PAYMENT_REQUEST: 31115,
113
+ /** Payment request response (Unicity custom - 31116) */
114
+ PAYMENT_REQUEST_RESPONSE: 31116,
115
+ /** Nametag binding (NIP-78 app-specific data) */
116
+ NAMETAG_BINDING: 30078,
117
+ /** Public broadcast */
118
+ BROADCAST: 1
119
+ };
120
+ NIP29_KINDS = {
121
+ /** Chat message sent to group */
122
+ CHAT_MESSAGE: 9,
123
+ /** Thread root message */
124
+ THREAD_ROOT: 11,
125
+ /** Thread reply message */
126
+ THREAD_REPLY: 12,
127
+ /** User join request */
128
+ JOIN_REQUEST: 9021,
129
+ /** User leave request */
130
+ LEAVE_REQUEST: 9022,
131
+ /** Admin: add/update user */
132
+ PUT_USER: 9e3,
133
+ /** Admin: remove user */
134
+ REMOVE_USER: 9001,
135
+ /** Admin: edit group metadata */
136
+ EDIT_METADATA: 9002,
137
+ /** Admin: delete event */
138
+ DELETE_EVENT: 9005,
139
+ /** Admin: create group */
140
+ CREATE_GROUP: 9007,
141
+ /** Admin: delete group */
142
+ DELETE_GROUP: 9008,
143
+ /** Admin: create invite code */
144
+ CREATE_INVITE: 9009,
145
+ /** Relay-signed group metadata */
146
+ GROUP_METADATA: 39e3,
147
+ /** Relay-signed group admins */
148
+ GROUP_ADMINS: 39001,
149
+ /** Relay-signed group members */
150
+ GROUP_MEMBERS: 39002,
151
+ /** Relay-signed group roles */
152
+ GROUP_ROLES: 39003
153
+ };
154
+ DEFAULT_AGGREGATOR_URL = "https://aggregator.unicity.network/rpc";
155
+ DEV_AGGREGATOR_URL = "https://dev-aggregator.dyndns.org/rpc";
156
+ TEST_AGGREGATOR_URL = "https://goggregator-test.unicity.network";
157
+ DEFAULT_AGGREGATOR_TIMEOUT = 3e4;
158
+ DEFAULT_IPFS_GATEWAYS = [
159
+ "https://unicity-ipfs1.dyndns.org"
160
+ ];
161
+ DEFAULT_IPFS_BOOTSTRAP_PEERS = [
162
+ "/dns4/unicity-ipfs2.dyndns.org/tcp/4001/p2p/12D3KooWLNi5NDPPHbrfJakAQqwBqymYTTwMQXQKEWuCrJNDdmfh",
163
+ "/dns4/unicity-ipfs3.dyndns.org/tcp/4001/p2p/12D3KooWQ4aujVE4ShLjdusNZBdffq3TbzrwT2DuWZY9H1Gxhwn6",
164
+ "/dns4/unicity-ipfs4.dyndns.org/tcp/4001/p2p/12D3KooWJ1ByPfUzUrpYvgxKU8NZrR8i6PU1tUgMEbQX9Hh2DEn1",
165
+ "/dns4/unicity-ipfs5.dyndns.org/tcp/4001/p2p/12D3KooWB1MdZZGHN5B8TvWXntbycfe7Cjcz7n6eZ9eykZadvmDv"
166
+ ];
167
+ DEFAULT_BASE_PATH = "m/44'/0'/0'";
168
+ DEFAULT_DERIVATION_PATH = `${DEFAULT_BASE_PATH}/0/0`;
169
+ COIN_TYPES = {
170
+ /** ALPHA token (L1 blockchain) */
171
+ ALPHA: "ALPHA",
172
+ /** Test token */
173
+ TEST: "TEST"
174
+ };
175
+ DEFAULT_ELECTRUM_URL = "wss://fulcrum.unicity.network:50004";
176
+ TEST_ELECTRUM_URL = "wss://fulcrum.unicity.network:50004";
177
+ TOKEN_REGISTRY_URL = "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity-ids.testnet.json";
178
+ TOKEN_REGISTRY_REFRESH_INTERVAL = 36e5;
179
+ TEST_NOSTR_RELAYS = [
180
+ "wss://nostr-relay.testnet.unicity.network"
181
+ ];
182
+ DEFAULT_GROUP_RELAYS = [
183
+ "wss://sphere-relay.unicity.network"
184
+ ];
185
+ NETWORKS = {
186
+ mainnet: {
187
+ name: "Mainnet",
188
+ aggregatorUrl: DEFAULT_AGGREGATOR_URL,
189
+ nostrRelays: DEFAULT_NOSTR_RELAYS,
190
+ ipfsGateways: DEFAULT_IPFS_GATEWAYS,
191
+ electrumUrl: DEFAULT_ELECTRUM_URL,
192
+ groupRelays: DEFAULT_GROUP_RELAYS,
193
+ tokenRegistryUrl: TOKEN_REGISTRY_URL
194
+ },
195
+ testnet: {
196
+ name: "Testnet",
197
+ aggregatorUrl: TEST_AGGREGATOR_URL,
198
+ nostrRelays: TEST_NOSTR_RELAYS,
199
+ ipfsGateways: DEFAULT_IPFS_GATEWAYS,
200
+ electrumUrl: TEST_ELECTRUM_URL,
201
+ groupRelays: DEFAULT_GROUP_RELAYS,
202
+ tokenRegistryUrl: TOKEN_REGISTRY_URL
203
+ },
204
+ dev: {
205
+ name: "Development",
206
+ aggregatorUrl: DEV_AGGREGATOR_URL,
207
+ nostrRelays: TEST_NOSTR_RELAYS,
208
+ ipfsGateways: DEFAULT_IPFS_GATEWAYS,
209
+ electrumUrl: TEST_ELECTRUM_URL,
210
+ groupRelays: DEFAULT_GROUP_RELAYS,
211
+ tokenRegistryUrl: TOKEN_REGISTRY_URL
212
+ }
213
+ };
214
+ TIMEOUTS = {
215
+ /** WebSocket connection timeout */
216
+ WEBSOCKET_CONNECT: 1e4,
217
+ /** Nostr relay reconnect delay */
218
+ NOSTR_RECONNECT_DELAY: 3e3,
219
+ /** Max reconnect attempts */
220
+ MAX_RECONNECT_ATTEMPTS: 5,
221
+ /** Proof polling interval */
222
+ PROOF_POLL_INTERVAL: 1e3,
223
+ /** Sync interval */
224
+ SYNC_INTERVAL: 6e4
225
+ };
226
+ LIMITS = {
227
+ /** Min nametag length */
228
+ NAMETAG_MIN_LENGTH: 3,
229
+ /** Max nametag length */
230
+ NAMETAG_MAX_LENGTH: 20,
231
+ /** Max memo length */
232
+ MEMO_MAX_LENGTH: 500,
233
+ /** Max message length */
234
+ MESSAGE_MAX_LENGTH: 1e4
235
+ };
236
+ }
237
+ });
238
+
17
239
  // core/bech32.ts
18
240
  function convertBits(data, fromBits, toBits, pad) {
19
241
  let acc = 0;
@@ -430,7 +652,8 @@ var init_network = __esm({
430
652
  "l1/network.ts"() {
431
653
  "use strict";
432
654
  init_addressToScriptHash();
433
- DEFAULT_ENDPOINT = "wss://fulcrum.unicity.network:50004";
655
+ init_constants();
656
+ DEFAULT_ENDPOINT = DEFAULT_ELECTRUM_URL;
434
657
  ws = null;
435
658
  isConnected = false;
436
659
  isConnecting = false;
@@ -450,6 +673,9 @@ var init_network = __esm({
450
673
  }
451
674
  });
452
675
 
676
+ // modules/payments/L1PaymentsModule.ts
677
+ init_constants();
678
+
453
679
  // l1/index.ts
454
680
  var l1_exports = {};
455
681
  __export(l1_exports, {
@@ -1635,7 +1861,7 @@ var L1PaymentsModule = class {
1635
1861
  _transport;
1636
1862
  constructor(config) {
1637
1863
  this._config = {
1638
- electrumUrl: config?.electrumUrl ?? "wss://fulcrum.unicity.network:50004",
1864
+ electrumUrl: config?.electrumUrl ?? DEFAULT_ELECTRUM_URL,
1639
1865
  network: config?.network ?? "mainnet",
1640
1866
  defaultFeeRate: config?.defaultFeeRate ?? 10,
1641
1867
  enableVesting: config?.enableVesting ?? true
@@ -2475,221 +2701,8 @@ var NametagMinter = class {
2475
2701
  }
2476
2702
  };
2477
2703
 
2478
- // constants.ts
2479
- var STORAGE_PREFIX = "sphere_";
2480
- var DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
2481
- var STORAGE_KEYS_GLOBAL = {
2482
- /** Encrypted BIP39 mnemonic */
2483
- MNEMONIC: "mnemonic",
2484
- /** Encrypted master private key */
2485
- MASTER_KEY: "master_key",
2486
- /** BIP32 chain code */
2487
- CHAIN_CODE: "chain_code",
2488
- /** HD derivation path (full path like m/44'/0'/0'/0/0) */
2489
- DERIVATION_PATH: "derivation_path",
2490
- /** Base derivation path (like m/44'/0'/0' without chain/index) */
2491
- BASE_PATH: "base_path",
2492
- /** Derivation mode: bip32, wif_hmac, legacy_hmac */
2493
- DERIVATION_MODE: "derivation_mode",
2494
- /** Wallet source: mnemonic, file, unknown */
2495
- WALLET_SOURCE: "wallet_source",
2496
- /** Wallet existence flag */
2497
- WALLET_EXISTS: "wallet_exists",
2498
- /** Current active address index */
2499
- CURRENT_ADDRESS_INDEX: "current_address_index",
2500
- /** Nametag cache per address (separate from tracked addresses registry) */
2501
- ADDRESS_NAMETAGS: "address_nametags",
2502
- /** Active addresses registry (JSON: TrackedAddressesStorage) */
2503
- TRACKED_ADDRESSES: "tracked_addresses",
2504
- /** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
2505
- LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
2506
- /** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
2507
- GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
2508
- /** Cached token registry JSON (fetched from remote) */
2509
- TOKEN_REGISTRY_CACHE: "token_registry_cache",
2510
- /** Timestamp of last token registry cache update (ms since epoch) */
2511
- TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
2512
- /** Cached price data JSON (from CoinGecko or other provider) */
2513
- PRICE_CACHE: "price_cache",
2514
- /** Timestamp of last price cache update (ms since epoch) */
2515
- PRICE_CACHE_TS: "price_cache_ts"
2516
- };
2517
- var STORAGE_KEYS_ADDRESS = {
2518
- /** Pending transfers for this address */
2519
- PENDING_TRANSFERS: "pending_transfers",
2520
- /** Transfer outbox for this address */
2521
- OUTBOX: "outbox",
2522
- /** Conversations for this address */
2523
- CONVERSATIONS: "conversations",
2524
- /** Messages for this address */
2525
- MESSAGES: "messages",
2526
- /** Transaction history for this address */
2527
- TRANSACTION_HISTORY: "transaction_history",
2528
- /** Pending V5 finalization tokens (unconfirmed instant split tokens) */
2529
- PENDING_V5_TOKENS: "pending_v5_tokens",
2530
- /** Group chat: joined groups for this address */
2531
- GROUP_CHAT_GROUPS: "group_chat_groups",
2532
- /** Group chat: messages for this address */
2533
- GROUP_CHAT_MESSAGES: "group_chat_messages",
2534
- /** Group chat: members for this address */
2535
- GROUP_CHAT_MEMBERS: "group_chat_members",
2536
- /** Group chat: processed event IDs for deduplication */
2537
- GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
2538
- };
2539
- var STORAGE_KEYS = {
2540
- ...STORAGE_KEYS_GLOBAL,
2541
- ...STORAGE_KEYS_ADDRESS
2542
- };
2543
- function getAddressStorageKey(addressId, key) {
2544
- return `${addressId}_${key}`;
2545
- }
2546
- function getAddressId(directAddress) {
2547
- let hash = directAddress;
2548
- if (hash.startsWith("DIRECT://")) {
2549
- hash = hash.slice(9);
2550
- } else if (hash.startsWith("DIRECT:")) {
2551
- hash = hash.slice(7);
2552
- }
2553
- const first = hash.slice(0, 6).toLowerCase();
2554
- const last = hash.slice(-6).toLowerCase();
2555
- return `DIRECT_${first}_${last}`;
2556
- }
2557
- var DEFAULT_NOSTR_RELAYS = [
2558
- "wss://relay.unicity.network",
2559
- "wss://relay.damus.io",
2560
- "wss://nos.lol",
2561
- "wss://relay.nostr.band"
2562
- ];
2563
- var NOSTR_EVENT_KINDS = {
2564
- /** NIP-04 encrypted direct message */
2565
- DIRECT_MESSAGE: 4,
2566
- /** Token transfer (Unicity custom - 31113) */
2567
- TOKEN_TRANSFER: 31113,
2568
- /** Payment request (Unicity custom - 31115) */
2569
- PAYMENT_REQUEST: 31115,
2570
- /** Payment request response (Unicity custom - 31116) */
2571
- PAYMENT_REQUEST_RESPONSE: 31116,
2572
- /** Nametag binding (NIP-78 app-specific data) */
2573
- NAMETAG_BINDING: 30078,
2574
- /** Public broadcast */
2575
- BROADCAST: 1
2576
- };
2577
- var NIP29_KINDS = {
2578
- /** Chat message sent to group */
2579
- CHAT_MESSAGE: 9,
2580
- /** Thread root message */
2581
- THREAD_ROOT: 11,
2582
- /** Thread reply message */
2583
- THREAD_REPLY: 12,
2584
- /** User join request */
2585
- JOIN_REQUEST: 9021,
2586
- /** User leave request */
2587
- LEAVE_REQUEST: 9022,
2588
- /** Admin: add/update user */
2589
- PUT_USER: 9e3,
2590
- /** Admin: remove user */
2591
- REMOVE_USER: 9001,
2592
- /** Admin: edit group metadata */
2593
- EDIT_METADATA: 9002,
2594
- /** Admin: delete event */
2595
- DELETE_EVENT: 9005,
2596
- /** Admin: create group */
2597
- CREATE_GROUP: 9007,
2598
- /** Admin: delete group */
2599
- DELETE_GROUP: 9008,
2600
- /** Admin: create invite code */
2601
- CREATE_INVITE: 9009,
2602
- /** Relay-signed group metadata */
2603
- GROUP_METADATA: 39e3,
2604
- /** Relay-signed group admins */
2605
- GROUP_ADMINS: 39001,
2606
- /** Relay-signed group members */
2607
- GROUP_MEMBERS: 39002,
2608
- /** Relay-signed group roles */
2609
- GROUP_ROLES: 39003
2610
- };
2611
- var DEFAULT_AGGREGATOR_URL = "https://aggregator.unicity.network/rpc";
2612
- var DEV_AGGREGATOR_URL = "https://dev-aggregator.dyndns.org/rpc";
2613
- var TEST_AGGREGATOR_URL = "https://goggregator-test.unicity.network";
2614
- var DEFAULT_AGGREGATOR_TIMEOUT = 3e4;
2615
- var DEFAULT_IPFS_GATEWAYS = [
2616
- "https://unicity-ipfs1.dyndns.org"
2617
- ];
2618
- var DEFAULT_IPFS_BOOTSTRAP_PEERS = [
2619
- "/dns4/unicity-ipfs2.dyndns.org/tcp/4001/p2p/12D3KooWLNi5NDPPHbrfJakAQqwBqymYTTwMQXQKEWuCrJNDdmfh",
2620
- "/dns4/unicity-ipfs3.dyndns.org/tcp/4001/p2p/12D3KooWQ4aujVE4ShLjdusNZBdffq3TbzrwT2DuWZY9H1Gxhwn6",
2621
- "/dns4/unicity-ipfs4.dyndns.org/tcp/4001/p2p/12D3KooWJ1ByPfUzUrpYvgxKU8NZrR8i6PU1tUgMEbQX9Hh2DEn1",
2622
- "/dns4/unicity-ipfs5.dyndns.org/tcp/4001/p2p/12D3KooWB1MdZZGHN5B8TvWXntbycfe7Cjcz7n6eZ9eykZadvmDv"
2623
- ];
2624
- var DEFAULT_BASE_PATH = "m/44'/0'/0'";
2625
- var DEFAULT_DERIVATION_PATH = `${DEFAULT_BASE_PATH}/0/0`;
2626
- var COIN_TYPES = {
2627
- /** ALPHA token (L1 blockchain) */
2628
- ALPHA: "ALPHA",
2629
- /** Test token */
2630
- TEST: "TEST"
2631
- };
2632
- var DEFAULT_ELECTRUM_URL = "wss://fulcrum.alpha.unicity.network:50004";
2633
- var TEST_ELECTRUM_URL = "wss://fulcrum.alpha.testnet.unicity.network:50004";
2634
- var TOKEN_REGISTRY_URL = "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity-ids.testnet.json";
2635
- var TOKEN_REGISTRY_REFRESH_INTERVAL = 36e5;
2636
- var TEST_NOSTR_RELAYS = [
2637
- "wss://nostr-relay.testnet.unicity.network"
2638
- ];
2639
- var DEFAULT_GROUP_RELAYS = [
2640
- "wss://sphere-relay.unicity.network"
2641
- ];
2642
- var NETWORKS = {
2643
- mainnet: {
2644
- name: "Mainnet",
2645
- aggregatorUrl: DEFAULT_AGGREGATOR_URL,
2646
- nostrRelays: DEFAULT_NOSTR_RELAYS,
2647
- ipfsGateways: DEFAULT_IPFS_GATEWAYS,
2648
- electrumUrl: DEFAULT_ELECTRUM_URL,
2649
- groupRelays: DEFAULT_GROUP_RELAYS,
2650
- tokenRegistryUrl: TOKEN_REGISTRY_URL
2651
- },
2652
- testnet: {
2653
- name: "Testnet",
2654
- aggregatorUrl: TEST_AGGREGATOR_URL,
2655
- nostrRelays: TEST_NOSTR_RELAYS,
2656
- ipfsGateways: DEFAULT_IPFS_GATEWAYS,
2657
- electrumUrl: TEST_ELECTRUM_URL,
2658
- groupRelays: DEFAULT_GROUP_RELAYS,
2659
- tokenRegistryUrl: TOKEN_REGISTRY_URL
2660
- },
2661
- dev: {
2662
- name: "Development",
2663
- aggregatorUrl: DEV_AGGREGATOR_URL,
2664
- nostrRelays: TEST_NOSTR_RELAYS,
2665
- ipfsGateways: DEFAULT_IPFS_GATEWAYS,
2666
- electrumUrl: TEST_ELECTRUM_URL,
2667
- groupRelays: DEFAULT_GROUP_RELAYS,
2668
- tokenRegistryUrl: TOKEN_REGISTRY_URL
2669
- }
2670
- };
2671
- var TIMEOUTS = {
2672
- /** WebSocket connection timeout */
2673
- WEBSOCKET_CONNECT: 1e4,
2674
- /** Nostr relay reconnect delay */
2675
- NOSTR_RECONNECT_DELAY: 3e3,
2676
- /** Max reconnect attempts */
2677
- MAX_RECONNECT_ATTEMPTS: 5,
2678
- /** Proof polling interval */
2679
- PROOF_POLL_INTERVAL: 1e3,
2680
- /** Sync interval */
2681
- SYNC_INTERVAL: 6e4
2682
- };
2683
- var LIMITS = {
2684
- /** Min nametag length */
2685
- NAMETAG_MIN_LENGTH: 3,
2686
- /** Max nametag length */
2687
- NAMETAG_MAX_LENGTH: 20,
2688
- /** Max memo length */
2689
- MEMO_MAX_LENGTH: 500,
2690
- /** Max message length */
2691
- MESSAGE_MAX_LENGTH: 1e4
2692
- };
2704
+ // modules/payments/PaymentsModule.ts
2705
+ init_constants();
2693
2706
 
2694
2707
  // types/txf.ts
2695
2708
  var ARCHIVED_PREFIX = "archived-";
@@ -2734,6 +2747,7 @@ function isValidTokenId(tokenId) {
2734
2747
  }
2735
2748
 
2736
2749
  // registry/TokenRegistry.ts
2750
+ init_constants();
2737
2751
  var FETCH_TIMEOUT_MS = 1e4;
2738
2752
  var TokenRegistry = class _TokenRegistry {
2739
2753
  static instance = null;
@@ -7631,6 +7645,7 @@ import { HashAlgorithm as HashAlgorithm6 } from "@unicitylabs/state-transition-s
7631
7645
  import { UnmaskedPredicate as UnmaskedPredicate6 } from "@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate";
7632
7646
 
7633
7647
  // modules/communications/CommunicationsModule.ts
7648
+ init_constants();
7634
7649
  var CommunicationsModule = class {
7635
7650
  config;
7636
7651
  deps = null;
@@ -8105,6 +8120,7 @@ function createCommunicationsModule(config) {
8105
8120
  }
8106
8121
 
8107
8122
  // modules/groupchat/GroupChatModule.ts
8123
+ init_constants();
8108
8124
  import {
8109
8125
  NostrClient,
8110
8126
  NostrKeyManager,
@@ -11954,6 +11970,9 @@ function createMarketModule(config) {
11954
11970
  return new MarketModule(config);
11955
11971
  }
11956
11972
 
11973
+ // core/Sphere.ts
11974
+ init_constants();
11975
+
11957
11976
  // core/encryption.ts
11958
11977
  import CryptoJS6 from "crypto-js";
11959
11978
  function encryptSimple(plaintext, password) {
@@ -12057,6 +12076,72 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
12057
12076
  };
12058
12077
  }
12059
12078
 
12079
+ // core/discover.ts
12080
+ async function discoverAddressesImpl(deriveTransportPubkey, batchResolve, options = {}) {
12081
+ const maxAddresses = options.maxAddresses ?? 50;
12082
+ const gapLimit = options.gapLimit ?? 20;
12083
+ const batchSize = options.batchSize ?? 20;
12084
+ const { onProgress, signal } = options;
12085
+ const discovered = /* @__PURE__ */ new Map();
12086
+ let consecutiveEmpty = 0;
12087
+ let scanned = 0;
12088
+ const totalBatches = Math.ceil(maxAddresses / batchSize);
12089
+ for (let batchStart = 0; batchStart < maxAddresses; batchStart += batchSize) {
12090
+ if (signal?.aborted) break;
12091
+ if (consecutiveEmpty >= gapLimit) break;
12092
+ const batchEnd = Math.min(batchStart + batchSize, maxAddresses);
12093
+ const batchIndices = [];
12094
+ const pubkeyToIndex = /* @__PURE__ */ new Map();
12095
+ const pubkeyToInfo = /* @__PURE__ */ new Map();
12096
+ for (let i = batchStart; i < batchEnd; i++) {
12097
+ const info = deriveTransportPubkey(i);
12098
+ batchIndices.push(i);
12099
+ pubkeyToIndex.set(info.transportPubkey, i);
12100
+ pubkeyToInfo.set(info.transportPubkey, info);
12101
+ }
12102
+ const batchPubkeys = Array.from(pubkeyToIndex.keys());
12103
+ onProgress?.({
12104
+ currentBatch: Math.floor(batchStart / batchSize) + 1,
12105
+ totalBatches,
12106
+ discoveredCount: discovered.size,
12107
+ currentGap: consecutiveEmpty,
12108
+ phase: "transport"
12109
+ });
12110
+ const peerInfos = await batchResolve(batchPubkeys);
12111
+ const foundInBatch = /* @__PURE__ */ new Set();
12112
+ for (const peer of peerInfos) {
12113
+ const index = pubkeyToIndex.get(peer.transportPubkey);
12114
+ if (index !== void 0) {
12115
+ foundInBatch.add(index);
12116
+ const derived = pubkeyToInfo.get(peer.transportPubkey);
12117
+ discovered.set(index, {
12118
+ index,
12119
+ l1Address: peer.l1Address || derived.l1Address,
12120
+ directAddress: peer.directAddress || derived.directAddress,
12121
+ chainPubkey: peer.chainPubkey || derived.chainPubkey,
12122
+ nametag: peer.nametag,
12123
+ l1Balance: 0,
12124
+ source: "transport"
12125
+ });
12126
+ }
12127
+ }
12128
+ for (const idx of batchIndices) {
12129
+ scanned++;
12130
+ if (foundInBatch.has(idx)) {
12131
+ consecutiveEmpty = 0;
12132
+ } else {
12133
+ consecutiveEmpty++;
12134
+ if (consecutiveEmpty >= gapLimit) break;
12135
+ }
12136
+ }
12137
+ }
12138
+ return {
12139
+ addresses: Array.from(discovered.values()).sort((a, b) => a.index - b.index),
12140
+ scannedCount: scanned,
12141
+ aborted: signal?.aborted ?? false
12142
+ };
12143
+ }
12144
+
12060
12145
  // core/Sphere.ts
12061
12146
  init_network();
12062
12147
 
@@ -12879,7 +12964,9 @@ var Sphere = class _Sphere {
12879
12964
  price: options.price,
12880
12965
  groupChat,
12881
12966
  market,
12882
- password: options.password
12967
+ password: options.password,
12968
+ discoverAddresses: options.discoverAddresses,
12969
+ onProgress: options.onProgress
12883
12970
  });
12884
12971
  return { sphere: sphere2, created: false };
12885
12972
  }
@@ -12907,7 +12994,9 @@ var Sphere = class _Sphere {
12907
12994
  price: options.price,
12908
12995
  groupChat,
12909
12996
  market,
12910
- password: options.password
12997
+ password: options.password,
12998
+ discoverAddresses: options.discoverAddresses,
12999
+ onProgress: options.onProgress
12911
13000
  });
12912
13001
  return { sphere, created: true, generatedMnemonic };
12913
13002
  }
@@ -12968,6 +13057,7 @@ var Sphere = class _Sphere {
12968
13057
  if (await _Sphere.exists(options.storage)) {
12969
13058
  throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
12970
13059
  }
13060
+ const progress = options.onProgress;
12971
13061
  if (!options.storage.isConnected()) {
12972
13062
  await options.storage.connect();
12973
13063
  }
@@ -12985,20 +13075,39 @@ var Sphere = class _Sphere {
12985
13075
  marketConfig
12986
13076
  );
12987
13077
  sphere._password = options.password ?? null;
13078
+ progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
12988
13079
  await sphere.storeMnemonic(options.mnemonic, options.derivationPath);
12989
13080
  await sphere.initializeIdentityFromMnemonic(options.mnemonic, options.derivationPath);
13081
+ progress?.({ step: "initializing", message: "Initializing wallet..." });
12990
13082
  await sphere.initializeProviders();
12991
13083
  await sphere.initializeModules();
13084
+ progress?.({ step: "finalizing", message: "Finalizing wallet..." });
12992
13085
  await sphere.finalizeWalletCreation();
12993
13086
  sphere._initialized = true;
12994
13087
  _Sphere.instance = sphere;
12995
13088
  await sphere.ensureAddressTracked(0);
12996
13089
  if (options.nametag) {
13090
+ progress?.({ step: "registering_nametag", message: "Registering nametag..." });
12997
13091
  await sphere.registerNametag(options.nametag);
12998
13092
  } else {
13093
+ progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
12999
13094
  await sphere.recoverNametagFromTransport();
13095
+ progress?.({ step: "syncing_identity", message: "Publishing identity..." });
13000
13096
  await sphere.syncIdentityWithTransport();
13001
13097
  }
13098
+ if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
13099
+ progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
13100
+ try {
13101
+ const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13102
+ const result = await sphere.discoverAddresses(discoverOpts);
13103
+ if (result.addresses.length > 0) {
13104
+ console.log(`[Sphere.create] Address discovery: found ${result.addresses.length} address(es)`);
13105
+ }
13106
+ } catch (err) {
13107
+ console.warn("[Sphere.create] Address discovery failed (non-fatal):", err);
13108
+ }
13109
+ }
13110
+ progress?.({ step: "complete", message: "Wallet created" });
13002
13111
  return sphere;
13003
13112
  }
13004
13113
  /**
@@ -13008,6 +13117,7 @@ var Sphere = class _Sphere {
13008
13117
  if (!await _Sphere.exists(options.storage)) {
13009
13118
  throw new Error("No wallet found. Use Sphere.create() to create a new wallet.");
13010
13119
  }
13120
+ const progress = options.onProgress;
13011
13121
  _Sphere.configureTokenRegistry(options.storage, options.network);
13012
13122
  const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
13013
13123
  const marketConfig = _Sphere.resolveMarketConfig(options.market);
@@ -13025,13 +13135,17 @@ var Sphere = class _Sphere {
13025
13135
  if (!options.storage.isConnected()) {
13026
13136
  await options.storage.connect();
13027
13137
  }
13138
+ progress?.({ step: "storing_keys", message: "Loading wallet keys..." });
13028
13139
  await sphere.loadIdentityFromStorage();
13140
+ progress?.({ step: "initializing", message: "Initializing wallet..." });
13029
13141
  await sphere.initializeProviders();
13030
13142
  await sphere.initializeModules();
13143
+ progress?.({ step: "syncing_identity", message: "Publishing identity..." });
13031
13144
  await sphere.syncIdentityWithTransport();
13032
13145
  sphere._initialized = true;
13033
13146
  _Sphere.instance = sphere;
13034
13147
  if (sphere._identity?.nametag && !sphere._payments.hasNametag()) {
13148
+ progress?.({ step: "registering_nametag", message: "Restoring nametag token..." });
13035
13149
  console.log(`[Sphere] Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
13036
13150
  try {
13037
13151
  const result = await sphere.mintNametag(sphere._identity.nametag);
@@ -13044,6 +13158,19 @@ var Sphere = class _Sphere {
13044
13158
  console.warn(`[Sphere] Nametag token mint failed:`, err);
13045
13159
  }
13046
13160
  }
13161
+ if (options.discoverAddresses !== false && sphere._transport.discoverAddresses && sphere._masterKey) {
13162
+ progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
13163
+ try {
13164
+ const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13165
+ const result = await sphere.discoverAddresses(discoverOpts);
13166
+ if (result.addresses.length > 0) {
13167
+ console.log(`[Sphere.load] Address discovery: found ${result.addresses.length} address(es)`);
13168
+ }
13169
+ } catch (err) {
13170
+ console.warn("[Sphere.load] Address discovery failed (non-fatal):", err);
13171
+ }
13172
+ }
13173
+ progress?.({ step: "complete", message: "Wallet loaded" });
13047
13174
  return sphere;
13048
13175
  }
13049
13176
  /**
@@ -13053,9 +13180,11 @@ var Sphere = class _Sphere {
13053
13180
  if (!options.mnemonic && !options.masterKey) {
13054
13181
  throw new Error("Either mnemonic or masterKey is required");
13055
13182
  }
13183
+ const progress = options.onProgress;
13056
13184
  console.log("[Sphere.import] Starting import...");
13057
13185
  const needsClear = _Sphere.instance !== null || await _Sphere.exists(options.storage);
13058
13186
  if (needsClear) {
13187
+ progress?.({ step: "clearing", message: "Clearing previous wallet data..." });
13059
13188
  console.log("[Sphere.import] Clearing existing wallet data...");
13060
13189
  await _Sphere.clear({ storage: options.storage, tokenStorage: options.tokenStorage });
13061
13190
  console.log("[Sphere.import] Clear done");
@@ -13080,6 +13209,7 @@ var Sphere = class _Sphere {
13080
13209
  marketConfig
13081
13210
  );
13082
13211
  sphere._password = options.password ?? null;
13212
+ progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
13083
13213
  if (options.mnemonic) {
13084
13214
  if (!_Sphere.validateMnemonic(options.mnemonic)) {
13085
13215
  throw new Error("Invalid mnemonic");
@@ -13104,17 +13234,21 @@ var Sphere = class _Sphere {
13104
13234
  options.derivationPath
13105
13235
  );
13106
13236
  }
13237
+ progress?.({ step: "initializing", message: "Initializing wallet..." });
13107
13238
  console.log("[Sphere.import] Initializing providers...");
13108
13239
  await sphere.initializeProviders();
13109
13240
  console.log("[Sphere.import] Providers initialized. Initializing modules...");
13110
13241
  await sphere.initializeModules();
13111
13242
  console.log("[Sphere.import] Modules initialized");
13112
13243
  if (!options.nametag) {
13244
+ progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
13113
13245
  console.log("[Sphere.import] Recovering nametag from transport...");
13114
13246
  await sphere.recoverNametagFromTransport();
13115
13247
  console.log("[Sphere.import] Nametag recovery done");
13248
+ progress?.({ step: "syncing_identity", message: "Publishing identity..." });
13116
13249
  await sphere.syncIdentityWithTransport();
13117
13250
  }
13251
+ progress?.({ step: "finalizing", message: "Finalizing wallet..." });
13118
13252
  console.log("[Sphere.import] Finalizing wallet creation...");
13119
13253
  await sphere.finalizeWalletCreation();
13120
13254
  sphere._initialized = true;
@@ -13122,10 +13256,12 @@ var Sphere = class _Sphere {
13122
13256
  console.log("[Sphere.import] Tracking address 0...");
13123
13257
  await sphere.ensureAddressTracked(0);
13124
13258
  if (options.nametag) {
13259
+ progress?.({ step: "registering_nametag", message: "Registering nametag..." });
13125
13260
  console.log("[Sphere.import] Registering nametag...");
13126
13261
  await sphere.registerNametag(options.nametag);
13127
13262
  }
13128
13263
  if (sphere._tokenStorageProviders.size > 0) {
13264
+ progress?.({ step: "syncing_tokens", message: "Syncing tokens..." });
13129
13265
  try {
13130
13266
  const syncResult = await sphere._payments.sync();
13131
13267
  console.log(`[Sphere.import] Auto-sync: +${syncResult.added} -${syncResult.removed}`);
@@ -13133,6 +13269,19 @@ var Sphere = class _Sphere {
13133
13269
  console.warn("[Sphere.import] Auto-sync failed (non-fatal):", err);
13134
13270
  }
13135
13271
  }
13272
+ if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
13273
+ progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
13274
+ try {
13275
+ const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
13276
+ const result = await sphere.discoverAddresses(discoverOpts);
13277
+ if (result.addresses.length > 0) {
13278
+ console.log(`[Sphere.import] Address discovery: found ${result.addresses.length} address(es)`);
13279
+ }
13280
+ } catch (err) {
13281
+ console.warn("[Sphere.import] Address discovery failed (non-fatal):", err);
13282
+ }
13283
+ }
13284
+ progress?.({ step: "complete", message: "Import complete" });
13136
13285
  console.log("[Sphere.import] Import complete");
13137
13286
  return sphere;
13138
13287
  }
@@ -14001,6 +14150,23 @@ var Sphere = class _Sphere {
14001
14150
  await provider.initialize();
14002
14151
  }
14003
14152
  await this.reinitializeModulesForNewAddress();
14153
+ this.emitEvent("identity:changed", {
14154
+ l1Address: this._identity.l1Address,
14155
+ directAddress: this._identity.directAddress,
14156
+ chainPubkey: this._identity.chainPubkey,
14157
+ nametag: this._identity.nametag,
14158
+ addressIndex: index
14159
+ });
14160
+ console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
14161
+ this.postSwitchSync(index, newNametag).catch((err) => {
14162
+ console.warn(`[Sphere] Post-switch sync failed for address ${index}:`, err);
14163
+ });
14164
+ }
14165
+ /**
14166
+ * Background transport sync and nametag operations after address switch.
14167
+ * Runs after switchToAddress returns so L1/L3 queries can start immediately.
14168
+ */
14169
+ async postSwitchSync(index, newNametag) {
14004
14170
  if (!newNametag) {
14005
14171
  await this.syncIdentityWithTransport();
14006
14172
  }
@@ -14023,7 +14189,7 @@ var Sphere = class _Sphere {
14023
14189
  nametag: newNametag,
14024
14190
  addressIndex: index
14025
14191
  });
14026
- } else if (this._identity.nametag && !this._payments.hasNametag()) {
14192
+ } else if (this._identity?.nametag && !this._payments.hasNametag()) {
14027
14193
  console.log(`[Sphere] Nametag @${this._identity.nametag} has no token after switch, minting...`);
14028
14194
  try {
14029
14195
  const result = await this.mintNametag(this._identity.nametag);
@@ -14036,14 +14202,6 @@ var Sphere = class _Sphere {
14036
14202
  console.warn(`[Sphere] Nametag token mint failed after switch:`, err);
14037
14203
  }
14038
14204
  }
14039
- this.emitEvent("identity:changed", {
14040
- l1Address: this._identity.l1Address,
14041
- directAddress: this._identity.directAddress,
14042
- chainPubkey: this._identity.chainPubkey,
14043
- nametag: this._identity.nametag,
14044
- addressIndex: index
14045
- });
14046
- console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
14047
14205
  }
14048
14206
  /**
14049
14207
  * Re-initialize modules after address switch
@@ -14250,6 +14408,98 @@ var Sphere = class _Sphere {
14250
14408
  await this.persistTrackedAddresses();
14251
14409
  await this.persistAddressNametags();
14252
14410
  }
14411
+ /**
14412
+ * Discover previously used HD addresses.
14413
+ *
14414
+ * Primary: queries Nostr relay for identity binding events (fast, single batch query).
14415
+ * Secondary: runs L1 balance scan to find legacy addresses with no binding event.
14416
+ *
14417
+ * @example
14418
+ * ```ts
14419
+ * const result = await sphere.discoverAddresses();
14420
+ * console.log(`Found ${result.addresses.length} addresses`);
14421
+ *
14422
+ * // With auto-tracking
14423
+ * await sphere.discoverAddresses({ autoTrack: true });
14424
+ * ```
14425
+ */
14426
+ async discoverAddresses(options = {}) {
14427
+ this.ensureReady();
14428
+ if (!this._masterKey) {
14429
+ throw new Error("Address discovery requires HD master key");
14430
+ }
14431
+ if (!this._transport.discoverAddresses) {
14432
+ throw new Error("Transport provider does not support address discovery");
14433
+ }
14434
+ const includeL1Scan = options.includeL1Scan ?? true;
14435
+ const transportResult = await discoverAddressesImpl(
14436
+ (index) => {
14437
+ const addrInfo = this._deriveAddressInternal(index, false);
14438
+ return {
14439
+ transportPubkey: addrInfo.publicKey.slice(2),
14440
+ // x-only 32 bytes
14441
+ chainPubkey: addrInfo.publicKey,
14442
+ l1Address: addrInfo.address,
14443
+ directAddress: ""
14444
+ // not needed for discovery query
14445
+ };
14446
+ },
14447
+ (pubkeys) => this._transport.discoverAddresses(pubkeys),
14448
+ options
14449
+ );
14450
+ if (includeL1Scan) {
14451
+ try {
14452
+ const l1Result = await this.scanAddresses({
14453
+ maxAddresses: options.maxAddresses,
14454
+ gapLimit: options.gapLimit,
14455
+ signal: options.signal,
14456
+ onProgress: options.onProgress ? (p) => options.onProgress({
14457
+ currentBatch: 0,
14458
+ totalBatches: 0,
14459
+ discoveredCount: p.foundCount,
14460
+ currentGap: p.currentGap,
14461
+ phase: "l1"
14462
+ }) : void 0
14463
+ });
14464
+ for (const l1Addr of l1Result.addresses) {
14465
+ if (l1Addr.isChange) continue;
14466
+ const existing = transportResult.addresses.find((a) => a.index === l1Addr.index);
14467
+ if (existing) {
14468
+ existing.l1Balance = l1Addr.balance;
14469
+ existing.source = "both";
14470
+ if (!existing.nametag && l1Addr.nametag) {
14471
+ existing.nametag = l1Addr.nametag;
14472
+ }
14473
+ } else {
14474
+ const addrInfo = this._deriveAddressInternal(l1Addr.index, false);
14475
+ transportResult.addresses.push({
14476
+ index: l1Addr.index,
14477
+ l1Address: l1Addr.address,
14478
+ directAddress: "",
14479
+ chainPubkey: addrInfo.publicKey,
14480
+ nametag: l1Addr.nametag,
14481
+ l1Balance: l1Addr.balance,
14482
+ source: "l1"
14483
+ });
14484
+ }
14485
+ }
14486
+ transportResult.addresses.sort((a, b) => a.index - b.index);
14487
+ } catch (err) {
14488
+ console.warn("[Sphere] L1 scan failed during discovery (non-fatal):", err);
14489
+ }
14490
+ }
14491
+ if (options.autoTrack && transportResult.addresses.length > 0) {
14492
+ await this.trackScannedAddresses(
14493
+ transportResult.addresses.map((a) => ({
14494
+ index: a.index,
14495
+ // Preserve existing hidden state; default to false for newly discovered
14496
+ hidden: this._trackedAddresses.get(a.index)?.hidden ?? false,
14497
+ nametag: a.nametag
14498
+ }))
14499
+ );
14500
+ }
14501
+ return transportResult;
14502
+ }
14253
14503
  // ===========================================================================
14254
14504
  // Public Methods - Status
14255
14505
  // ===========================================================================
@@ -14821,6 +15071,17 @@ var Sphere = class _Sphere {
14821
15071
  return;
14822
15072
  }
14823
15073
  }
15074
+ const needsUpdate = !existing.directAddress || !existing.l1Address || !existing.chainPubkey || this._identity?.nametag && !existing.nametag;
15075
+ if (needsUpdate) {
15076
+ console.log("[Sphere] Existing binding incomplete, re-publishing with full data");
15077
+ await this._transport.publishIdentityBinding(
15078
+ this._identity.chainPubkey,
15079
+ this._identity.l1Address,
15080
+ this._identity.directAddress || "",
15081
+ this._identity?.nametag || existing.nametag || void 0
15082
+ );
15083
+ return;
15084
+ }
14824
15085
  console.log("[Sphere] Existing binding found, skipping re-publish");
14825
15086
  return;
14826
15087
  }
@@ -15309,6 +15570,7 @@ function formatAmount(amount, options = {}) {
15309
15570
  init_bech32();
15310
15571
 
15311
15572
  // core/network-health.ts
15573
+ init_constants();
15312
15574
  var DEFAULT_TIMEOUT_MS = 5e3;
15313
15575
  async function checkNetworkHealth(network = "testnet", options) {
15314
15576
  const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
@@ -15494,6 +15756,9 @@ async function runCustomCheck(name, checkFn, timeoutMs) {
15494
15756
  }
15495
15757
  }
15496
15758
 
15759
+ // index.ts
15760
+ init_constants();
15761
+
15497
15762
  // types/payment-session.ts
15498
15763
  function createPaymentSession(params) {
15499
15764
  const now = Date.now();
@@ -15565,6 +15830,9 @@ var SphereError = class extends Error {
15565
15830
  }
15566
15831
  };
15567
15832
 
15833
+ // index.ts
15834
+ init_constants();
15835
+
15568
15836
  // validation/token-validator.ts
15569
15837
  var TokenValidator = class {
15570
15838
  aggregatorClient = null;
@@ -15898,6 +16166,7 @@ import {
15898
16166
  } from "@unicitylabs/nostr-js-sdk";
15899
16167
 
15900
16168
  // price/CoinGeckoPriceProvider.ts
16169
+ init_constants();
15901
16170
  var CoinGeckoPriceProvider = class {
15902
16171
  platform = "coingecko";
15903
16172
  cache = /* @__PURE__ */ new Map();