@unicitylabs/sphere-sdk 0.4.7 → 0.4.9
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 +443 -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 +442 -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 +499 -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 +499 -228
- package/dist/index.js.map +1 -1
- package/dist/l1/index.cjs +70 -1
- package/dist/l1/index.cjs.map +1 -1
- package/dist/l1/index.js +70 -1
- package/dist/l1/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,228 @@ var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__
|
|
|
30
30
|
));
|
|
31
31
|
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
|
|
32
32
|
|
|
33
|
+
// constants.ts
|
|
34
|
+
function getAddressStorageKey(addressId, key) {
|
|
35
|
+
return `${addressId}_${key}`;
|
|
36
|
+
}
|
|
37
|
+
function getAddressId(directAddress) {
|
|
38
|
+
let hash = directAddress;
|
|
39
|
+
if (hash.startsWith("DIRECT://")) {
|
|
40
|
+
hash = hash.slice(9);
|
|
41
|
+
} else if (hash.startsWith("DIRECT:")) {
|
|
42
|
+
hash = hash.slice(7);
|
|
43
|
+
}
|
|
44
|
+
const first = hash.slice(0, 6).toLowerCase();
|
|
45
|
+
const last = hash.slice(-6).toLowerCase();
|
|
46
|
+
return `DIRECT_${first}_${last}`;
|
|
47
|
+
}
|
|
48
|
+
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;
|
|
49
|
+
var init_constants = __esm({
|
|
50
|
+
"constants.ts"() {
|
|
51
|
+
"use strict";
|
|
52
|
+
STORAGE_PREFIX = "sphere_";
|
|
53
|
+
DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
|
|
54
|
+
STORAGE_KEYS_GLOBAL = {
|
|
55
|
+
/** Encrypted BIP39 mnemonic */
|
|
56
|
+
MNEMONIC: "mnemonic",
|
|
57
|
+
/** Encrypted master private key */
|
|
58
|
+
MASTER_KEY: "master_key",
|
|
59
|
+
/** BIP32 chain code */
|
|
60
|
+
CHAIN_CODE: "chain_code",
|
|
61
|
+
/** HD derivation path (full path like m/44'/0'/0'/0/0) */
|
|
62
|
+
DERIVATION_PATH: "derivation_path",
|
|
63
|
+
/** Base derivation path (like m/44'/0'/0' without chain/index) */
|
|
64
|
+
BASE_PATH: "base_path",
|
|
65
|
+
/** Derivation mode: bip32, wif_hmac, legacy_hmac */
|
|
66
|
+
DERIVATION_MODE: "derivation_mode",
|
|
67
|
+
/** Wallet source: mnemonic, file, unknown */
|
|
68
|
+
WALLET_SOURCE: "wallet_source",
|
|
69
|
+
/** Wallet existence flag */
|
|
70
|
+
WALLET_EXISTS: "wallet_exists",
|
|
71
|
+
/** Current active address index */
|
|
72
|
+
CURRENT_ADDRESS_INDEX: "current_address_index",
|
|
73
|
+
/** Nametag cache per address (separate from tracked addresses registry) */
|
|
74
|
+
ADDRESS_NAMETAGS: "address_nametags",
|
|
75
|
+
/** Active addresses registry (JSON: TrackedAddressesStorage) */
|
|
76
|
+
TRACKED_ADDRESSES: "tracked_addresses",
|
|
77
|
+
/** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
|
|
78
|
+
LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
|
|
79
|
+
/** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
|
|
80
|
+
GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
|
|
81
|
+
/** Cached token registry JSON (fetched from remote) */
|
|
82
|
+
TOKEN_REGISTRY_CACHE: "token_registry_cache",
|
|
83
|
+
/** Timestamp of last token registry cache update (ms since epoch) */
|
|
84
|
+
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
|
|
85
|
+
/** Cached price data JSON (from CoinGecko or other provider) */
|
|
86
|
+
PRICE_CACHE: "price_cache",
|
|
87
|
+
/** Timestamp of last price cache update (ms since epoch) */
|
|
88
|
+
PRICE_CACHE_TS: "price_cache_ts"
|
|
89
|
+
};
|
|
90
|
+
STORAGE_KEYS_ADDRESS = {
|
|
91
|
+
/** Pending transfers for this address */
|
|
92
|
+
PENDING_TRANSFERS: "pending_transfers",
|
|
93
|
+
/** Transfer outbox for this address */
|
|
94
|
+
OUTBOX: "outbox",
|
|
95
|
+
/** Conversations for this address */
|
|
96
|
+
CONVERSATIONS: "conversations",
|
|
97
|
+
/** Messages for this address */
|
|
98
|
+
MESSAGES: "messages",
|
|
99
|
+
/** Transaction history for this address */
|
|
100
|
+
TRANSACTION_HISTORY: "transaction_history",
|
|
101
|
+
/** Pending V5 finalization tokens (unconfirmed instant split tokens) */
|
|
102
|
+
PENDING_V5_TOKENS: "pending_v5_tokens",
|
|
103
|
+
/** Group chat: joined groups for this address */
|
|
104
|
+
GROUP_CHAT_GROUPS: "group_chat_groups",
|
|
105
|
+
/** Group chat: messages for this address */
|
|
106
|
+
GROUP_CHAT_MESSAGES: "group_chat_messages",
|
|
107
|
+
/** Group chat: members for this address */
|
|
108
|
+
GROUP_CHAT_MEMBERS: "group_chat_members",
|
|
109
|
+
/** Group chat: processed event IDs for deduplication */
|
|
110
|
+
GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
|
|
111
|
+
};
|
|
112
|
+
STORAGE_KEYS = {
|
|
113
|
+
...STORAGE_KEYS_GLOBAL,
|
|
114
|
+
...STORAGE_KEYS_ADDRESS
|
|
115
|
+
};
|
|
116
|
+
DEFAULT_NOSTR_RELAYS = [
|
|
117
|
+
"wss://relay.unicity.network",
|
|
118
|
+
"wss://relay.damus.io",
|
|
119
|
+
"wss://nos.lol",
|
|
120
|
+
"wss://relay.nostr.band"
|
|
121
|
+
];
|
|
122
|
+
NOSTR_EVENT_KINDS = {
|
|
123
|
+
/** NIP-04 encrypted direct message */
|
|
124
|
+
DIRECT_MESSAGE: 4,
|
|
125
|
+
/** Token transfer (Unicity custom - 31113) */
|
|
126
|
+
TOKEN_TRANSFER: 31113,
|
|
127
|
+
/** Payment request (Unicity custom - 31115) */
|
|
128
|
+
PAYMENT_REQUEST: 31115,
|
|
129
|
+
/** Payment request response (Unicity custom - 31116) */
|
|
130
|
+
PAYMENT_REQUEST_RESPONSE: 31116,
|
|
131
|
+
/** Nametag binding (NIP-78 app-specific data) */
|
|
132
|
+
NAMETAG_BINDING: 30078,
|
|
133
|
+
/** Public broadcast */
|
|
134
|
+
BROADCAST: 1
|
|
135
|
+
};
|
|
136
|
+
NIP29_KINDS = {
|
|
137
|
+
/** Chat message sent to group */
|
|
138
|
+
CHAT_MESSAGE: 9,
|
|
139
|
+
/** Thread root message */
|
|
140
|
+
THREAD_ROOT: 11,
|
|
141
|
+
/** Thread reply message */
|
|
142
|
+
THREAD_REPLY: 12,
|
|
143
|
+
/** User join request */
|
|
144
|
+
JOIN_REQUEST: 9021,
|
|
145
|
+
/** User leave request */
|
|
146
|
+
LEAVE_REQUEST: 9022,
|
|
147
|
+
/** Admin: add/update user */
|
|
148
|
+
PUT_USER: 9e3,
|
|
149
|
+
/** Admin: remove user */
|
|
150
|
+
REMOVE_USER: 9001,
|
|
151
|
+
/** Admin: edit group metadata */
|
|
152
|
+
EDIT_METADATA: 9002,
|
|
153
|
+
/** Admin: delete event */
|
|
154
|
+
DELETE_EVENT: 9005,
|
|
155
|
+
/** Admin: create group */
|
|
156
|
+
CREATE_GROUP: 9007,
|
|
157
|
+
/** Admin: delete group */
|
|
158
|
+
DELETE_GROUP: 9008,
|
|
159
|
+
/** Admin: create invite code */
|
|
160
|
+
CREATE_INVITE: 9009,
|
|
161
|
+
/** Relay-signed group metadata */
|
|
162
|
+
GROUP_METADATA: 39e3,
|
|
163
|
+
/** Relay-signed group admins */
|
|
164
|
+
GROUP_ADMINS: 39001,
|
|
165
|
+
/** Relay-signed group members */
|
|
166
|
+
GROUP_MEMBERS: 39002,
|
|
167
|
+
/** Relay-signed group roles */
|
|
168
|
+
GROUP_ROLES: 39003
|
|
169
|
+
};
|
|
170
|
+
DEFAULT_AGGREGATOR_URL = "https://aggregator.unicity.network/rpc";
|
|
171
|
+
DEV_AGGREGATOR_URL = "https://dev-aggregator.dyndns.org/rpc";
|
|
172
|
+
TEST_AGGREGATOR_URL = "https://goggregator-test.unicity.network";
|
|
173
|
+
DEFAULT_AGGREGATOR_TIMEOUT = 3e4;
|
|
174
|
+
DEFAULT_IPFS_GATEWAYS = [
|
|
175
|
+
"https://unicity-ipfs1.dyndns.org"
|
|
176
|
+
];
|
|
177
|
+
DEFAULT_IPFS_BOOTSTRAP_PEERS = [
|
|
178
|
+
"/dns4/unicity-ipfs2.dyndns.org/tcp/4001/p2p/12D3KooWLNi5NDPPHbrfJakAQqwBqymYTTwMQXQKEWuCrJNDdmfh",
|
|
179
|
+
"/dns4/unicity-ipfs3.dyndns.org/tcp/4001/p2p/12D3KooWQ4aujVE4ShLjdusNZBdffq3TbzrwT2DuWZY9H1Gxhwn6",
|
|
180
|
+
"/dns4/unicity-ipfs4.dyndns.org/tcp/4001/p2p/12D3KooWJ1ByPfUzUrpYvgxKU8NZrR8i6PU1tUgMEbQX9Hh2DEn1",
|
|
181
|
+
"/dns4/unicity-ipfs5.dyndns.org/tcp/4001/p2p/12D3KooWB1MdZZGHN5B8TvWXntbycfe7Cjcz7n6eZ9eykZadvmDv"
|
|
182
|
+
];
|
|
183
|
+
DEFAULT_BASE_PATH = "m/44'/0'/0'";
|
|
184
|
+
DEFAULT_DERIVATION_PATH = `${DEFAULT_BASE_PATH}/0/0`;
|
|
185
|
+
COIN_TYPES = {
|
|
186
|
+
/** ALPHA token (L1 blockchain) */
|
|
187
|
+
ALPHA: "ALPHA",
|
|
188
|
+
/** Test token */
|
|
189
|
+
TEST: "TEST"
|
|
190
|
+
};
|
|
191
|
+
DEFAULT_ELECTRUM_URL = "wss://fulcrum.unicity.network:50004";
|
|
192
|
+
TEST_ELECTRUM_URL = "wss://fulcrum.unicity.network:50004";
|
|
193
|
+
TOKEN_REGISTRY_URL = "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity-ids.testnet.json";
|
|
194
|
+
TOKEN_REGISTRY_REFRESH_INTERVAL = 36e5;
|
|
195
|
+
TEST_NOSTR_RELAYS = [
|
|
196
|
+
"wss://nostr-relay.testnet.unicity.network"
|
|
197
|
+
];
|
|
198
|
+
DEFAULT_GROUP_RELAYS = [
|
|
199
|
+
"wss://sphere-relay.unicity.network"
|
|
200
|
+
];
|
|
201
|
+
NETWORKS = {
|
|
202
|
+
mainnet: {
|
|
203
|
+
name: "Mainnet",
|
|
204
|
+
aggregatorUrl: DEFAULT_AGGREGATOR_URL,
|
|
205
|
+
nostrRelays: DEFAULT_NOSTR_RELAYS,
|
|
206
|
+
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
207
|
+
electrumUrl: DEFAULT_ELECTRUM_URL,
|
|
208
|
+
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
209
|
+
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
210
|
+
},
|
|
211
|
+
testnet: {
|
|
212
|
+
name: "Testnet",
|
|
213
|
+
aggregatorUrl: TEST_AGGREGATOR_URL,
|
|
214
|
+
nostrRelays: TEST_NOSTR_RELAYS,
|
|
215
|
+
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
216
|
+
electrumUrl: TEST_ELECTRUM_URL,
|
|
217
|
+
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
218
|
+
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
219
|
+
},
|
|
220
|
+
dev: {
|
|
221
|
+
name: "Development",
|
|
222
|
+
aggregatorUrl: DEV_AGGREGATOR_URL,
|
|
223
|
+
nostrRelays: TEST_NOSTR_RELAYS,
|
|
224
|
+
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
225
|
+
electrumUrl: TEST_ELECTRUM_URL,
|
|
226
|
+
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
227
|
+
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
TIMEOUTS = {
|
|
231
|
+
/** WebSocket connection timeout */
|
|
232
|
+
WEBSOCKET_CONNECT: 1e4,
|
|
233
|
+
/** Nostr relay reconnect delay */
|
|
234
|
+
NOSTR_RECONNECT_DELAY: 3e3,
|
|
235
|
+
/** Max reconnect attempts */
|
|
236
|
+
MAX_RECONNECT_ATTEMPTS: 5,
|
|
237
|
+
/** Proof polling interval */
|
|
238
|
+
PROOF_POLL_INTERVAL: 1e3,
|
|
239
|
+
/** Sync interval */
|
|
240
|
+
SYNC_INTERVAL: 6e4
|
|
241
|
+
};
|
|
242
|
+
LIMITS = {
|
|
243
|
+
/** Min nametag length */
|
|
244
|
+
NAMETAG_MIN_LENGTH: 3,
|
|
245
|
+
/** Max nametag length */
|
|
246
|
+
NAMETAG_MAX_LENGTH: 20,
|
|
247
|
+
/** Max memo length */
|
|
248
|
+
MEMO_MAX_LENGTH: 500,
|
|
249
|
+
/** Max message length */
|
|
250
|
+
MESSAGE_MAX_LENGTH: 1e4
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
33
255
|
// core/bech32.ts
|
|
34
256
|
function convertBits(data, fromBits, toBits, pad) {
|
|
35
257
|
let acc = 0;
|
|
@@ -441,13 +663,16 @@ function disconnect() {
|
|
|
441
663
|
if (cb.timeoutId) clearTimeout(cb.timeoutId);
|
|
442
664
|
});
|
|
443
665
|
connectionCallbacks.length = 0;
|
|
666
|
+
blockSubscribers.length = 0;
|
|
667
|
+
lastBlockHeader = null;
|
|
444
668
|
}
|
|
445
669
|
var DEFAULT_ENDPOINT, ws, isConnected, isConnecting, requestId, intentionalClose, reconnectAttempts, isBlockSubscribed, lastBlockHeader, pending, blockSubscribers, connectionCallbacks, MAX_RECONNECT_ATTEMPTS, BASE_DELAY, MAX_DELAY, RPC_TIMEOUT, CONNECTION_TIMEOUT;
|
|
446
670
|
var init_network = __esm({
|
|
447
671
|
"l1/network.ts"() {
|
|
448
672
|
"use strict";
|
|
449
673
|
init_addressToScriptHash();
|
|
450
|
-
|
|
674
|
+
init_constants();
|
|
675
|
+
DEFAULT_ENDPOINT = DEFAULT_ELECTRUM_URL;
|
|
451
676
|
ws = null;
|
|
452
677
|
isConnected = false;
|
|
453
678
|
isConnecting = false;
|
|
@@ -611,6 +836,9 @@ __export(index_exports, {
|
|
|
611
836
|
});
|
|
612
837
|
module.exports = __toCommonJS(index_exports);
|
|
613
838
|
|
|
839
|
+
// modules/payments/L1PaymentsModule.ts
|
|
840
|
+
init_constants();
|
|
841
|
+
|
|
614
842
|
// l1/index.ts
|
|
615
843
|
var l1_exports = {};
|
|
616
844
|
__export(l1_exports, {
|
|
@@ -1796,7 +2024,7 @@ var L1PaymentsModule = class {
|
|
|
1796
2024
|
_transport;
|
|
1797
2025
|
constructor(config) {
|
|
1798
2026
|
this._config = {
|
|
1799
|
-
electrumUrl: config?.electrumUrl ??
|
|
2027
|
+
electrumUrl: config?.electrumUrl ?? DEFAULT_ELECTRUM_URL,
|
|
1800
2028
|
network: config?.network ?? "mainnet",
|
|
1801
2029
|
defaultFeeRate: config?.defaultFeeRate ?? 10,
|
|
1802
2030
|
enableVesting: config?.enableVesting ?? true
|
|
@@ -2636,221 +2864,8 @@ var NametagMinter = class {
|
|
|
2636
2864
|
}
|
|
2637
2865
|
};
|
|
2638
2866
|
|
|
2639
|
-
//
|
|
2640
|
-
|
|
2641
|
-
var DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
|
|
2642
|
-
var STORAGE_KEYS_GLOBAL = {
|
|
2643
|
-
/** Encrypted BIP39 mnemonic */
|
|
2644
|
-
MNEMONIC: "mnemonic",
|
|
2645
|
-
/** Encrypted master private key */
|
|
2646
|
-
MASTER_KEY: "master_key",
|
|
2647
|
-
/** BIP32 chain code */
|
|
2648
|
-
CHAIN_CODE: "chain_code",
|
|
2649
|
-
/** HD derivation path (full path like m/44'/0'/0'/0/0) */
|
|
2650
|
-
DERIVATION_PATH: "derivation_path",
|
|
2651
|
-
/** Base derivation path (like m/44'/0'/0' without chain/index) */
|
|
2652
|
-
BASE_PATH: "base_path",
|
|
2653
|
-
/** Derivation mode: bip32, wif_hmac, legacy_hmac */
|
|
2654
|
-
DERIVATION_MODE: "derivation_mode",
|
|
2655
|
-
/** Wallet source: mnemonic, file, unknown */
|
|
2656
|
-
WALLET_SOURCE: "wallet_source",
|
|
2657
|
-
/** Wallet existence flag */
|
|
2658
|
-
WALLET_EXISTS: "wallet_exists",
|
|
2659
|
-
/** Current active address index */
|
|
2660
|
-
CURRENT_ADDRESS_INDEX: "current_address_index",
|
|
2661
|
-
/** Nametag cache per address (separate from tracked addresses registry) */
|
|
2662
|
-
ADDRESS_NAMETAGS: "address_nametags",
|
|
2663
|
-
/** Active addresses registry (JSON: TrackedAddressesStorage) */
|
|
2664
|
-
TRACKED_ADDRESSES: "tracked_addresses",
|
|
2665
|
-
/** Last processed Nostr wallet event timestamp (unix seconds), keyed per pubkey */
|
|
2666
|
-
LAST_WALLET_EVENT_TS: "last_wallet_event_ts",
|
|
2667
|
-
/** Group chat: last used relay URL (stale data detection) — global, same relay for all addresses */
|
|
2668
|
-
GROUP_CHAT_RELAY_URL: "group_chat_relay_url",
|
|
2669
|
-
/** Cached token registry JSON (fetched from remote) */
|
|
2670
|
-
TOKEN_REGISTRY_CACHE: "token_registry_cache",
|
|
2671
|
-
/** Timestamp of last token registry cache update (ms since epoch) */
|
|
2672
|
-
TOKEN_REGISTRY_CACHE_TS: "token_registry_cache_ts",
|
|
2673
|
-
/** Cached price data JSON (from CoinGecko or other provider) */
|
|
2674
|
-
PRICE_CACHE: "price_cache",
|
|
2675
|
-
/** Timestamp of last price cache update (ms since epoch) */
|
|
2676
|
-
PRICE_CACHE_TS: "price_cache_ts"
|
|
2677
|
-
};
|
|
2678
|
-
var STORAGE_KEYS_ADDRESS = {
|
|
2679
|
-
/** Pending transfers for this address */
|
|
2680
|
-
PENDING_TRANSFERS: "pending_transfers",
|
|
2681
|
-
/** Transfer outbox for this address */
|
|
2682
|
-
OUTBOX: "outbox",
|
|
2683
|
-
/** Conversations for this address */
|
|
2684
|
-
CONVERSATIONS: "conversations",
|
|
2685
|
-
/** Messages for this address */
|
|
2686
|
-
MESSAGES: "messages",
|
|
2687
|
-
/** Transaction history for this address */
|
|
2688
|
-
TRANSACTION_HISTORY: "transaction_history",
|
|
2689
|
-
/** Pending V5 finalization tokens (unconfirmed instant split tokens) */
|
|
2690
|
-
PENDING_V5_TOKENS: "pending_v5_tokens",
|
|
2691
|
-
/** Group chat: joined groups for this address */
|
|
2692
|
-
GROUP_CHAT_GROUPS: "group_chat_groups",
|
|
2693
|
-
/** Group chat: messages for this address */
|
|
2694
|
-
GROUP_CHAT_MESSAGES: "group_chat_messages",
|
|
2695
|
-
/** Group chat: members for this address */
|
|
2696
|
-
GROUP_CHAT_MEMBERS: "group_chat_members",
|
|
2697
|
-
/** Group chat: processed event IDs for deduplication */
|
|
2698
|
-
GROUP_CHAT_PROCESSED_EVENTS: "group_chat_processed_events"
|
|
2699
|
-
};
|
|
2700
|
-
var STORAGE_KEYS = {
|
|
2701
|
-
...STORAGE_KEYS_GLOBAL,
|
|
2702
|
-
...STORAGE_KEYS_ADDRESS
|
|
2703
|
-
};
|
|
2704
|
-
function getAddressStorageKey(addressId, key) {
|
|
2705
|
-
return `${addressId}_${key}`;
|
|
2706
|
-
}
|
|
2707
|
-
function getAddressId(directAddress) {
|
|
2708
|
-
let hash = directAddress;
|
|
2709
|
-
if (hash.startsWith("DIRECT://")) {
|
|
2710
|
-
hash = hash.slice(9);
|
|
2711
|
-
} else if (hash.startsWith("DIRECT:")) {
|
|
2712
|
-
hash = hash.slice(7);
|
|
2713
|
-
}
|
|
2714
|
-
const first = hash.slice(0, 6).toLowerCase();
|
|
2715
|
-
const last = hash.slice(-6).toLowerCase();
|
|
2716
|
-
return `DIRECT_${first}_${last}`;
|
|
2717
|
-
}
|
|
2718
|
-
var DEFAULT_NOSTR_RELAYS = [
|
|
2719
|
-
"wss://relay.unicity.network",
|
|
2720
|
-
"wss://relay.damus.io",
|
|
2721
|
-
"wss://nos.lol",
|
|
2722
|
-
"wss://relay.nostr.band"
|
|
2723
|
-
];
|
|
2724
|
-
var NOSTR_EVENT_KINDS = {
|
|
2725
|
-
/** NIP-04 encrypted direct message */
|
|
2726
|
-
DIRECT_MESSAGE: 4,
|
|
2727
|
-
/** Token transfer (Unicity custom - 31113) */
|
|
2728
|
-
TOKEN_TRANSFER: 31113,
|
|
2729
|
-
/** Payment request (Unicity custom - 31115) */
|
|
2730
|
-
PAYMENT_REQUEST: 31115,
|
|
2731
|
-
/** Payment request response (Unicity custom - 31116) */
|
|
2732
|
-
PAYMENT_REQUEST_RESPONSE: 31116,
|
|
2733
|
-
/** Nametag binding (NIP-78 app-specific data) */
|
|
2734
|
-
NAMETAG_BINDING: 30078,
|
|
2735
|
-
/** Public broadcast */
|
|
2736
|
-
BROADCAST: 1
|
|
2737
|
-
};
|
|
2738
|
-
var NIP29_KINDS = {
|
|
2739
|
-
/** Chat message sent to group */
|
|
2740
|
-
CHAT_MESSAGE: 9,
|
|
2741
|
-
/** Thread root message */
|
|
2742
|
-
THREAD_ROOT: 11,
|
|
2743
|
-
/** Thread reply message */
|
|
2744
|
-
THREAD_REPLY: 12,
|
|
2745
|
-
/** User join request */
|
|
2746
|
-
JOIN_REQUEST: 9021,
|
|
2747
|
-
/** User leave request */
|
|
2748
|
-
LEAVE_REQUEST: 9022,
|
|
2749
|
-
/** Admin: add/update user */
|
|
2750
|
-
PUT_USER: 9e3,
|
|
2751
|
-
/** Admin: remove user */
|
|
2752
|
-
REMOVE_USER: 9001,
|
|
2753
|
-
/** Admin: edit group metadata */
|
|
2754
|
-
EDIT_METADATA: 9002,
|
|
2755
|
-
/** Admin: delete event */
|
|
2756
|
-
DELETE_EVENT: 9005,
|
|
2757
|
-
/** Admin: create group */
|
|
2758
|
-
CREATE_GROUP: 9007,
|
|
2759
|
-
/** Admin: delete group */
|
|
2760
|
-
DELETE_GROUP: 9008,
|
|
2761
|
-
/** Admin: create invite code */
|
|
2762
|
-
CREATE_INVITE: 9009,
|
|
2763
|
-
/** Relay-signed group metadata */
|
|
2764
|
-
GROUP_METADATA: 39e3,
|
|
2765
|
-
/** Relay-signed group admins */
|
|
2766
|
-
GROUP_ADMINS: 39001,
|
|
2767
|
-
/** Relay-signed group members */
|
|
2768
|
-
GROUP_MEMBERS: 39002,
|
|
2769
|
-
/** Relay-signed group roles */
|
|
2770
|
-
GROUP_ROLES: 39003
|
|
2771
|
-
};
|
|
2772
|
-
var DEFAULT_AGGREGATOR_URL = "https://aggregator.unicity.network/rpc";
|
|
2773
|
-
var DEV_AGGREGATOR_URL = "https://dev-aggregator.dyndns.org/rpc";
|
|
2774
|
-
var TEST_AGGREGATOR_URL = "https://goggregator-test.unicity.network";
|
|
2775
|
-
var DEFAULT_AGGREGATOR_TIMEOUT = 3e4;
|
|
2776
|
-
var DEFAULT_IPFS_GATEWAYS = [
|
|
2777
|
-
"https://unicity-ipfs1.dyndns.org"
|
|
2778
|
-
];
|
|
2779
|
-
var DEFAULT_IPFS_BOOTSTRAP_PEERS = [
|
|
2780
|
-
"/dns4/unicity-ipfs2.dyndns.org/tcp/4001/p2p/12D3KooWLNi5NDPPHbrfJakAQqwBqymYTTwMQXQKEWuCrJNDdmfh",
|
|
2781
|
-
"/dns4/unicity-ipfs3.dyndns.org/tcp/4001/p2p/12D3KooWQ4aujVE4ShLjdusNZBdffq3TbzrwT2DuWZY9H1Gxhwn6",
|
|
2782
|
-
"/dns4/unicity-ipfs4.dyndns.org/tcp/4001/p2p/12D3KooWJ1ByPfUzUrpYvgxKU8NZrR8i6PU1tUgMEbQX9Hh2DEn1",
|
|
2783
|
-
"/dns4/unicity-ipfs5.dyndns.org/tcp/4001/p2p/12D3KooWB1MdZZGHN5B8TvWXntbycfe7Cjcz7n6eZ9eykZadvmDv"
|
|
2784
|
-
];
|
|
2785
|
-
var DEFAULT_BASE_PATH = "m/44'/0'/0'";
|
|
2786
|
-
var DEFAULT_DERIVATION_PATH = `${DEFAULT_BASE_PATH}/0/0`;
|
|
2787
|
-
var COIN_TYPES = {
|
|
2788
|
-
/** ALPHA token (L1 blockchain) */
|
|
2789
|
-
ALPHA: "ALPHA",
|
|
2790
|
-
/** Test token */
|
|
2791
|
-
TEST: "TEST"
|
|
2792
|
-
};
|
|
2793
|
-
var DEFAULT_ELECTRUM_URL = "wss://fulcrum.alpha.unicity.network:50004";
|
|
2794
|
-
var TEST_ELECTRUM_URL = "wss://fulcrum.alpha.testnet.unicity.network:50004";
|
|
2795
|
-
var TOKEN_REGISTRY_URL = "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity-ids.testnet.json";
|
|
2796
|
-
var TOKEN_REGISTRY_REFRESH_INTERVAL = 36e5;
|
|
2797
|
-
var TEST_NOSTR_RELAYS = [
|
|
2798
|
-
"wss://nostr-relay.testnet.unicity.network"
|
|
2799
|
-
];
|
|
2800
|
-
var DEFAULT_GROUP_RELAYS = [
|
|
2801
|
-
"wss://sphere-relay.unicity.network"
|
|
2802
|
-
];
|
|
2803
|
-
var NETWORKS = {
|
|
2804
|
-
mainnet: {
|
|
2805
|
-
name: "Mainnet",
|
|
2806
|
-
aggregatorUrl: DEFAULT_AGGREGATOR_URL,
|
|
2807
|
-
nostrRelays: DEFAULT_NOSTR_RELAYS,
|
|
2808
|
-
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
2809
|
-
electrumUrl: DEFAULT_ELECTRUM_URL,
|
|
2810
|
-
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
2811
|
-
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
2812
|
-
},
|
|
2813
|
-
testnet: {
|
|
2814
|
-
name: "Testnet",
|
|
2815
|
-
aggregatorUrl: TEST_AGGREGATOR_URL,
|
|
2816
|
-
nostrRelays: TEST_NOSTR_RELAYS,
|
|
2817
|
-
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
2818
|
-
electrumUrl: TEST_ELECTRUM_URL,
|
|
2819
|
-
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
2820
|
-
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
2821
|
-
},
|
|
2822
|
-
dev: {
|
|
2823
|
-
name: "Development",
|
|
2824
|
-
aggregatorUrl: DEV_AGGREGATOR_URL,
|
|
2825
|
-
nostrRelays: TEST_NOSTR_RELAYS,
|
|
2826
|
-
ipfsGateways: DEFAULT_IPFS_GATEWAYS,
|
|
2827
|
-
electrumUrl: TEST_ELECTRUM_URL,
|
|
2828
|
-
groupRelays: DEFAULT_GROUP_RELAYS,
|
|
2829
|
-
tokenRegistryUrl: TOKEN_REGISTRY_URL
|
|
2830
|
-
}
|
|
2831
|
-
};
|
|
2832
|
-
var TIMEOUTS = {
|
|
2833
|
-
/** WebSocket connection timeout */
|
|
2834
|
-
WEBSOCKET_CONNECT: 1e4,
|
|
2835
|
-
/** Nostr relay reconnect delay */
|
|
2836
|
-
NOSTR_RECONNECT_DELAY: 3e3,
|
|
2837
|
-
/** Max reconnect attempts */
|
|
2838
|
-
MAX_RECONNECT_ATTEMPTS: 5,
|
|
2839
|
-
/** Proof polling interval */
|
|
2840
|
-
PROOF_POLL_INTERVAL: 1e3,
|
|
2841
|
-
/** Sync interval */
|
|
2842
|
-
SYNC_INTERVAL: 6e4
|
|
2843
|
-
};
|
|
2844
|
-
var LIMITS = {
|
|
2845
|
-
/** Min nametag length */
|
|
2846
|
-
NAMETAG_MIN_LENGTH: 3,
|
|
2847
|
-
/** Max nametag length */
|
|
2848
|
-
NAMETAG_MAX_LENGTH: 20,
|
|
2849
|
-
/** Max memo length */
|
|
2850
|
-
MEMO_MAX_LENGTH: 500,
|
|
2851
|
-
/** Max message length */
|
|
2852
|
-
MESSAGE_MAX_LENGTH: 1e4
|
|
2853
|
-
};
|
|
2867
|
+
// modules/payments/PaymentsModule.ts
|
|
2868
|
+
init_constants();
|
|
2854
2869
|
|
|
2855
2870
|
// types/txf.ts
|
|
2856
2871
|
var ARCHIVED_PREFIX = "archived-";
|
|
@@ -2895,6 +2910,7 @@ function isValidTokenId(tokenId) {
|
|
|
2895
2910
|
}
|
|
2896
2911
|
|
|
2897
2912
|
// registry/TokenRegistry.ts
|
|
2913
|
+
init_constants();
|
|
2898
2914
|
var FETCH_TIMEOUT_MS = 1e4;
|
|
2899
2915
|
var TokenRegistry = class _TokenRegistry {
|
|
2900
2916
|
static instance = null;
|
|
@@ -7792,6 +7808,7 @@ var import_HashAlgorithm6 = require("@unicitylabs/state-transition-sdk/lib/hash/
|
|
|
7792
7808
|
var import_UnmaskedPredicate6 = require("@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicate");
|
|
7793
7809
|
|
|
7794
7810
|
// modules/communications/CommunicationsModule.ts
|
|
7811
|
+
init_constants();
|
|
7795
7812
|
var CommunicationsModule = class {
|
|
7796
7813
|
config;
|
|
7797
7814
|
deps = null;
|
|
@@ -8267,6 +8284,7 @@ function createCommunicationsModule(config) {
|
|
|
8267
8284
|
|
|
8268
8285
|
// modules/groupchat/GroupChatModule.ts
|
|
8269
8286
|
var import_nostr_js_sdk2 = require("@unicitylabs/nostr-js-sdk");
|
|
8287
|
+
init_constants();
|
|
8270
8288
|
|
|
8271
8289
|
// modules/groupchat/types.ts
|
|
8272
8290
|
var GroupRole = {
|
|
@@ -12111,6 +12129,9 @@ function createMarketModule(config) {
|
|
|
12111
12129
|
return new MarketModule(config);
|
|
12112
12130
|
}
|
|
12113
12131
|
|
|
12132
|
+
// core/Sphere.ts
|
|
12133
|
+
init_constants();
|
|
12134
|
+
|
|
12114
12135
|
// core/encryption.ts
|
|
12115
12136
|
var import_crypto_js6 = __toESM(require("crypto-js"), 1);
|
|
12116
12137
|
function encryptSimple(plaintext, password) {
|
|
@@ -12214,6 +12235,72 @@ async function scanAddressesImpl(deriveAddress, options = {}) {
|
|
|
12214
12235
|
};
|
|
12215
12236
|
}
|
|
12216
12237
|
|
|
12238
|
+
// core/discover.ts
|
|
12239
|
+
async function discoverAddressesImpl(deriveTransportPubkey, batchResolve, options = {}) {
|
|
12240
|
+
const maxAddresses = options.maxAddresses ?? 50;
|
|
12241
|
+
const gapLimit = options.gapLimit ?? 20;
|
|
12242
|
+
const batchSize = options.batchSize ?? 20;
|
|
12243
|
+
const { onProgress, signal } = options;
|
|
12244
|
+
const discovered = /* @__PURE__ */ new Map();
|
|
12245
|
+
let consecutiveEmpty = 0;
|
|
12246
|
+
let scanned = 0;
|
|
12247
|
+
const totalBatches = Math.ceil(maxAddresses / batchSize);
|
|
12248
|
+
for (let batchStart = 0; batchStart < maxAddresses; batchStart += batchSize) {
|
|
12249
|
+
if (signal?.aborted) break;
|
|
12250
|
+
if (consecutiveEmpty >= gapLimit) break;
|
|
12251
|
+
const batchEnd = Math.min(batchStart + batchSize, maxAddresses);
|
|
12252
|
+
const batchIndices = [];
|
|
12253
|
+
const pubkeyToIndex = /* @__PURE__ */ new Map();
|
|
12254
|
+
const pubkeyToInfo = /* @__PURE__ */ new Map();
|
|
12255
|
+
for (let i = batchStart; i < batchEnd; i++) {
|
|
12256
|
+
const info = deriveTransportPubkey(i);
|
|
12257
|
+
batchIndices.push(i);
|
|
12258
|
+
pubkeyToIndex.set(info.transportPubkey, i);
|
|
12259
|
+
pubkeyToInfo.set(info.transportPubkey, info);
|
|
12260
|
+
}
|
|
12261
|
+
const batchPubkeys = Array.from(pubkeyToIndex.keys());
|
|
12262
|
+
onProgress?.({
|
|
12263
|
+
currentBatch: Math.floor(batchStart / batchSize) + 1,
|
|
12264
|
+
totalBatches,
|
|
12265
|
+
discoveredCount: discovered.size,
|
|
12266
|
+
currentGap: consecutiveEmpty,
|
|
12267
|
+
phase: "transport"
|
|
12268
|
+
});
|
|
12269
|
+
const peerInfos = await batchResolve(batchPubkeys);
|
|
12270
|
+
const foundInBatch = /* @__PURE__ */ new Set();
|
|
12271
|
+
for (const peer of peerInfos) {
|
|
12272
|
+
const index = pubkeyToIndex.get(peer.transportPubkey);
|
|
12273
|
+
if (index !== void 0) {
|
|
12274
|
+
foundInBatch.add(index);
|
|
12275
|
+
const derived = pubkeyToInfo.get(peer.transportPubkey);
|
|
12276
|
+
discovered.set(index, {
|
|
12277
|
+
index,
|
|
12278
|
+
l1Address: peer.l1Address || derived.l1Address,
|
|
12279
|
+
directAddress: peer.directAddress || derived.directAddress,
|
|
12280
|
+
chainPubkey: peer.chainPubkey || derived.chainPubkey,
|
|
12281
|
+
nametag: peer.nametag,
|
|
12282
|
+
l1Balance: 0,
|
|
12283
|
+
source: "transport"
|
|
12284
|
+
});
|
|
12285
|
+
}
|
|
12286
|
+
}
|
|
12287
|
+
for (const idx of batchIndices) {
|
|
12288
|
+
scanned++;
|
|
12289
|
+
if (foundInBatch.has(idx)) {
|
|
12290
|
+
consecutiveEmpty = 0;
|
|
12291
|
+
} else {
|
|
12292
|
+
consecutiveEmpty++;
|
|
12293
|
+
if (consecutiveEmpty >= gapLimit) break;
|
|
12294
|
+
}
|
|
12295
|
+
}
|
|
12296
|
+
}
|
|
12297
|
+
return {
|
|
12298
|
+
addresses: Array.from(discovered.values()).sort((a, b) => a.index - b.index),
|
|
12299
|
+
scannedCount: scanned,
|
|
12300
|
+
aborted: signal?.aborted ?? false
|
|
12301
|
+
};
|
|
12302
|
+
}
|
|
12303
|
+
|
|
12217
12304
|
// core/Sphere.ts
|
|
12218
12305
|
init_network();
|
|
12219
12306
|
|
|
@@ -13036,7 +13123,9 @@ var Sphere = class _Sphere {
|
|
|
13036
13123
|
price: options.price,
|
|
13037
13124
|
groupChat,
|
|
13038
13125
|
market,
|
|
13039
|
-
password: options.password
|
|
13126
|
+
password: options.password,
|
|
13127
|
+
discoverAddresses: options.discoverAddresses,
|
|
13128
|
+
onProgress: options.onProgress
|
|
13040
13129
|
});
|
|
13041
13130
|
return { sphere: sphere2, created: false };
|
|
13042
13131
|
}
|
|
@@ -13064,7 +13153,9 @@ var Sphere = class _Sphere {
|
|
|
13064
13153
|
price: options.price,
|
|
13065
13154
|
groupChat,
|
|
13066
13155
|
market,
|
|
13067
|
-
password: options.password
|
|
13156
|
+
password: options.password,
|
|
13157
|
+
discoverAddresses: options.discoverAddresses,
|
|
13158
|
+
onProgress: options.onProgress
|
|
13068
13159
|
});
|
|
13069
13160
|
return { sphere, created: true, generatedMnemonic };
|
|
13070
13161
|
}
|
|
@@ -13125,6 +13216,7 @@ var Sphere = class _Sphere {
|
|
|
13125
13216
|
if (await _Sphere.exists(options.storage)) {
|
|
13126
13217
|
throw new Error("Wallet already exists. Use Sphere.load() or Sphere.clear() first.");
|
|
13127
13218
|
}
|
|
13219
|
+
const progress = options.onProgress;
|
|
13128
13220
|
if (!options.storage.isConnected()) {
|
|
13129
13221
|
await options.storage.connect();
|
|
13130
13222
|
}
|
|
@@ -13142,20 +13234,39 @@ var Sphere = class _Sphere {
|
|
|
13142
13234
|
marketConfig
|
|
13143
13235
|
);
|
|
13144
13236
|
sphere._password = options.password ?? null;
|
|
13237
|
+
progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
|
|
13145
13238
|
await sphere.storeMnemonic(options.mnemonic, options.derivationPath);
|
|
13146
13239
|
await sphere.initializeIdentityFromMnemonic(options.mnemonic, options.derivationPath);
|
|
13240
|
+
progress?.({ step: "initializing", message: "Initializing wallet..." });
|
|
13147
13241
|
await sphere.initializeProviders();
|
|
13148
13242
|
await sphere.initializeModules();
|
|
13243
|
+
progress?.({ step: "finalizing", message: "Finalizing wallet..." });
|
|
13149
13244
|
await sphere.finalizeWalletCreation();
|
|
13150
13245
|
sphere._initialized = true;
|
|
13151
13246
|
_Sphere.instance = sphere;
|
|
13152
13247
|
await sphere.ensureAddressTracked(0);
|
|
13153
13248
|
if (options.nametag) {
|
|
13249
|
+
progress?.({ step: "registering_nametag", message: "Registering nametag..." });
|
|
13154
13250
|
await sphere.registerNametag(options.nametag);
|
|
13155
13251
|
} else {
|
|
13252
|
+
progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
|
|
13156
13253
|
await sphere.recoverNametagFromTransport();
|
|
13254
|
+
progress?.({ step: "syncing_identity", message: "Publishing identity..." });
|
|
13157
13255
|
await sphere.syncIdentityWithTransport();
|
|
13158
13256
|
}
|
|
13257
|
+
if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
|
|
13258
|
+
progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
|
|
13259
|
+
try {
|
|
13260
|
+
const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
|
|
13261
|
+
const result = await sphere.discoverAddresses(discoverOpts);
|
|
13262
|
+
if (result.addresses.length > 0) {
|
|
13263
|
+
console.log(`[Sphere.create] Address discovery: found ${result.addresses.length} address(es)`);
|
|
13264
|
+
}
|
|
13265
|
+
} catch (err) {
|
|
13266
|
+
console.warn("[Sphere.create] Address discovery failed (non-fatal):", err);
|
|
13267
|
+
}
|
|
13268
|
+
}
|
|
13269
|
+
progress?.({ step: "complete", message: "Wallet created" });
|
|
13159
13270
|
return sphere;
|
|
13160
13271
|
}
|
|
13161
13272
|
/**
|
|
@@ -13165,6 +13276,7 @@ var Sphere = class _Sphere {
|
|
|
13165
13276
|
if (!await _Sphere.exists(options.storage)) {
|
|
13166
13277
|
throw new Error("No wallet found. Use Sphere.create() to create a new wallet.");
|
|
13167
13278
|
}
|
|
13279
|
+
const progress = options.onProgress;
|
|
13168
13280
|
_Sphere.configureTokenRegistry(options.storage, options.network);
|
|
13169
13281
|
const groupChatConfig = _Sphere.resolveGroupChatConfig(options.groupChat, options.network);
|
|
13170
13282
|
const marketConfig = _Sphere.resolveMarketConfig(options.market);
|
|
@@ -13182,13 +13294,17 @@ var Sphere = class _Sphere {
|
|
|
13182
13294
|
if (!options.storage.isConnected()) {
|
|
13183
13295
|
await options.storage.connect();
|
|
13184
13296
|
}
|
|
13297
|
+
progress?.({ step: "storing_keys", message: "Loading wallet keys..." });
|
|
13185
13298
|
await sphere.loadIdentityFromStorage();
|
|
13299
|
+
progress?.({ step: "initializing", message: "Initializing wallet..." });
|
|
13186
13300
|
await sphere.initializeProviders();
|
|
13187
13301
|
await sphere.initializeModules();
|
|
13302
|
+
progress?.({ step: "syncing_identity", message: "Publishing identity..." });
|
|
13188
13303
|
await sphere.syncIdentityWithTransport();
|
|
13189
13304
|
sphere._initialized = true;
|
|
13190
13305
|
_Sphere.instance = sphere;
|
|
13191
13306
|
if (sphere._identity?.nametag && !sphere._payments.hasNametag()) {
|
|
13307
|
+
progress?.({ step: "registering_nametag", message: "Restoring nametag token..." });
|
|
13192
13308
|
console.log(`[Sphere] Nametag @${sphere._identity.nametag} has no token, attempting to mint...`);
|
|
13193
13309
|
try {
|
|
13194
13310
|
const result = await sphere.mintNametag(sphere._identity.nametag);
|
|
@@ -13201,6 +13317,19 @@ var Sphere = class _Sphere {
|
|
|
13201
13317
|
console.warn(`[Sphere] Nametag token mint failed:`, err);
|
|
13202
13318
|
}
|
|
13203
13319
|
}
|
|
13320
|
+
if (options.discoverAddresses !== false && sphere._transport.discoverAddresses && sphere._masterKey) {
|
|
13321
|
+
progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
|
|
13322
|
+
try {
|
|
13323
|
+
const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
|
|
13324
|
+
const result = await sphere.discoverAddresses(discoverOpts);
|
|
13325
|
+
if (result.addresses.length > 0) {
|
|
13326
|
+
console.log(`[Sphere.load] Address discovery: found ${result.addresses.length} address(es)`);
|
|
13327
|
+
}
|
|
13328
|
+
} catch (err) {
|
|
13329
|
+
console.warn("[Sphere.load] Address discovery failed (non-fatal):", err);
|
|
13330
|
+
}
|
|
13331
|
+
}
|
|
13332
|
+
progress?.({ step: "complete", message: "Wallet loaded" });
|
|
13204
13333
|
return sphere;
|
|
13205
13334
|
}
|
|
13206
13335
|
/**
|
|
@@ -13210,9 +13339,11 @@ var Sphere = class _Sphere {
|
|
|
13210
13339
|
if (!options.mnemonic && !options.masterKey) {
|
|
13211
13340
|
throw new Error("Either mnemonic or masterKey is required");
|
|
13212
13341
|
}
|
|
13342
|
+
const progress = options.onProgress;
|
|
13213
13343
|
console.log("[Sphere.import] Starting import...");
|
|
13214
13344
|
const needsClear = _Sphere.instance !== null || await _Sphere.exists(options.storage);
|
|
13215
13345
|
if (needsClear) {
|
|
13346
|
+
progress?.({ step: "clearing", message: "Clearing previous wallet data..." });
|
|
13216
13347
|
console.log("[Sphere.import] Clearing existing wallet data...");
|
|
13217
13348
|
await _Sphere.clear({ storage: options.storage, tokenStorage: options.tokenStorage });
|
|
13218
13349
|
console.log("[Sphere.import] Clear done");
|
|
@@ -13237,6 +13368,7 @@ var Sphere = class _Sphere {
|
|
|
13237
13368
|
marketConfig
|
|
13238
13369
|
);
|
|
13239
13370
|
sphere._password = options.password ?? null;
|
|
13371
|
+
progress?.({ step: "storing_keys", message: "Storing wallet keys..." });
|
|
13240
13372
|
if (options.mnemonic) {
|
|
13241
13373
|
if (!_Sphere.validateMnemonic(options.mnemonic)) {
|
|
13242
13374
|
throw new Error("Invalid mnemonic");
|
|
@@ -13261,17 +13393,21 @@ var Sphere = class _Sphere {
|
|
|
13261
13393
|
options.derivationPath
|
|
13262
13394
|
);
|
|
13263
13395
|
}
|
|
13396
|
+
progress?.({ step: "initializing", message: "Initializing wallet..." });
|
|
13264
13397
|
console.log("[Sphere.import] Initializing providers...");
|
|
13265
13398
|
await sphere.initializeProviders();
|
|
13266
13399
|
console.log("[Sphere.import] Providers initialized. Initializing modules...");
|
|
13267
13400
|
await sphere.initializeModules();
|
|
13268
13401
|
console.log("[Sphere.import] Modules initialized");
|
|
13269
13402
|
if (!options.nametag) {
|
|
13403
|
+
progress?.({ step: "recovering_nametag", message: "Recovering nametag..." });
|
|
13270
13404
|
console.log("[Sphere.import] Recovering nametag from transport...");
|
|
13271
13405
|
await sphere.recoverNametagFromTransport();
|
|
13272
13406
|
console.log("[Sphere.import] Nametag recovery done");
|
|
13407
|
+
progress?.({ step: "syncing_identity", message: "Publishing identity..." });
|
|
13273
13408
|
await sphere.syncIdentityWithTransport();
|
|
13274
13409
|
}
|
|
13410
|
+
progress?.({ step: "finalizing", message: "Finalizing wallet..." });
|
|
13275
13411
|
console.log("[Sphere.import] Finalizing wallet creation...");
|
|
13276
13412
|
await sphere.finalizeWalletCreation();
|
|
13277
13413
|
sphere._initialized = true;
|
|
@@ -13279,10 +13415,12 @@ var Sphere = class _Sphere {
|
|
|
13279
13415
|
console.log("[Sphere.import] Tracking address 0...");
|
|
13280
13416
|
await sphere.ensureAddressTracked(0);
|
|
13281
13417
|
if (options.nametag) {
|
|
13418
|
+
progress?.({ step: "registering_nametag", message: "Registering nametag..." });
|
|
13282
13419
|
console.log("[Sphere.import] Registering nametag...");
|
|
13283
13420
|
await sphere.registerNametag(options.nametag);
|
|
13284
13421
|
}
|
|
13285
13422
|
if (sphere._tokenStorageProviders.size > 0) {
|
|
13423
|
+
progress?.({ step: "syncing_tokens", message: "Syncing tokens..." });
|
|
13286
13424
|
try {
|
|
13287
13425
|
const syncResult = await sphere._payments.sync();
|
|
13288
13426
|
console.log(`[Sphere.import] Auto-sync: +${syncResult.added} -${syncResult.removed}`);
|
|
@@ -13290,6 +13428,19 @@ var Sphere = class _Sphere {
|
|
|
13290
13428
|
console.warn("[Sphere.import] Auto-sync failed (non-fatal):", err);
|
|
13291
13429
|
}
|
|
13292
13430
|
}
|
|
13431
|
+
if (options.discoverAddresses !== false && sphere._transport.discoverAddresses) {
|
|
13432
|
+
progress?.({ step: "discovering_addresses", message: "Discovering addresses..." });
|
|
13433
|
+
try {
|
|
13434
|
+
const discoverOpts = typeof options.discoverAddresses === "object" ? { ...options.discoverAddresses, autoTrack: options.discoverAddresses.autoTrack ?? true } : { autoTrack: true };
|
|
13435
|
+
const result = await sphere.discoverAddresses(discoverOpts);
|
|
13436
|
+
if (result.addresses.length > 0) {
|
|
13437
|
+
console.log(`[Sphere.import] Address discovery: found ${result.addresses.length} address(es)`);
|
|
13438
|
+
}
|
|
13439
|
+
} catch (err) {
|
|
13440
|
+
console.warn("[Sphere.import] Address discovery failed (non-fatal):", err);
|
|
13441
|
+
}
|
|
13442
|
+
}
|
|
13443
|
+
progress?.({ step: "complete", message: "Import complete" });
|
|
13293
13444
|
console.log("[Sphere.import] Import complete");
|
|
13294
13445
|
return sphere;
|
|
13295
13446
|
}
|
|
@@ -14158,6 +14309,23 @@ var Sphere = class _Sphere {
|
|
|
14158
14309
|
await provider.initialize();
|
|
14159
14310
|
}
|
|
14160
14311
|
await this.reinitializeModulesForNewAddress();
|
|
14312
|
+
this.emitEvent("identity:changed", {
|
|
14313
|
+
l1Address: this._identity.l1Address,
|
|
14314
|
+
directAddress: this._identity.directAddress,
|
|
14315
|
+
chainPubkey: this._identity.chainPubkey,
|
|
14316
|
+
nametag: this._identity.nametag,
|
|
14317
|
+
addressIndex: index
|
|
14318
|
+
});
|
|
14319
|
+
console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
|
|
14320
|
+
this.postSwitchSync(index, newNametag).catch((err) => {
|
|
14321
|
+
console.warn(`[Sphere] Post-switch sync failed for address ${index}:`, err);
|
|
14322
|
+
});
|
|
14323
|
+
}
|
|
14324
|
+
/**
|
|
14325
|
+
* Background transport sync and nametag operations after address switch.
|
|
14326
|
+
* Runs after switchToAddress returns so L1/L3 queries can start immediately.
|
|
14327
|
+
*/
|
|
14328
|
+
async postSwitchSync(index, newNametag) {
|
|
14161
14329
|
if (!newNametag) {
|
|
14162
14330
|
await this.syncIdentityWithTransport();
|
|
14163
14331
|
}
|
|
@@ -14180,7 +14348,7 @@ var Sphere = class _Sphere {
|
|
|
14180
14348
|
nametag: newNametag,
|
|
14181
14349
|
addressIndex: index
|
|
14182
14350
|
});
|
|
14183
|
-
} else if (this._identity
|
|
14351
|
+
} else if (this._identity?.nametag && !this._payments.hasNametag()) {
|
|
14184
14352
|
console.log(`[Sphere] Nametag @${this._identity.nametag} has no token after switch, minting...`);
|
|
14185
14353
|
try {
|
|
14186
14354
|
const result = await this.mintNametag(this._identity.nametag);
|
|
@@ -14193,14 +14361,6 @@ var Sphere = class _Sphere {
|
|
|
14193
14361
|
console.warn(`[Sphere] Nametag token mint failed after switch:`, err);
|
|
14194
14362
|
}
|
|
14195
14363
|
}
|
|
14196
|
-
this.emitEvent("identity:changed", {
|
|
14197
|
-
l1Address: this._identity.l1Address,
|
|
14198
|
-
directAddress: this._identity.directAddress,
|
|
14199
|
-
chainPubkey: this._identity.chainPubkey,
|
|
14200
|
-
nametag: this._identity.nametag,
|
|
14201
|
-
addressIndex: index
|
|
14202
|
-
});
|
|
14203
|
-
console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
|
|
14204
14364
|
}
|
|
14205
14365
|
/**
|
|
14206
14366
|
* Re-initialize modules after address switch
|
|
@@ -14407,6 +14567,98 @@ var Sphere = class _Sphere {
|
|
|
14407
14567
|
await this.persistTrackedAddresses();
|
|
14408
14568
|
await this.persistAddressNametags();
|
|
14409
14569
|
}
|
|
14570
|
+
/**
|
|
14571
|
+
* Discover previously used HD addresses.
|
|
14572
|
+
*
|
|
14573
|
+
* Primary: queries Nostr relay for identity binding events (fast, single batch query).
|
|
14574
|
+
* Secondary: runs L1 balance scan to find legacy addresses with no binding event.
|
|
14575
|
+
*
|
|
14576
|
+
* @example
|
|
14577
|
+
* ```ts
|
|
14578
|
+
* const result = await sphere.discoverAddresses();
|
|
14579
|
+
* console.log(`Found ${result.addresses.length} addresses`);
|
|
14580
|
+
*
|
|
14581
|
+
* // With auto-tracking
|
|
14582
|
+
* await sphere.discoverAddresses({ autoTrack: true });
|
|
14583
|
+
* ```
|
|
14584
|
+
*/
|
|
14585
|
+
async discoverAddresses(options = {}) {
|
|
14586
|
+
this.ensureReady();
|
|
14587
|
+
if (!this._masterKey) {
|
|
14588
|
+
throw new Error("Address discovery requires HD master key");
|
|
14589
|
+
}
|
|
14590
|
+
if (!this._transport.discoverAddresses) {
|
|
14591
|
+
throw new Error("Transport provider does not support address discovery");
|
|
14592
|
+
}
|
|
14593
|
+
const includeL1Scan = options.includeL1Scan ?? true;
|
|
14594
|
+
const transportResult = await discoverAddressesImpl(
|
|
14595
|
+
(index) => {
|
|
14596
|
+
const addrInfo = this._deriveAddressInternal(index, false);
|
|
14597
|
+
return {
|
|
14598
|
+
transportPubkey: addrInfo.publicKey.slice(2),
|
|
14599
|
+
// x-only 32 bytes
|
|
14600
|
+
chainPubkey: addrInfo.publicKey,
|
|
14601
|
+
l1Address: addrInfo.address,
|
|
14602
|
+
directAddress: ""
|
|
14603
|
+
// not needed for discovery query
|
|
14604
|
+
};
|
|
14605
|
+
},
|
|
14606
|
+
(pubkeys) => this._transport.discoverAddresses(pubkeys),
|
|
14607
|
+
options
|
|
14608
|
+
);
|
|
14609
|
+
if (includeL1Scan) {
|
|
14610
|
+
try {
|
|
14611
|
+
const l1Result = await this.scanAddresses({
|
|
14612
|
+
maxAddresses: options.maxAddresses,
|
|
14613
|
+
gapLimit: options.gapLimit,
|
|
14614
|
+
signal: options.signal,
|
|
14615
|
+
onProgress: options.onProgress ? (p) => options.onProgress({
|
|
14616
|
+
currentBatch: 0,
|
|
14617
|
+
totalBatches: 0,
|
|
14618
|
+
discoveredCount: p.foundCount,
|
|
14619
|
+
currentGap: p.currentGap,
|
|
14620
|
+
phase: "l1"
|
|
14621
|
+
}) : void 0
|
|
14622
|
+
});
|
|
14623
|
+
for (const l1Addr of l1Result.addresses) {
|
|
14624
|
+
if (l1Addr.isChange) continue;
|
|
14625
|
+
const existing = transportResult.addresses.find((a) => a.index === l1Addr.index);
|
|
14626
|
+
if (existing) {
|
|
14627
|
+
existing.l1Balance = l1Addr.balance;
|
|
14628
|
+
existing.source = "both";
|
|
14629
|
+
if (!existing.nametag && l1Addr.nametag) {
|
|
14630
|
+
existing.nametag = l1Addr.nametag;
|
|
14631
|
+
}
|
|
14632
|
+
} else {
|
|
14633
|
+
const addrInfo = this._deriveAddressInternal(l1Addr.index, false);
|
|
14634
|
+
transportResult.addresses.push({
|
|
14635
|
+
index: l1Addr.index,
|
|
14636
|
+
l1Address: l1Addr.address,
|
|
14637
|
+
directAddress: "",
|
|
14638
|
+
chainPubkey: addrInfo.publicKey,
|
|
14639
|
+
nametag: l1Addr.nametag,
|
|
14640
|
+
l1Balance: l1Addr.balance,
|
|
14641
|
+
source: "l1"
|
|
14642
|
+
});
|
|
14643
|
+
}
|
|
14644
|
+
}
|
|
14645
|
+
transportResult.addresses.sort((a, b) => a.index - b.index);
|
|
14646
|
+
} catch (err) {
|
|
14647
|
+
console.warn("[Sphere] L1 scan failed during discovery (non-fatal):", err);
|
|
14648
|
+
}
|
|
14649
|
+
}
|
|
14650
|
+
if (options.autoTrack && transportResult.addresses.length > 0) {
|
|
14651
|
+
await this.trackScannedAddresses(
|
|
14652
|
+
transportResult.addresses.map((a) => ({
|
|
14653
|
+
index: a.index,
|
|
14654
|
+
// Preserve existing hidden state; default to false for newly discovered
|
|
14655
|
+
hidden: this._trackedAddresses.get(a.index)?.hidden ?? false,
|
|
14656
|
+
nametag: a.nametag
|
|
14657
|
+
}))
|
|
14658
|
+
);
|
|
14659
|
+
}
|
|
14660
|
+
return transportResult;
|
|
14661
|
+
}
|
|
14410
14662
|
// ===========================================================================
|
|
14411
14663
|
// Public Methods - Status
|
|
14412
14664
|
// ===========================================================================
|
|
@@ -14978,6 +15230,17 @@ var Sphere = class _Sphere {
|
|
|
14978
15230
|
return;
|
|
14979
15231
|
}
|
|
14980
15232
|
}
|
|
15233
|
+
const needsUpdate = !existing.directAddress || !existing.l1Address || !existing.chainPubkey || this._identity?.nametag && !existing.nametag;
|
|
15234
|
+
if (needsUpdate) {
|
|
15235
|
+
console.log("[Sphere] Existing binding incomplete, re-publishing with full data");
|
|
15236
|
+
await this._transport.publishIdentityBinding(
|
|
15237
|
+
this._identity.chainPubkey,
|
|
15238
|
+
this._identity.l1Address,
|
|
15239
|
+
this._identity.directAddress || "",
|
|
15240
|
+
this._identity?.nametag || existing.nametag || void 0
|
|
15241
|
+
);
|
|
15242
|
+
return;
|
|
15243
|
+
}
|
|
14981
15244
|
console.log("[Sphere] Existing binding found, skipping re-publish");
|
|
14982
15245
|
return;
|
|
14983
15246
|
}
|
|
@@ -15466,6 +15729,7 @@ function formatAmount(amount, options = {}) {
|
|
|
15466
15729
|
init_bech32();
|
|
15467
15730
|
|
|
15468
15731
|
// core/network-health.ts
|
|
15732
|
+
init_constants();
|
|
15469
15733
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
15470
15734
|
async function checkNetworkHealth(network = "testnet", options) {
|
|
15471
15735
|
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
@@ -15651,6 +15915,9 @@ async function runCustomCheck(name, checkFn, timeoutMs) {
|
|
|
15651
15915
|
}
|
|
15652
15916
|
}
|
|
15653
15917
|
|
|
15918
|
+
// index.ts
|
|
15919
|
+
init_constants();
|
|
15920
|
+
|
|
15654
15921
|
// types/payment-session.ts
|
|
15655
15922
|
function createPaymentSession(params) {
|
|
15656
15923
|
const now = Date.now();
|
|
@@ -15722,6 +15989,9 @@ var SphereError = class extends Error {
|
|
|
15722
15989
|
}
|
|
15723
15990
|
};
|
|
15724
15991
|
|
|
15992
|
+
// index.ts
|
|
15993
|
+
init_constants();
|
|
15994
|
+
|
|
15725
15995
|
// validation/token-validator.ts
|
|
15726
15996
|
var TokenValidator = class {
|
|
15727
15997
|
aggregatorClient = null;
|
|
@@ -16050,6 +16320,7 @@ function createTokenValidator(options) {
|
|
|
16050
16320
|
var import_nostr_js_sdk4 = require("@unicitylabs/nostr-js-sdk");
|
|
16051
16321
|
|
|
16052
16322
|
// price/CoinGeckoPriceProvider.ts
|
|
16323
|
+
init_constants();
|
|
16053
16324
|
var CoinGeckoPriceProvider = class {
|
|
16054
16325
|
platform = "coingecko";
|
|
16055
16326
|
cache = /* @__PURE__ */ new Map();
|