@unicitylabs/sphere-sdk 0.2.3 → 0.3.0
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/README.md +61 -20
- package/dist/core/index.cjs +5764 -3576
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +648 -256
- package/dist/core/index.d.ts +648 -256
- package/dist/core/index.js +5767 -3576
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/index.cjs +2118 -185
- package/dist/impl/browser/index.cjs.map +1 -1
- package/dist/impl/browser/index.js +2118 -185
- package/dist/impl/browser/index.js.map +1 -1
- package/dist/impl/browser/ipfs.cjs +1823 -513
- package/dist/impl/browser/ipfs.cjs.map +1 -1
- package/dist/impl/browser/ipfs.js +1823 -513
- package/dist/impl/browser/ipfs.js.map +1 -1
- package/dist/impl/nodejs/index.cjs +2110 -183
- package/dist/impl/nodejs/index.cjs.map +1 -1
- package/dist/impl/nodejs/index.d.cts +86 -23
- package/dist/impl/nodejs/index.d.ts +86 -23
- package/dist/impl/nodejs/index.js +2110 -183
- package/dist/impl/nodejs/index.js.map +1 -1
- package/dist/index.cjs +5782 -3603
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +719 -105
- package/dist/index.d.ts +719 -105
- package/dist/index.js +5780 -3603
- package/dist/index.js.map +1 -1
- package/package.json +28 -6
package/dist/core/index.d.cts
CHANGED
|
@@ -1,6 +1,73 @@
|
|
|
1
1
|
import { Token as Token$1 } from '@unicitylabs/state-transition-sdk/lib/token/Token';
|
|
2
2
|
import elliptic from 'elliptic';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Group Chat Types (NIP-29)
|
|
6
|
+
* Plain interfaces for SDK consumers — no classes, no UI helpers.
|
|
7
|
+
*/
|
|
8
|
+
declare const GroupRole: {
|
|
9
|
+
readonly ADMIN: "ADMIN";
|
|
10
|
+
readonly MODERATOR: "MODERATOR";
|
|
11
|
+
readonly MEMBER: "MEMBER";
|
|
12
|
+
};
|
|
13
|
+
type GroupRole = (typeof GroupRole)[keyof typeof GroupRole];
|
|
14
|
+
declare const GroupVisibility: {
|
|
15
|
+
readonly PUBLIC: "PUBLIC";
|
|
16
|
+
readonly PRIVATE: "PRIVATE";
|
|
17
|
+
};
|
|
18
|
+
type GroupVisibility = (typeof GroupVisibility)[keyof typeof GroupVisibility];
|
|
19
|
+
interface GroupData {
|
|
20
|
+
id: string;
|
|
21
|
+
relayUrl: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
picture?: string;
|
|
25
|
+
visibility: GroupVisibility;
|
|
26
|
+
createdAt: number;
|
|
27
|
+
updatedAt?: number;
|
|
28
|
+
memberCount?: number;
|
|
29
|
+
unreadCount?: number;
|
|
30
|
+
lastMessageTime?: number;
|
|
31
|
+
lastMessageText?: string;
|
|
32
|
+
/** When the current user joined this group locally (used to filter old events) */
|
|
33
|
+
localJoinedAt?: number;
|
|
34
|
+
}
|
|
35
|
+
interface GroupMessageData {
|
|
36
|
+
id?: string;
|
|
37
|
+
groupId: string;
|
|
38
|
+
content: string;
|
|
39
|
+
timestamp: number;
|
|
40
|
+
senderPubkey: string;
|
|
41
|
+
senderNametag?: string;
|
|
42
|
+
replyToId?: string;
|
|
43
|
+
previousIds?: string[];
|
|
44
|
+
}
|
|
45
|
+
interface GroupMemberData {
|
|
46
|
+
pubkey: string;
|
|
47
|
+
groupId: string;
|
|
48
|
+
role: GroupRole;
|
|
49
|
+
nametag?: string;
|
|
50
|
+
joinedAt: number;
|
|
51
|
+
}
|
|
52
|
+
interface GroupChatModuleConfig {
|
|
53
|
+
/** Override relay URLs (default: from network config) */
|
|
54
|
+
relays?: string[];
|
|
55
|
+
/** Default message fetch limit (default: 50) */
|
|
56
|
+
defaultMessageLimit?: number;
|
|
57
|
+
/** Max previous message IDs in ordering tags (default: 3) */
|
|
58
|
+
maxPreviousTags?: number;
|
|
59
|
+
/** Reconnect delay in ms (default: 3000) */
|
|
60
|
+
reconnectDelayMs?: number;
|
|
61
|
+
/** Max reconnect attempts (default: 5) */
|
|
62
|
+
maxReconnectAttempts?: number;
|
|
63
|
+
}
|
|
64
|
+
interface CreateGroupOptions {
|
|
65
|
+
name: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
picture?: string;
|
|
68
|
+
visibility?: GroupVisibility;
|
|
69
|
+
}
|
|
70
|
+
|
|
4
71
|
/**
|
|
5
72
|
* Cryptographic utilities for SDK2
|
|
6
73
|
*
|
|
@@ -272,147 +339,6 @@ interface TombstoneEntry {
|
|
|
272
339
|
timestamp: number;
|
|
273
340
|
}
|
|
274
341
|
|
|
275
|
-
/**
|
|
276
|
-
* INSTANT_SPLIT V5 Types
|
|
277
|
-
*
|
|
278
|
-
* Optimized token split transfer types that achieve ~2.3s critical path latency
|
|
279
|
-
* instead of the standard ~42s sequential flow.
|
|
280
|
-
*
|
|
281
|
-
* Key Insight: TransferCommitment.create() only needs token.state, NOT the mint proof.
|
|
282
|
-
* This allows creating transfer commitments immediately after mint data creation,
|
|
283
|
-
* without waiting for mint proofs.
|
|
284
|
-
*
|
|
285
|
-
* V5 Flow (Production Mode):
|
|
286
|
-
* 1. Create burn commitment, submit to aggregator
|
|
287
|
-
* 2. Wait for burn inclusion proof (~2s - unavoidable)
|
|
288
|
-
* 3. Create mint commitments with proper SplitMintReason (requires burn proof)
|
|
289
|
-
* 4. Create transfer commitment from mint data (no mint proof needed)
|
|
290
|
-
* 5. Package bundle -> send via Nostr -> SUCCESS (~2.3s total!)
|
|
291
|
-
* 6. Background: submit mints, wait for proofs, save change token, sync storage
|
|
292
|
-
*/
|
|
293
|
-
type SdkToken = any;
|
|
294
|
-
/**
|
|
295
|
-
* Bundle payload for INSTANT_SPLIT V5 (Production Mode)
|
|
296
|
-
*
|
|
297
|
-
* V5 achieves ~2.3s sender latency while working with production aggregators:
|
|
298
|
-
* - Burn proof is required for creating SplitMintReason
|
|
299
|
-
* - Transfer commitment is created from mint data WITHOUT waiting for mint proof
|
|
300
|
-
* - Mints are submitted in background after Nostr delivery
|
|
301
|
-
*
|
|
302
|
-
* Security: Burn is proven on-chain before mints can be created, preventing double-spend.
|
|
303
|
-
*/
|
|
304
|
-
interface InstantSplitBundleV5 {
|
|
305
|
-
/** Bundle version - V5 is production mode (proper SplitMintReason) */
|
|
306
|
-
version: '5.0';
|
|
307
|
-
/** Bundle type identifier */
|
|
308
|
-
type: 'INSTANT_SPLIT';
|
|
309
|
-
/**
|
|
310
|
-
* Burn TRANSACTION JSON (WITH inclusion proof!)
|
|
311
|
-
* V5 sends the proven burn transaction so recipient can verify burn completed.
|
|
312
|
-
*/
|
|
313
|
-
burnTransaction: string;
|
|
314
|
-
/**
|
|
315
|
-
* Recipient's MintTransactionData JSON (contains proper SplitMintReason in V5)
|
|
316
|
-
* The SplitMintReason references the burn transaction.
|
|
317
|
-
*/
|
|
318
|
-
recipientMintData: string;
|
|
319
|
-
/**
|
|
320
|
-
* Pre-created TransferCommitment JSON (recipient submits and waits for proof)
|
|
321
|
-
* Created from mint data WITHOUT any proofs.
|
|
322
|
-
*/
|
|
323
|
-
transferCommitment: string;
|
|
324
|
-
/** Payment amount (display metadata) */
|
|
325
|
-
amount: string;
|
|
326
|
-
/** Coin ID hex */
|
|
327
|
-
coinId: string;
|
|
328
|
-
/** Token type hex */
|
|
329
|
-
tokenTypeHex: string;
|
|
330
|
-
/** Split group ID for recovery correlation */
|
|
331
|
-
splitGroupId: string;
|
|
332
|
-
/** Sender's pubkey for acknowledgment */
|
|
333
|
-
senderPubkey: string;
|
|
334
|
-
/** Salt for recipient predicate creation (hex) */
|
|
335
|
-
recipientSaltHex: string;
|
|
336
|
-
/** Salt for transfer commitment creation (hex) */
|
|
337
|
-
transferSaltHex: string;
|
|
338
|
-
/**
|
|
339
|
-
* Serialized TokenState JSON for the intermediate minted token.
|
|
340
|
-
*
|
|
341
|
-
* In V5, the mint is to sender's address first, then transferred to recipient.
|
|
342
|
-
* The recipient needs this state to reconstruct the minted token before applying transfer.
|
|
343
|
-
* Without this, the recipient can't create a matching predicate (they don't have sender's signing key).
|
|
344
|
-
*/
|
|
345
|
-
mintedTokenStateJson: string;
|
|
346
|
-
/**
|
|
347
|
-
* Serialized TokenState JSON for the final recipient state (after transfer).
|
|
348
|
-
*
|
|
349
|
-
* The sender creates the transfer commitment targeting the recipient's PROXY address.
|
|
350
|
-
* The recipient can't recreate this state correctly because their signingService
|
|
351
|
-
* creates predicates for their DIRECT address, not the PROXY address.
|
|
352
|
-
* This is optional - recipient can create their own if they have the correct address.
|
|
353
|
-
*/
|
|
354
|
-
finalRecipientStateJson: string;
|
|
355
|
-
/**
|
|
356
|
-
* Serialized recipient address JSON (PROXY or DIRECT).
|
|
357
|
-
*
|
|
358
|
-
* Used by the recipient to identify which nametag token is being targeted.
|
|
359
|
-
* For PROXY address transfers, the recipient needs to find the matching
|
|
360
|
-
* nametag token and pass it to finalizeTransaction() for verification.
|
|
361
|
-
*/
|
|
362
|
-
recipientAddressJson: string;
|
|
363
|
-
/**
|
|
364
|
-
* Serialized nametag token JSON (for PROXY address transfers).
|
|
365
|
-
*
|
|
366
|
-
* For PROXY address transfers, the sender includes the nametag token
|
|
367
|
-
* so the recipient can verify they're authorized to receive at this address.
|
|
368
|
-
* This is REQUIRED for PROXY addresses - transfers without this will fail.
|
|
369
|
-
*/
|
|
370
|
-
nametagTokenJson?: string;
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Bundle payload for INSTANT_SPLIT V4 (Dev Mode Only - True Nostr-First Split)
|
|
374
|
-
*
|
|
375
|
-
* V4 achieves near-zero sender latency (~0.3s) by:
|
|
376
|
-
* 1. Creating ALL commitments locally BEFORE any aggregator submission
|
|
377
|
-
* 2. Persisting via Nostr FIRST
|
|
378
|
-
* 3. Then submitting ALL to aggregator in background
|
|
379
|
-
*
|
|
380
|
-
* NOTE: V4 only works in dev mode. Production requires V5 with proper SplitMintReason.
|
|
381
|
-
*/
|
|
382
|
-
interface InstantSplitBundleV4 {
|
|
383
|
-
/** Bundle version - V4 is true Nostr-first (dev mode only) */
|
|
384
|
-
version: '4.0';
|
|
385
|
-
/** Bundle type identifier */
|
|
386
|
-
type: 'INSTANT_SPLIT';
|
|
387
|
-
/**
|
|
388
|
-
* Burn commitment JSON (NOT transaction - no proof yet!)
|
|
389
|
-
* Both sender and recipient submit this to aggregator.
|
|
390
|
-
*/
|
|
391
|
-
burnCommitment: string;
|
|
392
|
-
/** Recipient's MintTransactionData JSON (they recreate commitment and submit) */
|
|
393
|
-
recipientMintData: string;
|
|
394
|
-
/**
|
|
395
|
-
* Pre-created TransferCommitment JSON (recipient submits and waits for proof)
|
|
396
|
-
* Created from mint data WITHOUT any proofs.
|
|
397
|
-
*/
|
|
398
|
-
transferCommitment: string;
|
|
399
|
-
/** Payment amount (display metadata) */
|
|
400
|
-
amount: string;
|
|
401
|
-
/** Coin ID hex */
|
|
402
|
-
coinId: string;
|
|
403
|
-
/** Token type hex */
|
|
404
|
-
tokenTypeHex: string;
|
|
405
|
-
/** Split group ID for recovery correlation */
|
|
406
|
-
splitGroupId: string;
|
|
407
|
-
/** Sender's pubkey for acknowledgment */
|
|
408
|
-
senderPubkey: string;
|
|
409
|
-
/** Salt for recipient predicate creation (hex) */
|
|
410
|
-
recipientSaltHex: string;
|
|
411
|
-
/** Salt for transfer commitment creation (hex) */
|
|
412
|
-
transferSaltHex: string;
|
|
413
|
-
}
|
|
414
|
-
/** Union type for all InstantSplit bundle versions */
|
|
415
|
-
type InstantSplitBundle = InstantSplitBundleV4 | InstantSplitBundleV5;
|
|
416
342
|
/**
|
|
417
343
|
* Result of an instant split send operation
|
|
418
344
|
*/
|
|
@@ -429,19 +355,8 @@ interface InstantSplitResult {
|
|
|
429
355
|
error?: string;
|
|
430
356
|
/** Whether background processing was started */
|
|
431
357
|
backgroundStarted?: boolean;
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
* Result from processing an INSTANT_SPLIT bundle (recipient side)
|
|
435
|
-
*/
|
|
436
|
-
interface InstantSplitProcessResult {
|
|
437
|
-
/** Whether processing succeeded */
|
|
438
|
-
success: boolean;
|
|
439
|
-
/** The finalized SDK token (if successful) */
|
|
440
|
-
token?: SdkToken;
|
|
441
|
-
/** Error message (if failed) */
|
|
442
|
-
error?: string;
|
|
443
|
-
/** Processing duration in ms */
|
|
444
|
-
durationMs: number;
|
|
358
|
+
/** Promise that resolves when background processing completes (change token saved) */
|
|
359
|
+
backgroundPromise?: Promise<void>;
|
|
445
360
|
}
|
|
446
361
|
/**
|
|
447
362
|
* Options for instant split send operation
|
|
@@ -476,6 +391,17 @@ interface BackgroundProgressStatus {
|
|
|
476
391
|
message: string;
|
|
477
392
|
error?: string;
|
|
478
393
|
}
|
|
394
|
+
/** Result of resolveUnconfirmed() */
|
|
395
|
+
interface UnconfirmedResolutionResult {
|
|
396
|
+
resolved: number;
|
|
397
|
+
stillPending: number;
|
|
398
|
+
failed: number;
|
|
399
|
+
details: Array<{
|
|
400
|
+
tokenId: string;
|
|
401
|
+
stage: string;
|
|
402
|
+
status: 'resolved' | 'pending' | 'failed';
|
|
403
|
+
}>;
|
|
404
|
+
}
|
|
479
405
|
|
|
480
406
|
/**
|
|
481
407
|
* SDK2 Core Types
|
|
@@ -529,6 +455,14 @@ interface Asset {
|
|
|
529
455
|
readonly iconUrl?: string;
|
|
530
456
|
readonly totalAmount: string;
|
|
531
457
|
readonly tokenCount: number;
|
|
458
|
+
/** Sum of confirmed token amounts (smallest units) */
|
|
459
|
+
readonly confirmedAmount: string;
|
|
460
|
+
/** Sum of unconfirmed (submitted/pending) token amounts (smallest units) */
|
|
461
|
+
readonly unconfirmedAmount: string;
|
|
462
|
+
/** Number of confirmed tokens aggregated */
|
|
463
|
+
readonly confirmedTokenCount: number;
|
|
464
|
+
/** Number of unconfirmed tokens aggregated */
|
|
465
|
+
readonly unconfirmedTokenCount: number;
|
|
532
466
|
/** Price per whole unit in USD (null if PriceProvider not configured) */
|
|
533
467
|
readonly priceUsd: number | null;
|
|
534
468
|
/** Price per whole unit in EUR (null if PriceProvider not configured) */
|
|
@@ -542,6 +476,7 @@ interface Asset {
|
|
|
542
476
|
}
|
|
543
477
|
type TransferStatus = 'pending' | 'submitted' | 'confirmed' | 'delivered' | 'completed' | 'failed';
|
|
544
478
|
type AddressMode = 'auto' | 'direct' | 'proxy';
|
|
479
|
+
type TransferMode = 'instant' | 'conservative';
|
|
545
480
|
interface TransferRequest {
|
|
546
481
|
readonly coinId: string;
|
|
547
482
|
readonly amount: string;
|
|
@@ -549,12 +484,31 @@ interface TransferRequest {
|
|
|
549
484
|
readonly memo?: string;
|
|
550
485
|
/** Address mode: 'auto' (default) uses directAddress if available, 'direct' forces DIRECT, 'proxy' forces PROXY */
|
|
551
486
|
readonly addressMode?: AddressMode;
|
|
487
|
+
/** Transfer mode: 'instant' (default) sends via Nostr immediately, 'conservative' collects all proofs first */
|
|
488
|
+
readonly transferMode?: TransferMode;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Per-token transfer detail tracking the on-chain commitment or split operation
|
|
492
|
+
* for each source token involved in a transfer.
|
|
493
|
+
*/
|
|
494
|
+
interface TokenTransferDetail {
|
|
495
|
+
/** Source token ID that was consumed in this transfer */
|
|
496
|
+
readonly sourceTokenId: string;
|
|
497
|
+
/** Transfer method used for this token */
|
|
498
|
+
readonly method: 'direct' | 'split';
|
|
499
|
+
/** Aggregator commitment request ID hex (for direct transfers) */
|
|
500
|
+
readonly requestIdHex?: string;
|
|
501
|
+
/** Split group ID (for split transfers — correlates sender/recipient/change tokens) */
|
|
502
|
+
readonly splitGroupId?: string;
|
|
503
|
+
/** Nostr event ID (for split transfers delivered via Nostr) */
|
|
504
|
+
readonly nostrEventId?: string;
|
|
552
505
|
}
|
|
553
506
|
interface TransferResult {
|
|
554
507
|
readonly id: string;
|
|
555
508
|
status: TransferStatus;
|
|
556
509
|
readonly tokens: Token[];
|
|
557
|
-
|
|
510
|
+
/** Per-token transfer details — one entry per source token consumed */
|
|
511
|
+
readonly tokenTransfers: TokenTransferDetail[];
|
|
558
512
|
error?: string;
|
|
559
513
|
}
|
|
560
514
|
interface IncomingTransfer {
|
|
@@ -731,7 +685,7 @@ interface TrackedAddress extends TrackedAddressEntry {
|
|
|
731
685
|
/** Primary nametag (from nametag cache, without @ prefix) */
|
|
732
686
|
readonly nametag?: string;
|
|
733
687
|
}
|
|
734
|
-
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden';
|
|
688
|
+
type SphereEventType = 'transfer:incoming' | 'transfer:confirmed' | 'transfer:failed' | 'payment_request:incoming' | 'payment_request:accepted' | 'payment_request:rejected' | 'payment_request:paid' | 'payment_request:response' | 'message:dm' | 'message:broadcast' | 'sync:started' | 'sync:completed' | 'sync:provider' | 'sync:error' | 'connection:changed' | 'nametag:registered' | 'nametag:recovered' | 'identity:changed' | 'address:activated' | 'address:hidden' | 'address:unhidden' | 'sync:remote-update' | 'groupchat:message' | 'groupchat:joined' | 'groupchat:left' | 'groupchat:kicked' | 'groupchat:group_deleted' | 'groupchat:updated' | 'groupchat:connection';
|
|
735
689
|
interface SphereEventMap {
|
|
736
690
|
'transfer:incoming': IncomingTransfer;
|
|
737
691
|
'transfer:confirmed': TransferResult;
|
|
@@ -790,6 +744,34 @@ interface SphereEventMap {
|
|
|
790
744
|
index: number;
|
|
791
745
|
addressId: string;
|
|
792
746
|
};
|
|
747
|
+
'sync:remote-update': {
|
|
748
|
+
providerId: string;
|
|
749
|
+
name: string;
|
|
750
|
+
sequence: number;
|
|
751
|
+
cid: string;
|
|
752
|
+
added: number;
|
|
753
|
+
removed: number;
|
|
754
|
+
};
|
|
755
|
+
'groupchat:message': GroupMessageData;
|
|
756
|
+
'groupchat:joined': {
|
|
757
|
+
groupId: string;
|
|
758
|
+
groupName: string;
|
|
759
|
+
};
|
|
760
|
+
'groupchat:left': {
|
|
761
|
+
groupId: string;
|
|
762
|
+
};
|
|
763
|
+
'groupchat:kicked': {
|
|
764
|
+
groupId: string;
|
|
765
|
+
groupName: string;
|
|
766
|
+
};
|
|
767
|
+
'groupchat:group_deleted': {
|
|
768
|
+
groupId: string;
|
|
769
|
+
groupName: string;
|
|
770
|
+
};
|
|
771
|
+
'groupchat:updated': Record<string, never>;
|
|
772
|
+
'groupchat:connection': {
|
|
773
|
+
connected: boolean;
|
|
774
|
+
};
|
|
793
775
|
}
|
|
794
776
|
type SphereEventHandler<T extends SphereEventType> = (data: SphereEventMap[T]) => void;
|
|
795
777
|
/**
|
|
@@ -1012,6 +994,12 @@ interface TransportProvider extends BaseProvider {
|
|
|
1012
994
|
* @returns Unsubscribe function
|
|
1013
995
|
*/
|
|
1014
996
|
onInstantSplitReceived?(handler: InstantSplitBundleHandler): () => void;
|
|
997
|
+
/**
|
|
998
|
+
* Fetch pending events from transport (one-shot query).
|
|
999
|
+
* Creates a temporary subscription, processes events through normal handlers,
|
|
1000
|
+
* and resolves after EOSE (End Of Stored Events).
|
|
1001
|
+
*/
|
|
1002
|
+
fetchPendingEvents?(): Promise<void>;
|
|
1015
1003
|
}
|
|
1016
1004
|
/**
|
|
1017
1005
|
* Payload for sending instant split bundles
|
|
@@ -1076,7 +1064,7 @@ interface IncomingTokenTransfer {
|
|
|
1076
1064
|
payload: TokenTransferPayload;
|
|
1077
1065
|
timestamp: number;
|
|
1078
1066
|
}
|
|
1079
|
-
type TokenTransferHandler = (transfer: IncomingTokenTransfer) => void
|
|
1067
|
+
type TokenTransferHandler = (transfer: IncomingTokenTransfer) => void | Promise<void>;
|
|
1080
1068
|
interface PaymentRequestPayload {
|
|
1081
1069
|
/** Amount requested (in smallest units) */
|
|
1082
1070
|
amount: string | bigint;
|
|
@@ -1425,24 +1413,8 @@ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
|
|
|
1425
1413
|
* Subscribe to storage events
|
|
1426
1414
|
*/
|
|
1427
1415
|
onEvent?(callback: StorageEventCallback): () => void;
|
|
1428
|
-
/**
|
|
1429
|
-
* Save individual token (for file-based storage like lottery pattern)
|
|
1430
|
-
*/
|
|
1431
|
-
saveToken?(tokenId: string, tokenData: unknown): Promise<void>;
|
|
1432
|
-
/**
|
|
1433
|
-
* Get individual token
|
|
1434
|
-
*/
|
|
1435
|
-
getToken?(tokenId: string): Promise<unknown | null>;
|
|
1436
|
-
/**
|
|
1437
|
-
* List all token IDs
|
|
1438
|
-
*/
|
|
1439
|
-
listTokenIds?(): Promise<string[]>;
|
|
1440
|
-
/**
|
|
1441
|
-
* Delete individual token
|
|
1442
|
-
*/
|
|
1443
|
-
deleteToken?(tokenId: string): Promise<void>;
|
|
1444
1416
|
}
|
|
1445
|
-
type StorageEventType = 'storage:saving' | 'storage:saved' | 'storage:loading' | 'storage:loaded' | 'storage:error' | 'sync:started' | 'sync:completed' | 'sync:conflict' | 'sync:error';
|
|
1417
|
+
type StorageEventType = 'storage:saving' | 'storage:saved' | 'storage:loading' | 'storage:loaded' | 'storage:error' | 'storage:remote-updated' | 'sync:started' | 'sync:completed' | 'sync:conflict' | 'sync:error';
|
|
1446
1418
|
interface StorageEvent {
|
|
1447
1419
|
type: StorageEventType;
|
|
1448
1420
|
timestamp: number;
|
|
@@ -1698,7 +1670,30 @@ interface TransactionHistoryEntry {
|
|
|
1698
1670
|
timestamp: number;
|
|
1699
1671
|
recipientNametag?: string;
|
|
1700
1672
|
senderPubkey?: string;
|
|
1701
|
-
|
|
1673
|
+
/** TransferResult.id that created this entry (links history to transfer operation) */
|
|
1674
|
+
transferId?: string;
|
|
1675
|
+
}
|
|
1676
|
+
interface ReceiveOptions {
|
|
1677
|
+
/** Wait for all unconfirmed tokens to be finalized (default: false).
|
|
1678
|
+
* When false, calls resolveUnconfirmed() once to submit pending commitments.
|
|
1679
|
+
* When true, polls resolveUnconfirmed() + load() until all confirmed or timeout. */
|
|
1680
|
+
finalize?: boolean;
|
|
1681
|
+
/** Finalization timeout in ms (default: 60000). Only used when finalize=true. */
|
|
1682
|
+
timeout?: number;
|
|
1683
|
+
/** Poll interval in ms (default: 2000). Only used when finalize=true. */
|
|
1684
|
+
pollInterval?: number;
|
|
1685
|
+
/** Progress callback after each resolveUnconfirmed() poll. Only used when finalize=true. */
|
|
1686
|
+
onProgress?: (result: UnconfirmedResolutionResult) => void;
|
|
1687
|
+
}
|
|
1688
|
+
interface ReceiveResult {
|
|
1689
|
+
/** Newly received incoming transfers. */
|
|
1690
|
+
transfers: IncomingTransfer[];
|
|
1691
|
+
/** Finalization result (from resolveUnconfirmed). */
|
|
1692
|
+
finalization?: UnconfirmedResolutionResult;
|
|
1693
|
+
/** Whether finalization timed out (only when finalize=true). */
|
|
1694
|
+
timedOut?: boolean;
|
|
1695
|
+
/** Duration of finalization in ms (only when finalize=true). */
|
|
1696
|
+
finalizationDurationMs?: number;
|
|
1702
1697
|
}
|
|
1703
1698
|
interface PaymentsModuleConfig {
|
|
1704
1699
|
/** Auto-sync after operations */
|
|
@@ -1738,11 +1733,12 @@ declare class PaymentsModule {
|
|
|
1738
1733
|
readonly l1: L1PaymentsModule | null;
|
|
1739
1734
|
private tokens;
|
|
1740
1735
|
private pendingTransfers;
|
|
1736
|
+
private pendingBackgroundTasks;
|
|
1741
1737
|
private tombstones;
|
|
1742
1738
|
private archivedTokens;
|
|
1743
1739
|
private forkedTokens;
|
|
1744
1740
|
private transactionHistory;
|
|
1745
|
-
private
|
|
1741
|
+
private nametags;
|
|
1746
1742
|
private paymentRequests;
|
|
1747
1743
|
private paymentRequestHandlers;
|
|
1748
1744
|
private outgoingPaymentRequests;
|
|
@@ -1755,8 +1751,17 @@ declare class PaymentsModule {
|
|
|
1755
1751
|
private proofPollingInterval;
|
|
1756
1752
|
private static readonly PROOF_POLLING_INTERVAL_MS;
|
|
1757
1753
|
private static readonly PROOF_POLLING_MAX_ATTEMPTS;
|
|
1754
|
+
private storageEventUnsubscribers;
|
|
1755
|
+
private syncDebounceTimer;
|
|
1756
|
+
private static readonly SYNC_DEBOUNCE_MS;
|
|
1757
|
+
/** Sync coalescing: concurrent sync() calls share the same operation */
|
|
1758
|
+
private _syncInProgress;
|
|
1758
1759
|
constructor(config?: PaymentsModuleConfig);
|
|
1759
|
-
/**
|
|
1760
|
+
/**
|
|
1761
|
+
* Get the current module configuration (excluding L1 config).
|
|
1762
|
+
*
|
|
1763
|
+
* @returns Resolved configuration with all defaults applied.
|
|
1764
|
+
*/
|
|
1760
1765
|
getConfig(): Omit<Required<PaymentsModuleConfig>, 'l1'>;
|
|
1761
1766
|
/** Price provider (optional) */
|
|
1762
1767
|
private priceProvider;
|
|
@@ -1766,11 +1771,18 @@ declare class PaymentsModule {
|
|
|
1766
1771
|
*/
|
|
1767
1772
|
initialize(deps: PaymentsModuleDependencies): void;
|
|
1768
1773
|
/**
|
|
1769
|
-
* Load
|
|
1774
|
+
* Load all token data from storage providers and restore wallet state.
|
|
1775
|
+
*
|
|
1776
|
+
* Loads tokens, nametag data, transaction history, and pending transfers
|
|
1777
|
+
* from configured storage providers. Restores pending V5 tokens and
|
|
1778
|
+
* triggers a fire-and-forget {@link resolveUnconfirmed} call.
|
|
1770
1779
|
*/
|
|
1771
1780
|
load(): Promise<void>;
|
|
1772
1781
|
/**
|
|
1773
|
-
* Cleanup
|
|
1782
|
+
* Cleanup all subscriptions, polling jobs, and pending resolvers.
|
|
1783
|
+
*
|
|
1784
|
+
* Should be called when the wallet is being shut down or the module is
|
|
1785
|
+
* no longer needed. Also destroys the L1 sub-module if present.
|
|
1774
1786
|
*/
|
|
1775
1787
|
destroy(): void;
|
|
1776
1788
|
/**
|
|
@@ -1822,11 +1834,19 @@ declare class PaymentsModule {
|
|
|
1822
1834
|
* @param senderPubkey - Sender's public key for verification
|
|
1823
1835
|
* @returns Processing result with finalized token
|
|
1824
1836
|
*/
|
|
1825
|
-
processInstantSplitBundle
|
|
1837
|
+
private processInstantSplitBundle;
|
|
1826
1838
|
/**
|
|
1827
|
-
*
|
|
1839
|
+
* Synchronous V4 bundle processing (dev mode only).
|
|
1840
|
+
* Kept for backward compatibility with V4 bundles.
|
|
1828
1841
|
*/
|
|
1829
|
-
|
|
1842
|
+
private processInstantSplitBundleSync;
|
|
1843
|
+
/**
|
|
1844
|
+
* Type-guard: check whether a payload is a valid {@link InstantSplitBundle} (V4 or V5).
|
|
1845
|
+
*
|
|
1846
|
+
* @param payload - The object to test.
|
|
1847
|
+
* @returns `true` if the payload matches the InstantSplitBundle shape.
|
|
1848
|
+
*/
|
|
1849
|
+
private isInstantSplitBundle;
|
|
1830
1850
|
/**
|
|
1831
1851
|
* Send a payment request to someone
|
|
1832
1852
|
* @param recipientPubkeyOrNametag - Recipient's pubkey or @nametag
|
|
@@ -1848,27 +1868,45 @@ declare class PaymentsModule {
|
|
|
1848
1868
|
status?: PaymentRequestStatus;
|
|
1849
1869
|
}): IncomingPaymentRequest$1[];
|
|
1850
1870
|
/**
|
|
1851
|
-
* Get
|
|
1871
|
+
* Get the count of payment requests with status `'pending'`.
|
|
1872
|
+
*
|
|
1873
|
+
* @returns Number of pending incoming payment requests.
|
|
1852
1874
|
*/
|
|
1853
1875
|
getPendingPaymentRequestsCount(): number;
|
|
1854
1876
|
/**
|
|
1855
|
-
* Accept a payment request
|
|
1877
|
+
* Accept a payment request and notify the requester.
|
|
1878
|
+
*
|
|
1879
|
+
* Marks the request as `'accepted'` and sends a response via transport.
|
|
1880
|
+
* The caller should subsequently call {@link send} to fulfill the payment.
|
|
1881
|
+
*
|
|
1882
|
+
* @param requestId - ID of the incoming payment request to accept.
|
|
1856
1883
|
*/
|
|
1857
1884
|
acceptPaymentRequest(requestId: string): Promise<void>;
|
|
1858
1885
|
/**
|
|
1859
|
-
* Reject a payment request
|
|
1886
|
+
* Reject a payment request and notify the requester.
|
|
1887
|
+
*
|
|
1888
|
+
* @param requestId - ID of the incoming payment request to reject.
|
|
1860
1889
|
*/
|
|
1861
1890
|
rejectPaymentRequest(requestId: string): Promise<void>;
|
|
1862
1891
|
/**
|
|
1863
|
-
* Mark a payment request as paid (
|
|
1892
|
+
* Mark a payment request as paid (local status update only).
|
|
1893
|
+
*
|
|
1894
|
+
* Typically called after a successful {@link send} to record that the
|
|
1895
|
+
* request has been fulfilled.
|
|
1896
|
+
*
|
|
1897
|
+
* @param requestId - ID of the incoming payment request to mark as paid.
|
|
1864
1898
|
*/
|
|
1865
1899
|
markPaymentRequestPaid(requestId: string): void;
|
|
1866
1900
|
/**
|
|
1867
|
-
*
|
|
1901
|
+
* Remove all non-pending incoming payment requests from memory.
|
|
1902
|
+
*
|
|
1903
|
+
* Keeps only requests with status `'pending'`.
|
|
1868
1904
|
*/
|
|
1869
1905
|
clearProcessedPaymentRequests(): void;
|
|
1870
1906
|
/**
|
|
1871
|
-
* Remove a specific payment request
|
|
1907
|
+
* Remove a specific incoming payment request by ID.
|
|
1908
|
+
*
|
|
1909
|
+
* @param requestId - ID of the payment request to remove.
|
|
1872
1910
|
*/
|
|
1873
1911
|
removePaymentRequest(requestId: string): void;
|
|
1874
1912
|
/**
|
|
@@ -1899,15 +1937,21 @@ declare class PaymentsModule {
|
|
|
1899
1937
|
*/
|
|
1900
1938
|
waitForPaymentResponse(requestId: string, timeoutMs?: number): Promise<PaymentRequestResponse>;
|
|
1901
1939
|
/**
|
|
1902
|
-
* Cancel
|
|
1940
|
+
* Cancel an active {@link waitForPaymentResponse} call.
|
|
1941
|
+
*
|
|
1942
|
+
* The pending promise is rejected with a `'Cancelled'` error.
|
|
1943
|
+
*
|
|
1944
|
+
* @param requestId - The outgoing request ID whose wait should be cancelled.
|
|
1903
1945
|
*/
|
|
1904
1946
|
cancelWaitForPaymentResponse(requestId: string): void;
|
|
1905
1947
|
/**
|
|
1906
|
-
* Remove an outgoing payment request
|
|
1948
|
+
* Remove an outgoing payment request and cancel any pending wait.
|
|
1949
|
+
*
|
|
1950
|
+
* @param requestId - ID of the outgoing request to remove.
|
|
1907
1951
|
*/
|
|
1908
1952
|
removeOutgoingPaymentRequest(requestId: string): void;
|
|
1909
1953
|
/**
|
|
1910
|
-
*
|
|
1954
|
+
* Remove all outgoing payment requests that are `'paid'`, `'rejected'`, or `'expired'`.
|
|
1911
1955
|
*/
|
|
1912
1956
|
clearCompletedOutgoingPaymentRequests(): void;
|
|
1913
1957
|
private handlePaymentRequestResponse;
|
|
@@ -1915,147 +1959,312 @@ declare class PaymentsModule {
|
|
|
1915
1959
|
* Send a response to a payment request (used internally by accept/reject/pay methods)
|
|
1916
1960
|
*/
|
|
1917
1961
|
private sendPaymentRequestResponse;
|
|
1962
|
+
/**
|
|
1963
|
+
* Fetch and process pending incoming transfers from the transport layer.
|
|
1964
|
+
*
|
|
1965
|
+
* Performs a one-shot query to fetch all pending events, processes them
|
|
1966
|
+
* through the existing pipeline, and resolves after all stored events
|
|
1967
|
+
* are handled. Useful for batch/CLI apps that need explicit receive.
|
|
1968
|
+
*
|
|
1969
|
+
* When `finalize` is true, polls resolveUnconfirmed() + load() until all
|
|
1970
|
+
* tokens are confirmed or the timeout expires. Otherwise calls
|
|
1971
|
+
* resolveUnconfirmed() once to submit pending commitments.
|
|
1972
|
+
*
|
|
1973
|
+
* @param options - Optional receive options including finalization control
|
|
1974
|
+
* @param callback - Optional callback invoked for each newly received transfer
|
|
1975
|
+
* @returns ReceiveResult with transfers and finalization metadata
|
|
1976
|
+
*/
|
|
1977
|
+
receive(options?: ReceiveOptions, callback?: (transfer: IncomingTransfer) => void): Promise<ReceiveResult>;
|
|
1918
1978
|
/**
|
|
1919
1979
|
* Set or update price provider
|
|
1920
1980
|
*/
|
|
1921
1981
|
setPriceProvider(provider: PriceProvider): void;
|
|
1922
1982
|
/**
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1983
|
+
* Wait for all pending background operations (e.g., instant split change token creation).
|
|
1984
|
+
* Call this before process exit to ensure all tokens are saved.
|
|
1925
1985
|
*/
|
|
1926
|
-
|
|
1986
|
+
waitForPendingOperations(): Promise<void>;
|
|
1927
1987
|
/**
|
|
1928
|
-
* Get
|
|
1929
|
-
*
|
|
1988
|
+
* Get total portfolio value in USD.
|
|
1989
|
+
* Returns null if PriceProvider is not configured.
|
|
1990
|
+
*/
|
|
1991
|
+
getFiatBalance(): Promise<number | null>;
|
|
1992
|
+
/**
|
|
1993
|
+
* Get token balances grouped by coin type.
|
|
1994
|
+
*
|
|
1995
|
+
* Returns an array of {@link Asset} objects, one per coin type held.
|
|
1996
|
+
* Each entry includes confirmed and unconfirmed breakdowns. Tokens with
|
|
1997
|
+
* status `'spent'`, `'invalid'`, or `'transferring'` are excluded.
|
|
1998
|
+
*
|
|
1999
|
+
* This is synchronous — no price data is included. Use {@link getAssets}
|
|
2000
|
+
* for the async version with fiat pricing.
|
|
2001
|
+
*
|
|
2002
|
+
* @param coinId - Optional coin ID to filter by (e.g. hex string). When omitted, all coin types are returned.
|
|
2003
|
+
* @returns Array of balance summaries (synchronous — no await needed).
|
|
2004
|
+
*/
|
|
2005
|
+
getBalance(coinId?: string): Asset[];
|
|
2006
|
+
/**
|
|
2007
|
+
* Get aggregated assets (tokens grouped by coinId) with price data.
|
|
2008
|
+
* Includes both confirmed and unconfirmed tokens with breakdown.
|
|
1930
2009
|
*/
|
|
1931
2010
|
getAssets(coinId?: string): Promise<Asset[]>;
|
|
1932
2011
|
/**
|
|
1933
|
-
*
|
|
2012
|
+
* Aggregate tokens by coinId with confirmed/unconfirmed breakdown.
|
|
2013
|
+
* Excludes tokens with status 'spent', 'invalid', or 'transferring'.
|
|
2014
|
+
*/
|
|
2015
|
+
private aggregateTokens;
|
|
2016
|
+
/**
|
|
2017
|
+
* Get all tokens, optionally filtered by coin type and/or status.
|
|
2018
|
+
*
|
|
2019
|
+
* @param filter - Optional filter criteria.
|
|
2020
|
+
* @param filter.coinId - Return only tokens of this coin type.
|
|
2021
|
+
* @param filter.status - Return only tokens with this status (e.g. `'submitted'` for unconfirmed).
|
|
2022
|
+
* @returns Array of matching {@link Token} objects (synchronous).
|
|
1934
2023
|
*/
|
|
1935
2024
|
getTokens(filter?: {
|
|
1936
2025
|
coinId?: string;
|
|
1937
2026
|
status?: TokenStatus;
|
|
1938
2027
|
}): Token[];
|
|
1939
2028
|
/**
|
|
1940
|
-
* Get single token
|
|
2029
|
+
* Get a single token by its local ID.
|
|
2030
|
+
*
|
|
2031
|
+
* @param id - The local UUID assigned when the token was added.
|
|
2032
|
+
* @returns The token, or `undefined` if not found.
|
|
1941
2033
|
*/
|
|
1942
2034
|
getToken(id: string): Token | undefined;
|
|
1943
2035
|
/**
|
|
1944
|
-
*
|
|
1945
|
-
*
|
|
1946
|
-
*
|
|
1947
|
-
*
|
|
2036
|
+
* Attempt to resolve unconfirmed (status `'submitted'`) tokens by acquiring
|
|
2037
|
+
* their missing aggregator proofs.
|
|
2038
|
+
*
|
|
2039
|
+
* Each unconfirmed V5 token progresses through stages:
|
|
2040
|
+
* `RECEIVED` → `MINT_SUBMITTED` → `MINT_PROVEN` → `TRANSFER_SUBMITTED` → `FINALIZED`
|
|
2041
|
+
*
|
|
2042
|
+
* Uses 500 ms quick-timeouts per proof check so the call returns quickly even
|
|
2043
|
+
* when proofs are not yet available. Tokens that exceed 50 failed attempts are
|
|
2044
|
+
* marked `'invalid'`.
|
|
2045
|
+
*
|
|
2046
|
+
* Automatically called (fire-and-forget) by {@link load}.
|
|
2047
|
+
*
|
|
2048
|
+
* @returns Summary with counts of resolved, still-pending, and failed tokens plus per-token details.
|
|
2049
|
+
*/
|
|
2050
|
+
resolveUnconfirmed(): Promise<UnconfirmedResolutionResult>;
|
|
2051
|
+
/**
|
|
2052
|
+
* Process a single V5 token through its finalization stages with quick-timeout proof checks.
|
|
1948
2053
|
*/
|
|
1949
|
-
|
|
2054
|
+
private resolveV5Token;
|
|
1950
2055
|
/**
|
|
1951
|
-
*
|
|
1952
|
-
* Similar to lottery's saveReceivedToken() pattern
|
|
2056
|
+
* Non-blocking proof check with 500ms timeout.
|
|
1953
2057
|
*/
|
|
1954
|
-
private
|
|
2058
|
+
private quickProofCheck;
|
|
1955
2059
|
/**
|
|
1956
|
-
*
|
|
1957
|
-
*
|
|
1958
|
-
* by other applications using the same storage directory.
|
|
2060
|
+
* Perform V5 bundle finalization from stored bundle data and proofs.
|
|
2061
|
+
* Extracted from InstantSplitProcessor.processV5Bundle() steps 4-10.
|
|
1959
2062
|
*/
|
|
1960
|
-
private
|
|
2063
|
+
private finalizeFromV5Bundle;
|
|
1961
2064
|
/**
|
|
1962
|
-
*
|
|
2065
|
+
* Parse pending finalization metadata from token's sdkData.
|
|
1963
2066
|
*/
|
|
1964
|
-
|
|
2067
|
+
private parsePendingFinalization;
|
|
1965
2068
|
/**
|
|
1966
|
-
*
|
|
2069
|
+
* Update pending finalization metadata in token's sdkData.
|
|
2070
|
+
* Creates a new token object since sdkData is readonly.
|
|
1967
2071
|
*/
|
|
1968
|
-
|
|
2072
|
+
private updatePendingFinalization;
|
|
2073
|
+
/**
|
|
2074
|
+
* Save pending V5 tokens to key-value storage.
|
|
2075
|
+
* These tokens can't be serialized to TXF format (no genesis/state),
|
|
2076
|
+
* so we persist them separately and restore on load().
|
|
2077
|
+
*/
|
|
2078
|
+
private savePendingV5Tokens;
|
|
1969
2079
|
/**
|
|
1970
|
-
*
|
|
1971
|
-
*
|
|
2080
|
+
* Load pending V5 tokens from key-value storage and merge into tokens map.
|
|
2081
|
+
* Called during load() to restore tokens that TXF format can't represent.
|
|
1972
2082
|
*/
|
|
1973
|
-
private
|
|
2083
|
+
private loadPendingV5Tokens;
|
|
1974
2084
|
/**
|
|
1975
|
-
*
|
|
2085
|
+
* Add a token to the wallet.
|
|
2086
|
+
*
|
|
2087
|
+
* Tokens are uniquely identified by a `(tokenId, stateHash)` composite key.
|
|
2088
|
+
* Duplicate detection:
|
|
2089
|
+
* - **Tombstoned** — rejected if the exact `(tokenId, stateHash)` pair has a tombstone.
|
|
2090
|
+
* - **Exact duplicate** — rejected if a token with the same composite key already exists.
|
|
2091
|
+
* - **State replacement** — if the same `tokenId` exists with a *different* `stateHash`,
|
|
2092
|
+
* the old state is archived and replaced with the incoming one.
|
|
2093
|
+
*
|
|
2094
|
+
* @param token - The token to add.
|
|
2095
|
+
* @param skipHistory - When `true`, do not create a `RECEIVED` transaction history entry (default `false`).
|
|
2096
|
+
* @returns `true` if the token was added, `false` if rejected as duplicate or tombstoned.
|
|
2097
|
+
*/
|
|
2098
|
+
addToken(token: Token, skipHistory?: boolean): Promise<boolean>;
|
|
2099
|
+
/**
|
|
2100
|
+
* Update an existing token or add it if not found.
|
|
2101
|
+
*
|
|
2102
|
+
* Looks up the token by genesis `tokenId` (from `sdkData`) first, then by
|
|
2103
|
+
* `token.id`. If no match is found, falls back to {@link addToken}.
|
|
2104
|
+
*
|
|
2105
|
+
* @param token - The token with updated data. Must include a valid `id`.
|
|
2106
|
+
*/
|
|
2107
|
+
updateToken(token: Token): Promise<void>;
|
|
2108
|
+
/**
|
|
2109
|
+
* Remove a token from the wallet.
|
|
2110
|
+
*
|
|
2111
|
+
* The token is archived first, then a tombstone `(tokenId, stateHash)` is
|
|
2112
|
+
* created to prevent re-addition via Nostr re-delivery. A `SENT` history
|
|
2113
|
+
* entry is created unless `skipHistory` is `true`.
|
|
2114
|
+
*
|
|
2115
|
+
* @param tokenId - Local UUID of the token to remove.
|
|
2116
|
+
* @param recipientNametag - Optional nametag of the transfer recipient (for history).
|
|
2117
|
+
* @param skipHistory - When `true`, skip creating a transaction history entry (default `false`).
|
|
2118
|
+
*/
|
|
2119
|
+
removeToken(tokenId: string, recipientNametag?: string, skipHistory?: boolean): Promise<void>;
|
|
2120
|
+
/**
|
|
2121
|
+
* Get all tombstone entries.
|
|
2122
|
+
*
|
|
2123
|
+
* Each tombstone is keyed by `(tokenId, stateHash)` and prevents a spent
|
|
2124
|
+
* token state from being re-added (e.g. via Nostr re-delivery).
|
|
2125
|
+
*
|
|
2126
|
+
* @returns A shallow copy of the tombstone array.
|
|
1976
2127
|
*/
|
|
1977
2128
|
getTombstones(): TombstoneEntry[];
|
|
1978
2129
|
/**
|
|
1979
|
-
* Check
|
|
2130
|
+
* Check whether a specific `(tokenId, stateHash)` combination is tombstoned.
|
|
2131
|
+
*
|
|
2132
|
+
* @param tokenId - The genesis token ID.
|
|
2133
|
+
* @param stateHash - The state hash of the token version to check.
|
|
2134
|
+
* @returns `true` if the exact combination has been tombstoned.
|
|
1980
2135
|
*/
|
|
1981
2136
|
isStateTombstoned(tokenId: string, stateHash: string): boolean;
|
|
1982
2137
|
/**
|
|
1983
|
-
* Merge remote
|
|
1984
|
-
*
|
|
2138
|
+
* Merge tombstones received from a remote sync source.
|
|
2139
|
+
*
|
|
2140
|
+
* Any local token whose `(tokenId, stateHash)` matches a remote tombstone is
|
|
2141
|
+
* removed. The remote tombstones are then added to the local set (union merge).
|
|
2142
|
+
*
|
|
2143
|
+
* @param remoteTombstones - Tombstone entries from the remote source.
|
|
2144
|
+
* @returns Number of local tokens that were removed.
|
|
1985
2145
|
*/
|
|
1986
2146
|
mergeTombstones(remoteTombstones: TombstoneEntry[]): Promise<number>;
|
|
1987
2147
|
/**
|
|
1988
|
-
*
|
|
2148
|
+
* Remove tombstones older than `maxAge` and cap the list at 100 entries.
|
|
2149
|
+
*
|
|
2150
|
+
* @param maxAge - Maximum age in milliseconds (default: 30 days).
|
|
1989
2151
|
*/
|
|
1990
2152
|
pruneTombstones(maxAge?: number): Promise<void>;
|
|
1991
2153
|
/**
|
|
1992
|
-
* Get archived tokens
|
|
2154
|
+
* Get all archived (spent/superseded) tokens in TXF format.
|
|
2155
|
+
*
|
|
2156
|
+
* Archived tokens are kept for recovery and sync purposes. The map key is
|
|
2157
|
+
* the genesis token ID.
|
|
2158
|
+
*
|
|
2159
|
+
* @returns A shallow copy of the archived token map.
|
|
1993
2160
|
*/
|
|
1994
2161
|
getArchivedTokens(): Map<string, TxfToken>;
|
|
1995
2162
|
/**
|
|
1996
|
-
* Get best archived version of a token
|
|
2163
|
+
* Get the best (most committed transactions) archived version of a token.
|
|
2164
|
+
*
|
|
2165
|
+
* Searches both archived and forked token maps and returns the version with
|
|
2166
|
+
* the highest number of committed transactions.
|
|
2167
|
+
*
|
|
2168
|
+
* @param tokenId - The genesis token ID to look up.
|
|
2169
|
+
* @returns The best TXF token version, or `null` if not found.
|
|
1997
2170
|
*/
|
|
1998
2171
|
getBestArchivedVersion(tokenId: string): TxfToken | null;
|
|
1999
2172
|
/**
|
|
2000
|
-
* Merge remote
|
|
2001
|
-
*
|
|
2173
|
+
* Merge archived tokens from a remote sync source.
|
|
2174
|
+
*
|
|
2175
|
+
* For each remote token:
|
|
2176
|
+
* - If missing locally, it is added.
|
|
2177
|
+
* - If the remote version is an incremental update of the local, it replaces it.
|
|
2178
|
+
* - If the histories diverge (fork), the remote version is stored via {@link storeForkedToken}.
|
|
2179
|
+
*
|
|
2180
|
+
* @param remoteArchived - Map of genesis token ID → TXF token from remote.
|
|
2181
|
+
* @returns Number of tokens that were updated or added locally.
|
|
2002
2182
|
*/
|
|
2003
2183
|
mergeArchivedTokens(remoteArchived: Map<string, TxfToken>): Promise<number>;
|
|
2004
2184
|
/**
|
|
2005
|
-
* Prune archived tokens
|
|
2185
|
+
* Prune archived tokens to keep at most `maxCount` entries.
|
|
2186
|
+
*
|
|
2187
|
+
* Oldest entries (by insertion order) are removed first.
|
|
2188
|
+
*
|
|
2189
|
+
* @param maxCount - Maximum number of archived tokens to retain (default: 100).
|
|
2006
2190
|
*/
|
|
2007
2191
|
pruneArchivedTokens(maxCount?: number): Promise<void>;
|
|
2008
2192
|
/**
|
|
2009
|
-
* Get forked
|
|
2193
|
+
* Get all forked token versions.
|
|
2194
|
+
*
|
|
2195
|
+
* Forked tokens represent alternative histories detected during sync.
|
|
2196
|
+
* The map key is `{tokenId}_{stateHash}`.
|
|
2197
|
+
*
|
|
2198
|
+
* @returns A shallow copy of the forked tokens map.
|
|
2010
2199
|
*/
|
|
2011
2200
|
getForkedTokens(): Map<string, TxfToken>;
|
|
2012
2201
|
/**
|
|
2013
|
-
* Store a forked token
|
|
2202
|
+
* Store a forked token version (alternative history).
|
|
2203
|
+
*
|
|
2204
|
+
* No-op if the exact `(tokenId, stateHash)` key already exists.
|
|
2205
|
+
*
|
|
2206
|
+
* @param tokenId - Genesis token ID.
|
|
2207
|
+
* @param stateHash - State hash of this forked version.
|
|
2208
|
+
* @param txfToken - The TXF token data to store.
|
|
2014
2209
|
*/
|
|
2015
2210
|
storeForkedToken(tokenId: string, stateHash: string, txfToken: TxfToken): Promise<void>;
|
|
2016
2211
|
/**
|
|
2017
|
-
* Merge remote
|
|
2018
|
-
*
|
|
2212
|
+
* Merge forked tokens from a remote sync source. Only new keys are added.
|
|
2213
|
+
*
|
|
2214
|
+
* @param remoteForked - Map of `{tokenId}_{stateHash}` → TXF token from remote.
|
|
2215
|
+
* @returns Number of new forked tokens added.
|
|
2019
2216
|
*/
|
|
2020
2217
|
mergeForkedTokens(remoteForked: Map<string, TxfToken>): Promise<number>;
|
|
2021
2218
|
/**
|
|
2022
|
-
* Prune forked tokens
|
|
2219
|
+
* Prune forked tokens to keep at most `maxCount` entries.
|
|
2220
|
+
*
|
|
2221
|
+
* @param maxCount - Maximum number of forked tokens to retain (default: 50).
|
|
2023
2222
|
*/
|
|
2024
2223
|
pruneForkedTokens(maxCount?: number): Promise<void>;
|
|
2025
2224
|
/**
|
|
2026
|
-
* Get transaction history
|
|
2225
|
+
* Get the transaction history sorted newest-first.
|
|
2226
|
+
*
|
|
2227
|
+
* @returns Array of {@link TransactionHistoryEntry} objects in descending timestamp order.
|
|
2027
2228
|
*/
|
|
2028
2229
|
getHistory(): TransactionHistoryEntry[];
|
|
2029
2230
|
/**
|
|
2030
|
-
*
|
|
2231
|
+
* Append an entry to the transaction history.
|
|
2232
|
+
*
|
|
2233
|
+
* A unique `id` is auto-generated. The entry is immediately persisted to storage.
|
|
2234
|
+
*
|
|
2235
|
+
* @param entry - History entry fields (without `id`).
|
|
2031
2236
|
*/
|
|
2032
2237
|
addToHistory(entry: Omit<TransactionHistoryEntry, 'id'>): Promise<void>;
|
|
2033
2238
|
/**
|
|
2034
|
-
* Set nametag for current identity
|
|
2239
|
+
* Set the nametag data for the current identity.
|
|
2240
|
+
*
|
|
2241
|
+
* Persists to both key-value storage and file storage (lottery compatibility).
|
|
2242
|
+
*
|
|
2243
|
+
* @param nametag - The nametag data including minted token JSON.
|
|
2035
2244
|
*/
|
|
2036
2245
|
setNametag(nametag: NametagData): Promise<void>;
|
|
2037
2246
|
/**
|
|
2038
|
-
* Get nametag
|
|
2247
|
+
* Get the current (first) nametag data.
|
|
2248
|
+
*
|
|
2249
|
+
* @returns The nametag data, or `null` if no nametag is set.
|
|
2039
2250
|
*/
|
|
2040
2251
|
getNametag(): NametagData | null;
|
|
2041
2252
|
/**
|
|
2042
|
-
*
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
/**
|
|
2046
|
-
* Clear nametag
|
|
2253
|
+
* Get all nametag data entries.
|
|
2254
|
+
*
|
|
2255
|
+
* @returns A copy of the nametags array.
|
|
2047
2256
|
*/
|
|
2048
|
-
|
|
2257
|
+
getNametags(): NametagData[];
|
|
2049
2258
|
/**
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2259
|
+
* Check whether a nametag is currently set.
|
|
2260
|
+
*
|
|
2261
|
+
* @returns `true` if nametag data is present.
|
|
2052
2262
|
*/
|
|
2053
|
-
|
|
2263
|
+
hasNametag(): boolean;
|
|
2054
2264
|
/**
|
|
2055
|
-
*
|
|
2056
|
-
* Looks for file: nametag-{name}.json
|
|
2265
|
+
* Remove all nametag data from memory and storage.
|
|
2057
2266
|
*/
|
|
2058
|
-
|
|
2267
|
+
clearNametag(): Promise<void>;
|
|
2059
2268
|
/**
|
|
2060
2269
|
* Mint a nametag token on-chain (like Sphere wallet and lottery)
|
|
2061
2270
|
* This creates the nametag token required for receiving tokens via PROXY addresses
|
|
@@ -2070,30 +2279,60 @@ declare class PaymentsModule {
|
|
|
2070
2279
|
*/
|
|
2071
2280
|
isNametagAvailable(nametag: string): Promise<boolean>;
|
|
2072
2281
|
/**
|
|
2073
|
-
* Sync with all token storage providers (IPFS,
|
|
2074
|
-
*
|
|
2282
|
+
* Sync local token state with all configured token storage providers (IPFS, file, etc.).
|
|
2283
|
+
*
|
|
2284
|
+
* For each provider, the local data is packaged into TXF storage format, sent
|
|
2285
|
+
* to the provider's `sync()` method, and the merged result is applied locally.
|
|
2286
|
+
* Emits `sync:started`, `sync:completed`, and `sync:error` events.
|
|
2287
|
+
*
|
|
2288
|
+
* @returns Summary with counts of tokens added and removed during sync.
|
|
2075
2289
|
*/
|
|
2076
2290
|
sync(): Promise<{
|
|
2077
2291
|
added: number;
|
|
2078
2292
|
removed: number;
|
|
2079
2293
|
}>;
|
|
2294
|
+
private _doSync;
|
|
2295
|
+
/**
|
|
2296
|
+
* Subscribe to 'storage:remote-updated' events from all token storage providers.
|
|
2297
|
+
* When a provider emits this event, a debounced sync is triggered.
|
|
2298
|
+
*/
|
|
2299
|
+
private subscribeToStorageEvents;
|
|
2300
|
+
/**
|
|
2301
|
+
* Unsubscribe from all storage provider events and clear debounce timer.
|
|
2302
|
+
*/
|
|
2303
|
+
private unsubscribeStorageEvents;
|
|
2304
|
+
/**
|
|
2305
|
+
* Debounced sync triggered by a storage:remote-updated event.
|
|
2306
|
+
* Waits 500ms to batch rapid updates, then performs sync.
|
|
2307
|
+
*/
|
|
2308
|
+
private debouncedSyncFromRemoteUpdate;
|
|
2080
2309
|
/**
|
|
2081
2310
|
* Get all active token storage providers
|
|
2082
2311
|
*/
|
|
2083
2312
|
private getTokenStorageProviders;
|
|
2084
2313
|
/**
|
|
2085
|
-
*
|
|
2314
|
+
* Replace the set of token storage providers at runtime.
|
|
2315
|
+
*
|
|
2316
|
+
* Use when providers are added or removed dynamically (e.g. IPFS node started).
|
|
2317
|
+
*
|
|
2318
|
+
* @param providers - New map of provider ID → TokenStorageProvider.
|
|
2086
2319
|
*/
|
|
2087
2320
|
updateTokenStorageProviders(providers: Map<string, TokenStorageProvider<TxfStorageDataBase>>): void;
|
|
2088
2321
|
/**
|
|
2089
|
-
* Validate tokens
|
|
2322
|
+
* Validate all tokens against the aggregator (oracle provider).
|
|
2323
|
+
*
|
|
2324
|
+
* Tokens that fail validation or are detected as spent are marked `'invalid'`.
|
|
2325
|
+
*
|
|
2326
|
+
* @returns Object with arrays of valid and invalid tokens.
|
|
2090
2327
|
*/
|
|
2091
2328
|
validate(): Promise<{
|
|
2092
2329
|
valid: Token[];
|
|
2093
2330
|
invalid: Token[];
|
|
2094
2331
|
}>;
|
|
2095
2332
|
/**
|
|
2096
|
-
* Get pending transfers
|
|
2333
|
+
* Get all in-progress (pending) outgoing transfers.
|
|
2334
|
+
*
|
|
2335
|
+
* @returns Array of {@link TransferResult} objects for transfers that have not yet completed.
|
|
2097
2336
|
*/
|
|
2098
2337
|
getPendingTransfers(): TransferResult[];
|
|
2099
2338
|
/**
|
|
@@ -2258,6 +2497,126 @@ declare class CommunicationsModule {
|
|
|
2258
2497
|
private ensureInitialized;
|
|
2259
2498
|
}
|
|
2260
2499
|
|
|
2500
|
+
/**
|
|
2501
|
+
* Group Chat Module (NIP-29)
|
|
2502
|
+
*
|
|
2503
|
+
* Relay-based group chat using NIP-29 protocol on a dedicated Nostr relay.
|
|
2504
|
+
* Embeds its own NostrClient — does NOT share the wallet's TransportProvider.
|
|
2505
|
+
*/
|
|
2506
|
+
|
|
2507
|
+
interface GroupChatModuleDependencies {
|
|
2508
|
+
identity: FullIdentity;
|
|
2509
|
+
storage: StorageProvider;
|
|
2510
|
+
emitEvent: <T extends SphereEventType>(type: T, data: SphereEventMap[T]) => void;
|
|
2511
|
+
}
|
|
2512
|
+
declare class GroupChatModule {
|
|
2513
|
+
private config;
|
|
2514
|
+
private deps;
|
|
2515
|
+
private client;
|
|
2516
|
+
private keyManager;
|
|
2517
|
+
private connected;
|
|
2518
|
+
private connecting;
|
|
2519
|
+
private connectPromise;
|
|
2520
|
+
private reconnectAttempts;
|
|
2521
|
+
private reconnectTimer;
|
|
2522
|
+
private subscriptionIds;
|
|
2523
|
+
private groups;
|
|
2524
|
+
private messages;
|
|
2525
|
+
private members;
|
|
2526
|
+
private processedEventIds;
|
|
2527
|
+
private pendingLeaves;
|
|
2528
|
+
private persistTimer;
|
|
2529
|
+
private persistPromise;
|
|
2530
|
+
private relayAdminPubkeys;
|
|
2531
|
+
private relayAdminFetchPromise;
|
|
2532
|
+
private messageHandlers;
|
|
2533
|
+
constructor(config?: GroupChatModuleConfig);
|
|
2534
|
+
initialize(deps: GroupChatModuleDependencies): void;
|
|
2535
|
+
load(): Promise<void>;
|
|
2536
|
+
destroy(): void;
|
|
2537
|
+
private destroyConnection;
|
|
2538
|
+
connect(): Promise<void>;
|
|
2539
|
+
getConnectionStatus(): boolean;
|
|
2540
|
+
private doConnect;
|
|
2541
|
+
private scheduleReconnect;
|
|
2542
|
+
private subscribeToJoinedGroups;
|
|
2543
|
+
private subscribeToGroup;
|
|
2544
|
+
private handleGroupEvent;
|
|
2545
|
+
private handleMetadataEvent;
|
|
2546
|
+
private handleModerationEvent;
|
|
2547
|
+
private updateMembersFromEvent;
|
|
2548
|
+
private updateAdminsFromEvent;
|
|
2549
|
+
private restoreJoinedGroups;
|
|
2550
|
+
fetchAvailableGroups(): Promise<GroupData[]>;
|
|
2551
|
+
joinGroup(groupId: string, inviteCode?: string): Promise<boolean>;
|
|
2552
|
+
leaveGroup(groupId: string): Promise<boolean>;
|
|
2553
|
+
createGroup(options: CreateGroupOptions): Promise<GroupData | null>;
|
|
2554
|
+
deleteGroup(groupId: string): Promise<boolean>;
|
|
2555
|
+
createInvite(groupId: string): Promise<string | null>;
|
|
2556
|
+
sendMessage(groupId: string, content: string, replyToId?: string): Promise<GroupMessageData | null>;
|
|
2557
|
+
fetchMessages(groupId: string, since?: number, limit?: number): Promise<GroupMessageData[]>;
|
|
2558
|
+
getGroups(): GroupData[];
|
|
2559
|
+
getGroup(groupId: string): GroupData | null;
|
|
2560
|
+
getMessages(groupId: string): GroupMessageData[];
|
|
2561
|
+
getMembers(groupId: string): GroupMemberData[];
|
|
2562
|
+
getMember(groupId: string, pubkey: string): GroupMemberData | null;
|
|
2563
|
+
getTotalUnreadCount(): number;
|
|
2564
|
+
markGroupAsRead(groupId: string): void;
|
|
2565
|
+
kickUser(groupId: string, userPubkey: string, reason?: string): Promise<boolean>;
|
|
2566
|
+
deleteMessage(groupId: string, messageId: string): Promise<boolean>;
|
|
2567
|
+
isCurrentUserAdmin(groupId: string): boolean;
|
|
2568
|
+
isCurrentUserModerator(groupId: string): boolean;
|
|
2569
|
+
/**
|
|
2570
|
+
* Check if current user can moderate a group:
|
|
2571
|
+
* - Group admin/moderator can always moderate their group
|
|
2572
|
+
* - Relay admins can moderate public groups
|
|
2573
|
+
*/
|
|
2574
|
+
canModerateGroup(groupId: string): Promise<boolean>;
|
|
2575
|
+
isCurrentUserRelayAdmin(): Promise<boolean>;
|
|
2576
|
+
getCurrentUserRole(groupId: string): GroupRole | null;
|
|
2577
|
+
onMessage(handler: (message: GroupMessageData) => void): () => void;
|
|
2578
|
+
getRelayUrls(): string[];
|
|
2579
|
+
getMyPublicKey(): string | null;
|
|
2580
|
+
private fetchRelayAdmins;
|
|
2581
|
+
private doFetchRelayAdmins;
|
|
2582
|
+
private fetchGroupMetadataInternal;
|
|
2583
|
+
private fetchAndSaveMembers;
|
|
2584
|
+
private fetchGroupMembersInternal;
|
|
2585
|
+
private fetchGroupAdminsInternal;
|
|
2586
|
+
private saveMessageToMemory;
|
|
2587
|
+
private deleteMessageFromMemory;
|
|
2588
|
+
private saveMemberToMemory;
|
|
2589
|
+
private removeMemberFromMemory;
|
|
2590
|
+
private removeGroupFromMemory;
|
|
2591
|
+
private updateGroupLastMessage;
|
|
2592
|
+
private updateMemberNametag;
|
|
2593
|
+
private addProcessedEventId;
|
|
2594
|
+
/** Schedule a debounced persist (coalesces rapid event bursts). */
|
|
2595
|
+
private schedulePersist;
|
|
2596
|
+
/** Persist immediately (for explicit flush points). */
|
|
2597
|
+
private persistAll;
|
|
2598
|
+
private doPersistAll;
|
|
2599
|
+
private persistGroups;
|
|
2600
|
+
private persistMessages;
|
|
2601
|
+
private persistMembers;
|
|
2602
|
+
private persistProcessedEvents;
|
|
2603
|
+
private checkAndClearOnRelayChange;
|
|
2604
|
+
private wrapMessageContent;
|
|
2605
|
+
private unwrapMessageContent;
|
|
2606
|
+
private getGroupIdFromEvent;
|
|
2607
|
+
private getGroupIdFromMetadataEvent;
|
|
2608
|
+
private extractReplyTo;
|
|
2609
|
+
private extractPreviousIds;
|
|
2610
|
+
private parseGroupMetadata;
|
|
2611
|
+
/** Subscribe and track the subscription ID for cleanup. */
|
|
2612
|
+
private trackSubscription;
|
|
2613
|
+
/** Subscribe for a one-shot fetch, auto-unsubscribe on EOSE or timeout. */
|
|
2614
|
+
private oneshotSubscription;
|
|
2615
|
+
private ensureInitialized;
|
|
2616
|
+
private ensureConnected;
|
|
2617
|
+
private randomId;
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2261
2620
|
/** Network configurations */
|
|
2262
2621
|
declare const NETWORKS: {
|
|
2263
2622
|
readonly mainnet: {
|
|
@@ -2266,6 +2625,7 @@ declare const NETWORKS: {
|
|
|
2266
2625
|
readonly nostrRelays: readonly ["wss://relay.unicity.network", "wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
|
|
2267
2626
|
readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
|
|
2268
2627
|
readonly electrumUrl: "wss://fulcrum.alpha.unicity.network:50004";
|
|
2628
|
+
readonly groupRelays: readonly ["wss://sphere-relay.unicity.network"];
|
|
2269
2629
|
};
|
|
2270
2630
|
readonly testnet: {
|
|
2271
2631
|
readonly name: "Testnet";
|
|
@@ -2273,6 +2633,7 @@ declare const NETWORKS: {
|
|
|
2273
2633
|
readonly nostrRelays: readonly ["wss://nostr-relay.testnet.unicity.network"];
|
|
2274
2634
|
readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
|
|
2275
2635
|
readonly electrumUrl: "wss://fulcrum.alpha.testnet.unicity.network:50004";
|
|
2636
|
+
readonly groupRelays: readonly ["wss://sphere-relay.unicity.network"];
|
|
2276
2637
|
};
|
|
2277
2638
|
readonly dev: {
|
|
2278
2639
|
readonly name: "Development";
|
|
@@ -2280,6 +2641,7 @@ declare const NETWORKS: {
|
|
|
2280
2641
|
readonly nostrRelays: readonly ["wss://nostr-relay.testnet.unicity.network"];
|
|
2281
2642
|
readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
|
|
2282
2643
|
readonly electrumUrl: "wss://fulcrum.alpha.testnet.unicity.network:50004";
|
|
2644
|
+
readonly groupRelays: readonly ["wss://sphere-relay.unicity.network"];
|
|
2283
2645
|
};
|
|
2284
2646
|
};
|
|
2285
2647
|
type NetworkType = keyof typeof NETWORKS;
|
|
@@ -2365,6 +2727,8 @@ type LegacyFileType = 'dat' | 'txt' | 'json' | 'mnemonic' | 'unknown';
|
|
|
2365
2727
|
*/
|
|
2366
2728
|
type DecryptionProgressCallback = (iteration: number, total: number) => Promise<void> | void;
|
|
2367
2729
|
|
|
2730
|
+
declare function isValidNametag(nametag: string): boolean;
|
|
2731
|
+
|
|
2368
2732
|
/** Options for creating a new wallet */
|
|
2369
2733
|
interface SphereCreateOptions {
|
|
2370
2734
|
/** BIP39 mnemonic (12 or 24 words) */
|
|
@@ -2391,6 +2755,8 @@ interface SphereCreateOptions {
|
|
|
2391
2755
|
* Use createBrowserProviders({ network: 'testnet' }) to set up testnet providers.
|
|
2392
2756
|
*/
|
|
2393
2757
|
network?: NetworkType;
|
|
2758
|
+
/** Group chat configuration (NIP-29). Omit to disable groupchat. */
|
|
2759
|
+
groupChat?: GroupChatModuleConfig | boolean;
|
|
2394
2760
|
}
|
|
2395
2761
|
/** Options for loading existing wallet */
|
|
2396
2762
|
interface SphereLoadOptions {
|
|
@@ -2412,6 +2778,8 @@ interface SphereLoadOptions {
|
|
|
2412
2778
|
* Use createBrowserProviders({ network: 'testnet' }) to set up testnet providers.
|
|
2413
2779
|
*/
|
|
2414
2780
|
network?: NetworkType;
|
|
2781
|
+
/** Group chat configuration (NIP-29). Omit to disable groupchat. */
|
|
2782
|
+
groupChat?: GroupChatModuleConfig | boolean;
|
|
2415
2783
|
}
|
|
2416
2784
|
/** Options for importing a wallet */
|
|
2417
2785
|
interface SphereImportOptions {
|
|
@@ -2441,6 +2809,8 @@ interface SphereImportOptions {
|
|
|
2441
2809
|
l1?: L1Config;
|
|
2442
2810
|
/** Optional price provider for fiat conversion */
|
|
2443
2811
|
price?: PriceProvider;
|
|
2812
|
+
/** Group chat configuration (NIP-29). Omit to disable groupchat. */
|
|
2813
|
+
groupChat?: GroupChatModuleConfig | boolean;
|
|
2444
2814
|
}
|
|
2445
2815
|
/** L1 (ALPHA blockchain) configuration */
|
|
2446
2816
|
interface L1Config {
|
|
@@ -2479,6 +2849,13 @@ interface SphereInitOptions {
|
|
|
2479
2849
|
* Use createBrowserProviders({ network: 'testnet' }) to set up testnet providers.
|
|
2480
2850
|
*/
|
|
2481
2851
|
network?: NetworkType;
|
|
2852
|
+
/**
|
|
2853
|
+
* Group chat configuration (NIP-29).
|
|
2854
|
+
* - `true`: Enable with network-default relays
|
|
2855
|
+
* - `GroupChatModuleConfig`: Enable with custom config
|
|
2856
|
+
* - Omit/undefined: No groupchat module
|
|
2857
|
+
*/
|
|
2858
|
+
groupChat?: GroupChatModuleConfig | boolean;
|
|
2482
2859
|
}
|
|
2483
2860
|
/** Result of init operation */
|
|
2484
2861
|
interface SphereInitResult {
|
|
@@ -2514,6 +2891,7 @@ declare class Sphere {
|
|
|
2514
2891
|
private _priceProvider;
|
|
2515
2892
|
private _payments;
|
|
2516
2893
|
private _communications;
|
|
2894
|
+
private _groupChat;
|
|
2517
2895
|
private eventHandlers;
|
|
2518
2896
|
private constructor();
|
|
2519
2897
|
/**
|
|
@@ -2546,6 +2924,18 @@ declare class Sphere {
|
|
|
2546
2924
|
* ```
|
|
2547
2925
|
*/
|
|
2548
2926
|
static init(options: SphereInitOptions): Promise<SphereInitResult>;
|
|
2927
|
+
/**
|
|
2928
|
+
* Resolve groupChat config from init/create/load options.
|
|
2929
|
+
* - `true` → use network-default relays
|
|
2930
|
+
* - `GroupChatModuleConfig` → pass through
|
|
2931
|
+
* - `undefined` → no groupchat
|
|
2932
|
+
*/
|
|
2933
|
+
/**
|
|
2934
|
+
* Resolve GroupChat config from Sphere.init() options.
|
|
2935
|
+
* Note: impl/shared/resolvers.ts has a similar resolver for provider-level config
|
|
2936
|
+
* (different input shape: { enabled?, relays? }). Both fill relay URLs from network defaults.
|
|
2937
|
+
*/
|
|
2938
|
+
private static resolveGroupChatConfig;
|
|
2549
2939
|
/**
|
|
2550
2940
|
* Create new wallet with mnemonic
|
|
2551
2941
|
*/
|
|
@@ -2602,6 +2992,8 @@ declare class Sphere {
|
|
|
2602
2992
|
get payments(): PaymentsModule;
|
|
2603
2993
|
/** Communications module */
|
|
2604
2994
|
get communications(): CommunicationsModule;
|
|
2995
|
+
/** Group chat module (NIP-29). Null if not configured. */
|
|
2996
|
+
get groupChat(): GroupChatModule | null;
|
|
2605
2997
|
/** Current identity (public info only) */
|
|
2606
2998
|
get identity(): Identity | null;
|
|
2607
2999
|
/** Is ready */
|
|
@@ -3095,9 +3487,9 @@ declare class Sphere {
|
|
|
3095
3487
|
*/
|
|
3096
3488
|
private recoverNametagFromTransport;
|
|
3097
3489
|
/**
|
|
3098
|
-
*
|
|
3490
|
+
* Strip @ prefix and normalize a nametag (lowercase, phone E.164, strip @unicity suffix).
|
|
3099
3491
|
*/
|
|
3100
|
-
private
|
|
3492
|
+
private cleanNametag;
|
|
3101
3493
|
destroy(): Promise<void>;
|
|
3102
3494
|
private storeMnemonic;
|
|
3103
3495
|
private storeMasterKey;
|
|
@@ -3378,4 +3770,4 @@ declare function randomHex(byteLength: number): string;
|
|
|
3378
3770
|
*/
|
|
3379
3771
|
declare function randomUUID(): string;
|
|
3380
3772
|
|
|
3381
|
-
export { type AddressInfo, CHARSET, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type EncryptedData, type EncryptionOptions, type KeyPair, type L1Config, type MasterKey, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isValidBech32, isValidPrivateKey, loadSphere, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic };
|
|
3773
|
+
export { type AddressInfo, CHARSET, CurrencyUtils, DEFAULT_DERIVATION_PATH, DEFAULT_TOKEN_DECIMALS, type DerivedKey, type EncryptedData, type EncryptionOptions, type KeyPair, type L1Config, type MasterKey, type ScanAddressProgress, type ScanAddressesOptions, type ScanAddressesResult, type ScannedAddressResult, Sphere, type SphereCreateOptions, type SphereImportOptions, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, base58Decode, base58Encode, bytesToHex, computeHash160, convertBits, createAddress, createBech32, createKeyPair, createSphere, decodeBech32, decrypt, decryptJson, decryptMnemonic, decryptSimple, decryptWithSalt, deriveAddressInfo, deriveChildKey, deriveKeyAtPath, deserializeEncrypted, doubleSha256, ec, encodeBech32, encrypt, encryptMnemonic, encryptSimple, entropyToMnemonic, extractFromText, findPattern, formatAmount, generateAddressInfo, generateMasterKey, generateMnemonic, generateRandomKey, getAddressHrp, getPublicKey, getSphere, hash160, hash160ToBytes, hexToBytes, identityFromMnemonic, identityFromMnemonicSync, importSphere, initSphere, isEncryptedData, isValidBech32, isValidNametag, isValidPrivateKey, loadSphere, mnemonicToEntropy, mnemonicToSeed, mnemonicToSeedSync, privateKeyToAddressInfo, publicKeyToAddress, randomBytes, randomHex, randomUUID, ripemd160, scanAddressesImpl, serializeEncrypted, sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, validateMnemonic };
|