@unicitylabs/sphere-sdk 0.1.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.
@@ -0,0 +1,1091 @@
1
+ import { StateTransitionClient } from '@unicitylabs/state-transition-sdk/lib/StateTransitionClient';
2
+ import { AggregatorClient } from '@unicitylabs/state-transition-sdk/lib/api/AggregatorClient';
3
+ import { RootTrustBase } from '@unicitylabs/state-transition-sdk/lib/bft/RootTrustBase';
4
+ import { TransferCommitment as TransferCommitment$1 } from '@unicitylabs/state-transition-sdk/lib/transaction/TransferCommitment';
5
+
6
+ /**
7
+ * SDK2 Core Types
8
+ * Platform-independent type definitions
9
+ */
10
+ type ProviderStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
11
+ interface ProviderMetadata {
12
+ readonly id: string;
13
+ readonly name: string;
14
+ readonly type: 'local' | 'cloud' | 'p2p' | 'network';
15
+ readonly description?: string;
16
+ }
17
+ interface BaseProvider extends ProviderMetadata {
18
+ connect(config?: unknown): Promise<void>;
19
+ disconnect(): Promise<void>;
20
+ isConnected(): boolean;
21
+ getStatus(): ProviderStatus;
22
+ }
23
+ interface Identity {
24
+ readonly publicKey: string;
25
+ /** L1 address (alpha1...) */
26
+ readonly address: string;
27
+ /** L3 predicate address (DIRECT://...) */
28
+ readonly predicateAddress?: string;
29
+ readonly ipnsName?: string;
30
+ readonly nametag?: string;
31
+ }
32
+ interface FullIdentity extends Identity {
33
+ readonly privateKey: string;
34
+ }
35
+
36
+ /**
37
+ * Storage Provider Interface
38
+ * Platform-independent storage abstraction
39
+ */
40
+
41
+ /**
42
+ * Basic key-value storage provider
43
+ * All operations are async for platform flexibility
44
+ */
45
+ interface StorageProvider extends BaseProvider {
46
+ /**
47
+ * Set identity for scoped storage
48
+ */
49
+ setIdentity(identity: FullIdentity): void;
50
+ /**
51
+ * Get value by key
52
+ */
53
+ get(key: string): Promise<string | null>;
54
+ /**
55
+ * Set value by key
56
+ */
57
+ set(key: string, value: string): Promise<void>;
58
+ /**
59
+ * Remove key
60
+ */
61
+ remove(key: string): Promise<void>;
62
+ /**
63
+ * Check if key exists
64
+ */
65
+ has(key: string): Promise<boolean>;
66
+ /**
67
+ * Get all keys with optional prefix filter
68
+ */
69
+ keys(prefix?: string): Promise<string[]>;
70
+ /**
71
+ * Clear all keys with optional prefix filter
72
+ */
73
+ clear(prefix?: string): Promise<void>;
74
+ }
75
+ /**
76
+ * Storage result types
77
+ */
78
+ interface SaveResult {
79
+ success: boolean;
80
+ cid?: string;
81
+ error?: string;
82
+ timestamp: number;
83
+ }
84
+ interface LoadResult<T = unknown> {
85
+ success: boolean;
86
+ data?: T;
87
+ error?: string;
88
+ source: 'local' | 'remote' | 'cache';
89
+ timestamp: number;
90
+ }
91
+ interface SyncResult<T = unknown> {
92
+ success: boolean;
93
+ merged?: T;
94
+ added: number;
95
+ removed: number;
96
+ conflicts: number;
97
+ error?: string;
98
+ }
99
+ /**
100
+ * Token-specific storage provider
101
+ * Handles token persistence with sync capabilities
102
+ */
103
+ interface TokenStorageProvider<TData = unknown> extends BaseProvider {
104
+ /**
105
+ * Set identity for storage scope
106
+ */
107
+ setIdentity(identity: FullIdentity): void;
108
+ /**
109
+ * Initialize provider (called once after identity is set)
110
+ */
111
+ initialize(): Promise<boolean>;
112
+ /**
113
+ * Shutdown provider
114
+ */
115
+ shutdown(): Promise<void>;
116
+ /**
117
+ * Save token data
118
+ */
119
+ save(data: TData): Promise<SaveResult>;
120
+ /**
121
+ * Load token data
122
+ */
123
+ load(identifier?: string): Promise<LoadResult<TData>>;
124
+ /**
125
+ * Sync local data with remote
126
+ */
127
+ sync(localData: TData): Promise<SyncResult<TData>>;
128
+ /**
129
+ * Check if data exists
130
+ */
131
+ exists?(identifier?: string): Promise<boolean>;
132
+ /**
133
+ * Clear all data
134
+ */
135
+ clear?(): Promise<boolean>;
136
+ /**
137
+ * Subscribe to storage events
138
+ */
139
+ onEvent?(callback: StorageEventCallback): () => void;
140
+ /**
141
+ * Save individual token (for file-based storage like lottery pattern)
142
+ */
143
+ saveToken?(tokenId: string, tokenData: unknown): Promise<void>;
144
+ /**
145
+ * Get individual token
146
+ */
147
+ getToken?(tokenId: string): Promise<unknown | null>;
148
+ /**
149
+ * List all token IDs
150
+ */
151
+ listTokenIds?(): Promise<string[]>;
152
+ /**
153
+ * Delete individual token
154
+ */
155
+ deleteToken?(tokenId: string): Promise<void>;
156
+ }
157
+ type StorageEventType = 'storage:saving' | 'storage:saved' | 'storage:loading' | 'storage:loaded' | 'storage:error' | 'sync:started' | 'sync:completed' | 'sync:conflict' | 'sync:error';
158
+ interface StorageEvent {
159
+ type: StorageEventType;
160
+ timestamp: number;
161
+ data?: unknown;
162
+ error?: string;
163
+ }
164
+ type StorageEventCallback = (event: StorageEvent) => void;
165
+ interface TxfStorageDataBase {
166
+ _meta: TxfMeta;
167
+ _tombstones?: TxfTombstone[];
168
+ _outbox?: TxfOutboxEntry[];
169
+ _sent?: TxfSentEntry[];
170
+ _invalid?: TxfInvalidEntry[];
171
+ [key: `_${string}`]: unknown;
172
+ }
173
+ interface TxfMeta {
174
+ version: number;
175
+ address: string;
176
+ ipnsName?: string;
177
+ formatVersion: string;
178
+ updatedAt: number;
179
+ }
180
+ interface TxfTombstone {
181
+ tokenId: string;
182
+ stateHash: string;
183
+ timestamp: number;
184
+ }
185
+ interface TxfOutboxEntry {
186
+ id: string;
187
+ status: string;
188
+ tokenId: string;
189
+ recipient: string;
190
+ createdAt: number;
191
+ data: unknown;
192
+ }
193
+ interface TxfSentEntry {
194
+ tokenId: string;
195
+ recipient: string;
196
+ txHash: string;
197
+ sentAt: number;
198
+ }
199
+ interface TxfInvalidEntry {
200
+ tokenId: string;
201
+ reason: string;
202
+ detectedAt: number;
203
+ }
204
+
205
+ /**
206
+ * File Storage Provider for Node.js
207
+ * Stores wallet data in JSON files
208
+ */
209
+
210
+ interface FileStorageProviderConfig {
211
+ /** Directory to store wallet data */
212
+ dataDir: string;
213
+ /** File name for key-value data (default: 'wallet.json') */
214
+ fileName?: string;
215
+ }
216
+ declare class FileStorageProvider implements StorageProvider {
217
+ readonly id = "file-storage";
218
+ readonly name = "File Storage";
219
+ readonly type: "local";
220
+ private dataDir;
221
+ private filePath;
222
+ private data;
223
+ private status;
224
+ private _identity;
225
+ constructor(config: FileStorageProviderConfig | string);
226
+ setIdentity(identity: FullIdentity): void;
227
+ getIdentity(): FullIdentity | null;
228
+ connect(): Promise<void>;
229
+ disconnect(): Promise<void>;
230
+ isConnected(): boolean;
231
+ getStatus(): ProviderStatus;
232
+ get(key: string): Promise<string | null>;
233
+ set(key: string, value: string): Promise<void>;
234
+ remove(key: string): Promise<void>;
235
+ has(key: string): Promise<boolean>;
236
+ keys(prefix?: string): Promise<string[]>;
237
+ clear(prefix?: string): Promise<void>;
238
+ private save;
239
+ }
240
+ declare function createFileStorageProvider(config: FileStorageProviderConfig | string): FileStorageProvider;
241
+
242
+ /**
243
+ * File Token Storage Provider for Node.js
244
+ * Stores tokens as individual JSON files
245
+ */
246
+
247
+ interface FileTokenStorageConfig {
248
+ /** Directory to store token files */
249
+ tokensDir: string;
250
+ }
251
+ declare class FileTokenStorageProvider implements TokenStorageProvider<TxfStorageDataBase> {
252
+ readonly id = "file-token-storage";
253
+ readonly name = "File Token Storage";
254
+ readonly type: "local";
255
+ private tokensDir;
256
+ private status;
257
+ private identity;
258
+ constructor(config: FileTokenStorageConfig | string);
259
+ setIdentity(identity: FullIdentity): void;
260
+ initialize(): Promise<boolean>;
261
+ shutdown(): Promise<void>;
262
+ connect(): Promise<void>;
263
+ disconnect(): Promise<void>;
264
+ isConnected(): boolean;
265
+ getStatus(): ProviderStatus;
266
+ load(): Promise<LoadResult<TxfStorageDataBase>>;
267
+ save(data: TxfStorageDataBase): Promise<SaveResult>;
268
+ sync(localData: TxfStorageDataBase): Promise<SyncResult<TxfStorageDataBase>>;
269
+ deleteToken(tokenId: string): Promise<void>;
270
+ saveToken(tokenId: string, tokenData: unknown): Promise<void>;
271
+ getToken(tokenId: string): Promise<unknown | null>;
272
+ listTokenIds(): Promise<string[]>;
273
+ }
274
+ declare function createFileTokenStorageProvider(config: FileTokenStorageConfig | string): FileTokenStorageProvider;
275
+
276
+ /**
277
+ * Transport Provider Interface
278
+ * Platform-independent P2P messaging abstraction
279
+ */
280
+
281
+ /**
282
+ * P2P messaging transport provider
283
+ */
284
+ interface TransportProvider extends BaseProvider {
285
+ /**
286
+ * Set identity for signing/encryption
287
+ */
288
+ setIdentity(identity: FullIdentity): void;
289
+ /**
290
+ * Send encrypted direct message
291
+ * @returns Event ID
292
+ */
293
+ sendMessage(recipientPubkey: string, content: string): Promise<string>;
294
+ /**
295
+ * Subscribe to incoming direct messages
296
+ * @returns Unsubscribe function
297
+ */
298
+ onMessage(handler: MessageHandler): () => void;
299
+ /**
300
+ * Send token transfer payload
301
+ * @returns Event ID
302
+ */
303
+ sendTokenTransfer(recipientPubkey: string, payload: TokenTransferPayload): Promise<string>;
304
+ /**
305
+ * Subscribe to incoming token transfers
306
+ * @returns Unsubscribe function
307
+ */
308
+ onTokenTransfer(handler: TokenTransferHandler): () => void;
309
+ /**
310
+ * Resolve nametag to public key
311
+ */
312
+ resolveNametag?(nametag: string): Promise<string | null>;
313
+ /**
314
+ * Register a nametag for this identity
315
+ * @returns true if successful, false if already taken
316
+ */
317
+ registerNametag?(nametag: string, publicKey: string): Promise<boolean>;
318
+ /**
319
+ * Publish nametag binding
320
+ */
321
+ publishNametag?(nametag: string, address: string): Promise<void>;
322
+ /**
323
+ * Subscribe to broadcast messages (global/channel)
324
+ */
325
+ subscribeToBroadcast?(tags: string[], handler: BroadcastHandler): () => void;
326
+ /**
327
+ * Publish broadcast message
328
+ */
329
+ publishBroadcast?(content: string, tags?: string[]): Promise<string>;
330
+ /**
331
+ * Send payment request to a recipient
332
+ * @returns Event ID
333
+ */
334
+ sendPaymentRequest?(recipientPubkey: string, request: PaymentRequestPayload): Promise<string>;
335
+ /**
336
+ * Subscribe to incoming payment requests
337
+ * @returns Unsubscribe function
338
+ */
339
+ onPaymentRequest?(handler: PaymentRequestHandler): () => void;
340
+ /**
341
+ * Send response to a payment request
342
+ * @returns Event ID
343
+ */
344
+ sendPaymentRequestResponse?(recipientPubkey: string, response: PaymentRequestResponsePayload): Promise<string>;
345
+ /**
346
+ * Subscribe to incoming payment request responses
347
+ * @returns Unsubscribe function
348
+ */
349
+ onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
350
+ /**
351
+ * Get list of configured relay URLs
352
+ */
353
+ getRelays?(): string[];
354
+ /**
355
+ * Get list of currently connected relay URLs
356
+ */
357
+ getConnectedRelays?(): string[];
358
+ /**
359
+ * Add a relay dynamically
360
+ * @returns true if added successfully
361
+ */
362
+ addRelay?(relayUrl: string): Promise<boolean>;
363
+ /**
364
+ * Remove a relay dynamically
365
+ * @returns true if removed successfully
366
+ */
367
+ removeRelay?(relayUrl: string): Promise<boolean>;
368
+ /**
369
+ * Check if a relay is configured
370
+ */
371
+ hasRelay?(relayUrl: string): boolean;
372
+ /**
373
+ * Check if a relay is currently connected
374
+ */
375
+ isRelayConnected?(relayUrl: string): boolean;
376
+ }
377
+ interface IncomingMessage {
378
+ id: string;
379
+ senderPubkey: string;
380
+ content: string;
381
+ timestamp: number;
382
+ encrypted: boolean;
383
+ }
384
+ type MessageHandler = (message: IncomingMessage) => void;
385
+ interface TokenTransferPayload {
386
+ /** Serialized token data */
387
+ token: string;
388
+ /** Inclusion proof */
389
+ proof: unknown;
390
+ /** Optional memo */
391
+ memo?: string;
392
+ /** Sender info */
393
+ sender?: {
394
+ pubkey: string;
395
+ nametag?: string;
396
+ };
397
+ }
398
+ interface IncomingTokenTransfer {
399
+ id: string;
400
+ senderPubkey: string;
401
+ payload: TokenTransferPayload;
402
+ timestamp: number;
403
+ }
404
+ type TokenTransferHandler = (transfer: IncomingTokenTransfer) => void;
405
+ interface PaymentRequestPayload {
406
+ /** Amount requested (in smallest units) */
407
+ amount: string | bigint;
408
+ /** Coin/token type ID */
409
+ coinId: string;
410
+ /** Message/memo for recipient */
411
+ message?: string;
412
+ /** Recipient's nametag (who should pay) */
413
+ recipientNametag?: string;
414
+ /** Custom metadata */
415
+ metadata?: Record<string, unknown>;
416
+ }
417
+ interface IncomingPaymentRequest {
418
+ /** Event ID */
419
+ id: string;
420
+ /** Sender's public key */
421
+ senderPubkey: string;
422
+ /** Parsed request data */
423
+ request: {
424
+ requestId: string;
425
+ amount: string;
426
+ coinId: string;
427
+ message?: string;
428
+ recipientNametag?: string;
429
+ metadata?: Record<string, unknown>;
430
+ };
431
+ /** Timestamp */
432
+ timestamp: number;
433
+ }
434
+ type PaymentRequestHandler = (request: IncomingPaymentRequest) => void;
435
+ type PaymentRequestResponseType = 'accepted' | 'rejected' | 'paid';
436
+ interface PaymentRequestResponsePayload {
437
+ /** Original request ID */
438
+ requestId: string;
439
+ /** Response type */
440
+ responseType: PaymentRequestResponseType;
441
+ /** Optional message */
442
+ message?: string;
443
+ /** Transfer ID (if paid) */
444
+ transferId?: string;
445
+ }
446
+ interface IncomingPaymentRequestResponse {
447
+ /** Event ID */
448
+ id: string;
449
+ /** Responder's public key */
450
+ responderPubkey: string;
451
+ /** Parsed response data */
452
+ response: {
453
+ requestId: string;
454
+ responseType: PaymentRequestResponseType;
455
+ message?: string;
456
+ transferId?: string;
457
+ };
458
+ /** Timestamp */
459
+ timestamp: number;
460
+ }
461
+ type PaymentRequestResponseHandler = (response: IncomingPaymentRequestResponse) => void;
462
+ interface IncomingBroadcast {
463
+ id: string;
464
+ authorPubkey: string;
465
+ content: string;
466
+ tags: string[];
467
+ timestamp: number;
468
+ }
469
+ type BroadcastHandler = (broadcast: IncomingBroadcast) => void;
470
+ type TransportEventType = 'transport:connected' | 'transport:disconnected' | 'transport:reconnecting' | 'transport:error' | 'transport:relay_added' | 'transport:relay_removed' | 'message:received' | 'message:sent' | 'transfer:received' | 'transfer:sent';
471
+ interface TransportEvent {
472
+ type: TransportEventType;
473
+ timestamp: number;
474
+ data?: unknown;
475
+ error?: string;
476
+ }
477
+ type TransportEventCallback = (event: TransportEvent) => void;
478
+
479
+ /**
480
+ * WebSocket Abstraction
481
+ * Platform-independent WebSocket interface for cross-platform support
482
+ */
483
+ /**
484
+ * Minimal WebSocket interface compatible with browser and Node.js
485
+ */
486
+ interface IWebSocket {
487
+ readonly readyState: number;
488
+ send(data: string): void;
489
+ close(code?: number, reason?: string): void;
490
+ onopen: ((event: unknown) => void) | null;
491
+ onclose: ((event: unknown) => void) | null;
492
+ onerror: ((event: unknown) => void) | null;
493
+ onmessage: ((event: IMessageEvent) => void) | null;
494
+ }
495
+ interface IMessageEvent {
496
+ data: string;
497
+ }
498
+ /**
499
+ * Factory function to create WebSocket instances
500
+ * Different implementations for browser (native) vs Node.js (ws package)
501
+ */
502
+ type WebSocketFactory = (url: string) => IWebSocket;
503
+ /**
504
+ * Generate a unique ID (platform-independent)
505
+ * Browser: crypto.randomUUID()
506
+ * Node: crypto.randomUUID() or uuid package
507
+ */
508
+ type UUIDGenerator = () => string;
509
+
510
+ /**
511
+ * Nostr Transport Provider
512
+ * Platform-independent implementation using Nostr protocol for P2P messaging
513
+ *
514
+ * Uses @unicitylabs/nostr-js-sdk for:
515
+ * - Real secp256k1 event signing
516
+ * - NIP-04 encryption/decryption
517
+ * - Event ID calculation
518
+ *
519
+ * WebSocket is injected via factory for cross-platform support
520
+ */
521
+
522
+ interface NostrTransportProviderConfig {
523
+ /** Nostr relay URLs */
524
+ relays?: string[];
525
+ /** Connection timeout (ms) */
526
+ timeout?: number;
527
+ /** Auto-reconnect on disconnect */
528
+ autoReconnect?: boolean;
529
+ /** Reconnect delay (ms) */
530
+ reconnectDelay?: number;
531
+ /** Max reconnect attempts */
532
+ maxReconnectAttempts?: number;
533
+ /** Enable debug logging */
534
+ debug?: boolean;
535
+ /** WebSocket factory (required for platform support) */
536
+ createWebSocket: WebSocketFactory;
537
+ /** UUID generator (optional, defaults to crypto.randomUUID) */
538
+ generateUUID?: UUIDGenerator;
539
+ }
540
+ declare class NostrTransportProvider implements TransportProvider {
541
+ readonly id = "nostr";
542
+ readonly name = "Nostr Transport";
543
+ readonly type: "p2p";
544
+ readonly description = "P2P messaging via Nostr protocol";
545
+ private config;
546
+ private identity;
547
+ private keyManager;
548
+ private status;
549
+ private connections;
550
+ private reconnectAttempts;
551
+ private messageHandlers;
552
+ private transferHandlers;
553
+ private paymentRequestHandlers;
554
+ private paymentRequestResponseHandlers;
555
+ private broadcastHandlers;
556
+ private eventCallbacks;
557
+ private subscriptions;
558
+ constructor(config: NostrTransportProviderConfig);
559
+ connect(): Promise<void>;
560
+ disconnect(): Promise<void>;
561
+ isConnected(): boolean;
562
+ getStatus(): ProviderStatus;
563
+ /**
564
+ * Get list of configured relay URLs
565
+ */
566
+ getRelays(): string[];
567
+ /**
568
+ * Get list of currently connected relay URLs
569
+ */
570
+ getConnectedRelays(): string[];
571
+ /**
572
+ * Add a new relay dynamically
573
+ * Will connect immediately if provider is already connected
574
+ */
575
+ addRelay(relayUrl: string): Promise<boolean>;
576
+ /**
577
+ * Remove a relay dynamically
578
+ * Will disconnect from the relay if connected
579
+ */
580
+ removeRelay(relayUrl: string): Promise<boolean>;
581
+ /**
582
+ * Check if a relay is configured
583
+ */
584
+ hasRelay(relayUrl: string): boolean;
585
+ /**
586
+ * Check if a relay is currently connected
587
+ */
588
+ isRelayConnected(relayUrl: string): boolean;
589
+ setIdentity(identity: FullIdentity): void;
590
+ /**
591
+ * Get the Nostr-format public key (32 bytes / 64 hex chars)
592
+ * This is the x-coordinate only, without the 02/03 prefix.
593
+ */
594
+ getNostrPubkey(): string;
595
+ sendMessage(recipientPubkey: string, content: string): Promise<string>;
596
+ onMessage(handler: MessageHandler): () => void;
597
+ sendTokenTransfer(recipientPubkey: string, payload: TokenTransferPayload): Promise<string>;
598
+ onTokenTransfer(handler: TokenTransferHandler): () => void;
599
+ sendPaymentRequest(recipientPubkey: string, payload: PaymentRequestPayload): Promise<string>;
600
+ onPaymentRequest(handler: PaymentRequestHandler): () => void;
601
+ sendPaymentRequestResponse(recipientPubkey: string, payload: PaymentRequestResponsePayload): Promise<string>;
602
+ onPaymentRequestResponse(handler: PaymentRequestResponseHandler): () => void;
603
+ resolveNametag(nametag: string): Promise<string | null>;
604
+ publishNametag(nametag: string, address: string): Promise<void>;
605
+ registerNametag(nametag: string, _publicKey: string): Promise<boolean>;
606
+ subscribeToBroadcast(tags: string[], handler: BroadcastHandler): () => void;
607
+ publishBroadcast(content: string, tags?: string[]): Promise<string>;
608
+ onEvent(callback: TransportEventCallback): () => void;
609
+ private connectToRelay;
610
+ private scheduleReconnect;
611
+ private handleRelayMessage;
612
+ private handleEvent;
613
+ private handleDirectMessage;
614
+ private handleTokenTransfer;
615
+ private handlePaymentRequest;
616
+ private handlePaymentRequestResponse;
617
+ private handleBroadcast;
618
+ private createEvent;
619
+ private createEncryptedEvent;
620
+ private publishEvent;
621
+ private queryEvents;
622
+ private queryEventsFromRelay;
623
+ private unsubscribeFromRelay;
624
+ private subscribeToEvents;
625
+ private subscribeToTags;
626
+ private decryptContent;
627
+ /**
628
+ * Strip known content prefixes (nostr-js-sdk compatibility)
629
+ * Handles: payment_request:, token_transfer:, etc.
630
+ */
631
+ private stripContentPrefix;
632
+ private ensureReady;
633
+ private emitEvent;
634
+ private log;
635
+ }
636
+
637
+ /**
638
+ * Node.js Transport Exports
639
+ * Re-exports shared transport with Node.js WebSocket
640
+ */
641
+
642
+ /**
643
+ * Create WebSocket factory for Node.js using 'ws' package
644
+ */
645
+ declare function createNodeWebSocketFactory(): WebSocketFactory;
646
+ /**
647
+ * Create NostrTransportProvider with Node.js WebSocket
648
+ */
649
+ declare function createNostrTransportProvider(config: Omit<NostrTransportProviderConfig, 'createWebSocket'>): NostrTransportProvider;
650
+
651
+ /**
652
+ * Oracle Provider Interface
653
+ * Platform-independent Unicity oracle abstraction
654
+ *
655
+ * The oracle is a trusted third-party service that provides verifiable truth
656
+ * about the state of tokens in the Unicity network. It aggregates state
657
+ * transitions into rounds and provides inclusion proofs that cryptographically
658
+ * verify token ownership and transfers.
659
+ */
660
+
661
+ /**
662
+ * Unicity state transition oracle provider
663
+ *
664
+ * The oracle serves as the source of truth for:
665
+ * - Token state validation (spent/unspent)
666
+ * - State transition inclusion proofs
667
+ * - Round-based commitment aggregation
668
+ */
669
+ interface OracleProvider extends BaseProvider {
670
+ /**
671
+ * Initialize with trust base
672
+ */
673
+ initialize(trustBase?: unknown): Promise<void>;
674
+ /**
675
+ * Submit transfer commitment
676
+ */
677
+ submitCommitment(commitment: TransferCommitment): Promise<SubmitResult>;
678
+ /**
679
+ * Get inclusion proof for a request
680
+ */
681
+ getProof(requestId: string): Promise<InclusionProof | null>;
682
+ /**
683
+ * Wait for inclusion proof with polling
684
+ */
685
+ waitForProof(requestId: string, options?: WaitOptions): Promise<InclusionProof>;
686
+ /**
687
+ * Validate token against aggregator
688
+ */
689
+ validateToken(tokenData: unknown): Promise<ValidationResult>;
690
+ /**
691
+ * Check if token state is spent
692
+ */
693
+ isSpent(stateHash: string): Promise<boolean>;
694
+ /**
695
+ * Get token state
696
+ */
697
+ getTokenState(tokenId: string): Promise<TokenState | null>;
698
+ /**
699
+ * Get current round number
700
+ */
701
+ getCurrentRound(): Promise<number>;
702
+ /**
703
+ * Mint new tokens (for faucet/testing)
704
+ */
705
+ mint?(params: MintParams): Promise<MintResult>;
706
+ /**
707
+ * Get underlying StateTransitionClient (if available)
708
+ * Used for advanced SDK operations like commitment creation
709
+ */
710
+ getStateTransitionClient?(): unknown;
711
+ /**
712
+ * Get underlying AggregatorClient (if available)
713
+ * Used for direct aggregator API access
714
+ */
715
+ getAggregatorClient?(): unknown;
716
+ /**
717
+ * Wait for inclusion proof using SDK commitment (if available)
718
+ * Used for transfer flows with SDK TransferCommitment
719
+ */
720
+ waitForProofSdk?(commitment: unknown, signal?: AbortSignal): Promise<unknown>;
721
+ }
722
+ interface TransferCommitment {
723
+ /** Source token (SDK format) */
724
+ sourceToken: unknown;
725
+ /** Recipient address/predicate */
726
+ recipient: string;
727
+ /** Random salt (non-reproducible) */
728
+ salt: Uint8Array;
729
+ /** Optional additional data */
730
+ data?: unknown;
731
+ }
732
+ interface SubmitResult {
733
+ success: boolean;
734
+ requestId?: string;
735
+ error?: string;
736
+ timestamp: number;
737
+ }
738
+ interface InclusionProof {
739
+ requestId: string;
740
+ roundNumber: number;
741
+ proof: unknown;
742
+ timestamp: number;
743
+ }
744
+ interface WaitOptions {
745
+ /** Timeout in ms (default: 30000) */
746
+ timeout?: number;
747
+ /** Poll interval in ms (default: 1000) */
748
+ pollInterval?: number;
749
+ /** Callback on each poll attempt */
750
+ onPoll?: (attempt: number) => void;
751
+ }
752
+ interface ValidationResult {
753
+ valid: boolean;
754
+ spent: boolean;
755
+ error?: string;
756
+ stateHash?: string;
757
+ }
758
+ interface TokenState {
759
+ tokenId: string;
760
+ stateHash: string;
761
+ spent: boolean;
762
+ roundNumber?: number;
763
+ lastUpdated: number;
764
+ }
765
+ interface MintParams {
766
+ coinId: string;
767
+ amount: string;
768
+ recipientAddress: string;
769
+ recipientPubkey?: string;
770
+ }
771
+ interface MintResult {
772
+ success: boolean;
773
+ requestId?: string;
774
+ tokenId?: string;
775
+ error?: string;
776
+ }
777
+ type OracleEventType = 'oracle:connected' | 'oracle:disconnected' | 'oracle:error' | 'commitment:submitted' | 'proof:received' | 'validation:completed';
778
+ interface OracleEvent {
779
+ type: OracleEventType;
780
+ timestamp: number;
781
+ data?: unknown;
782
+ error?: string;
783
+ }
784
+ type OracleEventCallback = (event: OracleEvent) => void;
785
+ /**
786
+ * Trust base loader interface for platform-specific loading
787
+ * Browser: fetch from URL
788
+ * Node.js: read from file
789
+ */
790
+ interface TrustBaseLoader {
791
+ /**
792
+ * Load trust base JSON data
793
+ * @returns Trust base data or null if not available
794
+ */
795
+ load(): Promise<unknown | null>;
796
+ }
797
+
798
+ /**
799
+ * Unicity Aggregator Provider
800
+ * Platform-independent implementation using @unicitylabs/state-transition-sdk
801
+ *
802
+ * The oracle is a trusted service that provides verifiable truth
803
+ * about token state through cryptographic inclusion proofs.
804
+ *
805
+ * TrustBaseLoader is injected for platform-specific loading:
806
+ * - Browser: fetch from URL
807
+ * - Node.js: read from file
808
+ */
809
+
810
+ interface SdkMintCommitment {
811
+ requestId?: {
812
+ toString(): string;
813
+ };
814
+ [key: string]: unknown;
815
+ }
816
+ interface UnicityAggregatorProviderConfig {
817
+ /** Aggregator URL */
818
+ url: string;
819
+ /** API key for authentication */
820
+ apiKey?: string;
821
+ /** Request timeout (ms) */
822
+ timeout?: number;
823
+ /** Skip trust base verification (dev only) */
824
+ skipVerification?: boolean;
825
+ /** Enable debug logging */
826
+ debug?: boolean;
827
+ /** Trust base loader (platform-specific) */
828
+ trustBaseLoader?: TrustBaseLoader;
829
+ }
830
+ /**
831
+ * Unicity Aggregator Provider
832
+ * Concrete implementation of OracleProvider using Unicity's aggregator service
833
+ */
834
+ declare class UnicityAggregatorProvider implements OracleProvider {
835
+ readonly id = "unicity-aggregator";
836
+ readonly name = "Unicity Aggregator";
837
+ readonly type: "network";
838
+ readonly description = "Unicity state transition aggregator (oracle implementation)";
839
+ private config;
840
+ private status;
841
+ private eventCallbacks;
842
+ private aggregatorClient;
843
+ private stateTransitionClient;
844
+ private trustBase;
845
+ /** Get the current trust base */
846
+ getTrustBase(): RootTrustBase | null;
847
+ /** Get the state transition client */
848
+ getStateTransitionClient(): StateTransitionClient | null;
849
+ /** Get the aggregator client */
850
+ getAggregatorClient(): AggregatorClient | null;
851
+ private spentCache;
852
+ constructor(config: UnicityAggregatorProviderConfig);
853
+ connect(): Promise<void>;
854
+ disconnect(): Promise<void>;
855
+ isConnected(): boolean;
856
+ getStatus(): ProviderStatus;
857
+ initialize(trustBase?: RootTrustBase): Promise<void>;
858
+ /**
859
+ * Submit a transfer commitment to the aggregator.
860
+ * Accepts either an SDK TransferCommitment or a simple commitment object.
861
+ */
862
+ submitCommitment(commitment: TransferCommitment | TransferCommitment$1): Promise<SubmitResult>;
863
+ /**
864
+ * Submit a mint commitment to the aggregator (SDK only)
865
+ * @param commitment - SDK MintCommitment instance
866
+ */
867
+ submitMintCommitment(commitment: SdkMintCommitment): Promise<SubmitResult>;
868
+ private isSdkTransferCommitment;
869
+ getProof(requestId: string): Promise<InclusionProof | null>;
870
+ waitForProof(requestId: string, options?: WaitOptions): Promise<InclusionProof>;
871
+ validateToken(tokenData: unknown): Promise<ValidationResult>;
872
+ /**
873
+ * Wait for inclusion proof using SDK (for SDK commitments)
874
+ */
875
+ waitForProofSdk(commitment: TransferCommitment$1 | SdkMintCommitment, signal?: AbortSignal): Promise<unknown>;
876
+ isSpent(stateHash: string): Promise<boolean>;
877
+ getTokenState(tokenId: string): Promise<TokenState | null>;
878
+ getCurrentRound(): Promise<number>;
879
+ mint(params: MintParams): Promise<MintResult>;
880
+ onEvent(callback: OracleEventCallback): () => void;
881
+ private rpcCall;
882
+ private ensureConnected;
883
+ private emitEvent;
884
+ private log;
885
+ }
886
+ /** @deprecated Use UnicityAggregatorProvider instead */
887
+ declare const UnicityOracleProvider: typeof UnicityAggregatorProvider;
888
+ /** @deprecated Use UnicityAggregatorProviderConfig instead */
889
+ type UnicityOracleProviderConfig = UnicityAggregatorProviderConfig;
890
+
891
+ /**
892
+ * Node.js Oracle Exports
893
+ * Re-exports shared oracle with Node.js-specific TrustBaseLoader
894
+ */
895
+
896
+ /**
897
+ * Node.js TrustBase loader using fs
898
+ */
899
+ declare class NodeTrustBaseLoader implements TrustBaseLoader {
900
+ private filePath;
901
+ constructor(filePath?: string);
902
+ load(): Promise<unknown | null>;
903
+ }
904
+ /**
905
+ * Create Node.js TrustBase loader
906
+ */
907
+ declare function createNodeTrustBaseLoader(filePath?: string): TrustBaseLoader;
908
+ /**
909
+ * Create UnicityAggregatorProvider with Node.js TrustBase loader
910
+ */
911
+ declare function createUnicityAggregatorProvider(config: Omit<UnicityAggregatorProviderConfig, 'trustBaseLoader'> & {
912
+ trustBasePath?: string;
913
+ }): UnicityAggregatorProvider;
914
+ /** @deprecated Use createUnicityAggregatorProvider instead */
915
+ declare const createUnicityOracleProvider: typeof createUnicityAggregatorProvider;
916
+
917
+ /** Network configurations */
918
+ declare const NETWORKS: {
919
+ readonly mainnet: {
920
+ readonly name: "Mainnet";
921
+ readonly aggregatorUrl: "https://aggregator.unicity.network/rpc";
922
+ readonly nostrRelays: readonly ["wss://relay.unicity.network", "wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
923
+ readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
924
+ readonly electrumUrl: "wss://fulcrum.alpha.unicity.network:50004";
925
+ };
926
+ readonly testnet: {
927
+ readonly name: "Testnet";
928
+ readonly aggregatorUrl: "https://goggregator-test.unicity.network";
929
+ readonly nostrRelays: readonly ["wss://nostr-relay.testnet.unicity.network"];
930
+ readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
931
+ readonly electrumUrl: "wss://fulcrum.alpha.testnet.unicity.network:50004";
932
+ };
933
+ readonly dev: {
934
+ readonly name: "Development";
935
+ readonly aggregatorUrl: "https://dev-aggregator.dyndns.org/rpc";
936
+ readonly nostrRelays: readonly ["wss://nostr-relay.testnet.unicity.network"];
937
+ readonly ipfsGateways: readonly ["https://ipfs.unicity.network", "https://dweb.link", "https://ipfs.io"];
938
+ readonly electrumUrl: "wss://fulcrum.alpha.testnet.unicity.network:50004";
939
+ };
940
+ };
941
+ type NetworkType = keyof typeof NETWORKS;
942
+
943
+ /**
944
+ * Shared Configuration Interfaces
945
+ * Base types extended by platform-specific implementations
946
+ */
947
+
948
+ /**
949
+ * Base transport (Nostr) configuration
950
+ * Supports extend/override pattern for relays
951
+ */
952
+ interface BaseTransportConfig {
953
+ /** Replace default relays entirely */
954
+ relays?: string[];
955
+ /** Add relays to network defaults (use with network preset) */
956
+ additionalRelays?: string[];
957
+ /** Connection timeout (ms) */
958
+ timeout?: number;
959
+ /** Auto-reconnect on disconnect */
960
+ autoReconnect?: boolean;
961
+ /** Enable debug logging */
962
+ debug?: boolean;
963
+ }
964
+ /**
965
+ * Base oracle (Aggregator) configuration
966
+ */
967
+ interface BaseOracleConfig {
968
+ /** Replace default aggregator URL (if not set, uses network default) */
969
+ url?: string;
970
+ /** API key for authentication */
971
+ apiKey?: string;
972
+ /** Request timeout (ms) */
973
+ timeout?: number;
974
+ /** Skip trust base verification (dev only) */
975
+ skipVerification?: boolean;
976
+ /** Enable debug logging */
977
+ debug?: boolean;
978
+ }
979
+ /**
980
+ * Node.js-specific oracle extensions
981
+ */
982
+ interface NodeOracleExtensions {
983
+ /** Path to trust base JSON file */
984
+ trustBasePath?: string;
985
+ }
986
+ /**
987
+ * L1 (ALPHA blockchain) configuration
988
+ * Same for all platforms
989
+ */
990
+ interface L1Config {
991
+ /** Fulcrum WebSocket URL (if not set, uses network default) */
992
+ electrumUrl?: string;
993
+ /** Default fee rate in sat/byte */
994
+ defaultFeeRate?: number;
995
+ /** Enable vesting classification */
996
+ enableVesting?: boolean;
997
+ }
998
+ /**
999
+ * Base providers result
1000
+ * Common structure for all platforms
1001
+ */
1002
+ interface BaseProviders {
1003
+ storage: StorageProvider;
1004
+ tokenStorage: TokenStorageProvider<TxfStorageDataBase>;
1005
+ transport: TransportProvider;
1006
+ oracle: OracleProvider;
1007
+ /** L1 configuration (for passing to Sphere.init) */
1008
+ l1?: L1Config;
1009
+ }
1010
+
1011
+ /**
1012
+ * Node.js Implementation
1013
+ * Providers for CLI/Node.js usage
1014
+ */
1015
+
1016
+ /**
1017
+ * Node.js transport configuration
1018
+ * Same as base (no Node.js-specific extensions)
1019
+ */
1020
+ type NodeTransportConfig = BaseTransportConfig;
1021
+ /**
1022
+ * Node.js oracle configuration
1023
+ * Extends base with trustBasePath for file-based trust base
1024
+ */
1025
+ type NodeOracleConfig = BaseOracleConfig & NodeOracleExtensions;
1026
+ /**
1027
+ * Node.js L1 configuration
1028
+ * Same as base
1029
+ */
1030
+ type NodeL1Config = L1Config;
1031
+ interface NodeProvidersConfig {
1032
+ /** Network preset: mainnet, testnet, or dev */
1033
+ network?: NetworkType;
1034
+ /** Directory for wallet data storage */
1035
+ dataDir?: string;
1036
+ /** Directory for token files */
1037
+ tokensDir?: string;
1038
+ /** Transport (Nostr) configuration */
1039
+ transport?: NodeTransportConfig;
1040
+ /** Oracle (Aggregator) configuration */
1041
+ oracle?: NodeOracleConfig;
1042
+ /** L1 (ALPHA blockchain) configuration */
1043
+ l1?: NodeL1Config;
1044
+ }
1045
+ interface NodeProviders {
1046
+ storage: StorageProvider;
1047
+ tokenStorage: TokenStorageProvider<TxfStorageDataBase>;
1048
+ transport: TransportProvider;
1049
+ oracle: OracleProvider;
1050
+ /** L1 configuration (for passing to Sphere.init) */
1051
+ l1?: L1Config;
1052
+ }
1053
+ /**
1054
+ * Create all Node.js providers with default configuration
1055
+ *
1056
+ * @example
1057
+ * ```ts
1058
+ * // Simple - testnet with defaults
1059
+ * const providers = createNodeProviders({
1060
+ * network: 'testnet',
1061
+ * tokensDir: './tokens',
1062
+ * });
1063
+ *
1064
+ * // Full configuration
1065
+ * const providers = createNodeProviders({
1066
+ * network: 'testnet',
1067
+ * dataDir: './wallet-data',
1068
+ * tokensDir: './tokens',
1069
+ * transport: {
1070
+ * additionalRelays: ['wss://my-relay.com'],
1071
+ * debug: true,
1072
+ * },
1073
+ * oracle: {
1074
+ * apiKey: 'my-api-key',
1075
+ * trustBasePath: './trustbase.json',
1076
+ * },
1077
+ * l1: {
1078
+ * enableVesting: true,
1079
+ * },
1080
+ * });
1081
+ *
1082
+ * // Use with Sphere.init
1083
+ * const { sphere } = await Sphere.init({
1084
+ * ...providers,
1085
+ * autoGenerate: true,
1086
+ * });
1087
+ * ```
1088
+ */
1089
+ declare function createNodeProviders(config?: NodeProvidersConfig): NodeProviders;
1090
+
1091
+ export { type BaseOracleConfig, type BaseProviders, type BaseTransportConfig, FileStorageProvider, type FileStorageProviderConfig, type FileTokenStorageConfig, FileTokenStorageProvider, type IWebSocket, type L1Config, type NodeL1Config, type NodeOracleConfig, type NodeProviders, type NodeProvidersConfig, type NodeTransportConfig, NodeTrustBaseLoader, NostrTransportProvider, type NostrTransportProviderConfig, type TrustBaseLoader, UnicityAggregatorProvider, type UnicityAggregatorProviderConfig, UnicityOracleProvider, type UnicityOracleProviderConfig, type WebSocketFactory, createFileStorageProvider, createFileTokenStorageProvider, createNodeProviders, createNodeTrustBaseLoader, createNodeWebSocketFactory, createNostrTransportProvider, createUnicityAggregatorProvider, createUnicityOracleProvider };