@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/connect/index.cjs.map +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +441 -177
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +163 -4
- package/dist/core/index.d.ts +163 -4
- package/dist/core/index.js +440 -177
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +40 -2
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +40 -2
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +40 -2
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +16 -3
- package/dist/impl/nodejs/index.d.ts +16 -3
- package/dist/impl/nodejs/index.js +40 -2
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +497 -228
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -6
- package/dist/index.d.ts +147 -6
- package/dist/index.js +497 -228
- package/dist/index.js.map +1 -1
- package/dist/l1/index.cjs +68 -1
- package/dist/l1/index.cjs.map +1 -1
- package/dist/l1/index.js +68 -1
- package/dist/l1/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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 ??
|
|
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
|
-
//
|
|
2479
|
-
|
|
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
|
|
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();
|