@unicitylabs/sphere-sdk 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -17,8 +17,8 @@ import { MintTransactionData } from '@unicitylabs/state-transition-sdk/lib/trans
17
17
  import { MintCommitment } from '@unicitylabs/state-transition-sdk/lib/transaction/MintCommitment';
18
18
  import { TransferTransaction } from '@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction';
19
19
  import { SigningService } from '@unicitylabs/state-transition-sdk/lib/sign/SigningService';
20
- import { ProxyAddress } from '@unicitylabs/state-transition-sdk/lib/address/ProxyAddress';
21
20
  import { AddressScheme } from '@unicitylabs/state-transition-sdk/lib/address/AddressScheme';
21
+ import { hashNametag } from '@unicitylabs/nostr-js-sdk';
22
22
 
23
23
  /**
24
24
  * Cryptographic utilities for SDK2
@@ -407,11 +407,12 @@ interface BaseProvider extends ProviderMetadata {
407
407
  getStatus(): ProviderStatus;
408
408
  }
409
409
  interface Identity {
410
- readonly publicKey: string;
410
+ /** 33-byte compressed secp256k1 public key (for L3 chain) */
411
+ readonly chainPubkey: string;
411
412
  /** L1 address (alpha1...) */
412
- readonly address: string;
413
- /** L3 predicate address (DIRECT://...) */
414
- readonly predicateAddress?: string;
413
+ readonly l1Address: string;
414
+ /** L3 DIRECT address (DIRECT://...) */
415
+ readonly directAddress?: string;
415
416
  readonly ipnsName?: string;
416
417
  readonly nametag?: string;
417
418
  }
@@ -429,6 +430,8 @@ interface Token {
429
430
  readonly coinId: string;
430
431
  readonly symbol: string;
431
432
  readonly name: string;
433
+ readonly decimals: number;
434
+ readonly iconUrl?: string;
432
435
  readonly amount: string;
433
436
  status: TokenStatus;
434
437
  readonly createdAt: number;
@@ -601,7 +604,7 @@ interface BroadcastMessage {
601
604
  readonly timestamp: number;
602
605
  readonly tags?: string[];
603
606
  }
604
- 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' | 'identity:changed';
607
+ 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';
605
608
  interface SphereEventMap {
606
609
  'transfer:incoming': IncomingTransfer;
607
610
  'transfer:confirmed': TransferResult;
@@ -639,10 +642,13 @@ interface SphereEventMap {
639
642
  nametag: string;
640
643
  addressIndex: number;
641
644
  };
645
+ 'nametag:recovered': {
646
+ nametag: string;
647
+ };
642
648
  'identity:changed': {
643
- address: string;
644
- predicateAddress?: string;
645
- publicKey: string;
649
+ l1Address: string;
650
+ directAddress?: string;
651
+ chainPubkey: string;
646
652
  nametag?: string;
647
653
  addressIndex: number;
648
654
  };
@@ -748,6 +754,253 @@ interface WalletJSONExportOptions$1 {
748
754
  addressCount?: number;
749
755
  }
750
756
 
757
+ /**
758
+ * Transport Provider Interface
759
+ * Platform-independent P2P messaging abstraction
760
+ */
761
+
762
+ /**
763
+ * P2P messaging transport provider
764
+ */
765
+ interface TransportProvider extends BaseProvider {
766
+ /**
767
+ * Set identity for signing/encryption
768
+ */
769
+ setIdentity(identity: FullIdentity): void;
770
+ /**
771
+ * Send encrypted direct message
772
+ * @param recipientTransportPubkey - Transport-specific pubkey for messaging
773
+ * @returns Event ID
774
+ */
775
+ sendMessage(recipientTransportPubkey: string, content: string): Promise<string>;
776
+ /**
777
+ * Subscribe to incoming direct messages
778
+ * @returns Unsubscribe function
779
+ */
780
+ onMessage(handler: MessageHandler): () => void;
781
+ /**
782
+ * Send token transfer payload
783
+ * @param recipientTransportPubkey - Transport-specific pubkey for messaging
784
+ * @returns Event ID
785
+ */
786
+ sendTokenTransfer(recipientTransportPubkey: string, payload: TokenTransferPayload): Promise<string>;
787
+ /**
788
+ * Subscribe to incoming token transfers
789
+ * @returns Unsubscribe function
790
+ */
791
+ onTokenTransfer(handler: TokenTransferHandler): () => void;
792
+ /**
793
+ * Resolve nametag to public key
794
+ */
795
+ resolveNametag?(nametag: string): Promise<string | null>;
796
+ /**
797
+ * Resolve nametag to full address information
798
+ * Returns transportPubkey, chainPubkey, l1Address, directAddress, proxyAddress
799
+ */
800
+ resolveNametagInfo?(nametag: string): Promise<NametagInfo | null>;
801
+ /**
802
+ * Recover nametag for current identity by decrypting stored encrypted nametag
803
+ * Used after wallet import to recover associated nametag
804
+ * @returns Decrypted nametag or null if none found
805
+ */
806
+ recoverNametag?(): Promise<string | null>;
807
+ /**
808
+ * Register a nametag for this identity
809
+ * @param nametag - Nametag to register
810
+ * @param chainPubkey - 33-byte compressed secp256k1 public key (for L1/L3)
811
+ * @param directAddress - L3 DIRECT address (DIRECT://...)
812
+ * @returns true if successful, false if already taken
813
+ */
814
+ registerNametag?(nametag: string, chainPubkey: string, directAddress: string): Promise<boolean>;
815
+ /**
816
+ * Publish nametag binding
817
+ */
818
+ publishNametag?(nametag: string, address: string): Promise<void>;
819
+ /**
820
+ * Subscribe to broadcast messages (global/channel)
821
+ */
822
+ subscribeToBroadcast?(tags: string[], handler: BroadcastHandler): () => void;
823
+ /**
824
+ * Publish broadcast message
825
+ */
826
+ publishBroadcast?(content: string, tags?: string[]): Promise<string>;
827
+ /**
828
+ * Send payment request to a recipient
829
+ * @param recipientTransportPubkey - Transport-specific pubkey for messaging
830
+ * @returns Event ID
831
+ */
832
+ sendPaymentRequest?(recipientTransportPubkey: string, request: PaymentRequestPayload): Promise<string>;
833
+ /**
834
+ * Subscribe to incoming payment requests
835
+ * @returns Unsubscribe function
836
+ */
837
+ onPaymentRequest?(handler: PaymentRequestHandler): () => void;
838
+ /**
839
+ * Send response to a payment request
840
+ * @param recipientTransportPubkey - Transport-specific pubkey for messaging
841
+ * @returns Event ID
842
+ */
843
+ sendPaymentRequestResponse?(recipientTransportPubkey: string, response: PaymentRequestResponsePayload): Promise<string>;
844
+ /**
845
+ * Subscribe to incoming payment request responses
846
+ * @returns Unsubscribe function
847
+ */
848
+ onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
849
+ /**
850
+ * Get list of configured relay URLs
851
+ */
852
+ getRelays?(): string[];
853
+ /**
854
+ * Get list of currently connected relay URLs
855
+ */
856
+ getConnectedRelays?(): string[];
857
+ /**
858
+ * Add a relay dynamically
859
+ * @returns true if added successfully
860
+ */
861
+ addRelay?(relayUrl: string): Promise<boolean>;
862
+ /**
863
+ * Remove a relay dynamically
864
+ * @returns true if removed successfully
865
+ */
866
+ removeRelay?(relayUrl: string): Promise<boolean>;
867
+ /**
868
+ * Check if a relay is configured
869
+ */
870
+ hasRelay?(relayUrl: string): boolean;
871
+ /**
872
+ * Check if a relay is currently connected
873
+ */
874
+ isRelayConnected?(relayUrl: string): boolean;
875
+ }
876
+ interface IncomingMessage {
877
+ id: string;
878
+ /** Transport-specific pubkey of sender */
879
+ senderTransportPubkey: string;
880
+ /** Sender's nametag (if known from NIP-17 unwrap) */
881
+ senderNametag?: string;
882
+ content: string;
883
+ timestamp: number;
884
+ encrypted: boolean;
885
+ }
886
+ type MessageHandler = (message: IncomingMessage) => void;
887
+ interface TokenTransferPayload {
888
+ /** Serialized token data */
889
+ token: string;
890
+ /** Inclusion proof */
891
+ proof: unknown;
892
+ /** Optional memo */
893
+ memo?: string;
894
+ /** Sender info */
895
+ sender?: {
896
+ /** Transport-specific pubkey */
897
+ transportPubkey: string;
898
+ nametag?: string;
899
+ };
900
+ }
901
+ interface IncomingTokenTransfer {
902
+ id: string;
903
+ /** Transport-specific pubkey of sender */
904
+ senderTransportPubkey: string;
905
+ payload: TokenTransferPayload;
906
+ timestamp: number;
907
+ }
908
+ type TokenTransferHandler = (transfer: IncomingTokenTransfer) => void;
909
+ interface PaymentRequestPayload {
910
+ /** Amount requested (in smallest units) */
911
+ amount: string | bigint;
912
+ /** Coin/token type ID */
913
+ coinId: string;
914
+ /** Message/memo for recipient */
915
+ message?: string;
916
+ /** Recipient's nametag (who should pay) */
917
+ recipientNametag?: string;
918
+ /** Custom metadata */
919
+ metadata?: Record<string, unknown>;
920
+ }
921
+ interface IncomingPaymentRequest {
922
+ /** Event ID */
923
+ id: string;
924
+ /** Transport-specific pubkey of sender */
925
+ senderTransportPubkey: string;
926
+ /** Parsed request data */
927
+ request: {
928
+ requestId: string;
929
+ amount: string;
930
+ coinId: string;
931
+ message?: string;
932
+ recipientNametag?: string;
933
+ metadata?: Record<string, unknown>;
934
+ };
935
+ /** Timestamp */
936
+ timestamp: number;
937
+ }
938
+ type PaymentRequestHandler = (request: IncomingPaymentRequest) => void;
939
+ type PaymentRequestResponseType = 'accepted' | 'rejected' | 'paid';
940
+ interface PaymentRequestResponsePayload {
941
+ /** Original request ID */
942
+ requestId: string;
943
+ /** Response type */
944
+ responseType: PaymentRequestResponseType;
945
+ /** Optional message */
946
+ message?: string;
947
+ /** Transfer ID (if paid) */
948
+ transferId?: string;
949
+ }
950
+ interface IncomingPaymentRequestResponse {
951
+ /** Event ID */
952
+ id: string;
953
+ /** Transport-specific pubkey of responder */
954
+ responderTransportPubkey: string;
955
+ /** Parsed response data */
956
+ response: {
957
+ requestId: string;
958
+ responseType: PaymentRequestResponseType;
959
+ message?: string;
960
+ transferId?: string;
961
+ };
962
+ /** Timestamp */
963
+ timestamp: number;
964
+ }
965
+ type PaymentRequestResponseHandler = (response: IncomingPaymentRequestResponse) => void;
966
+ interface IncomingBroadcast {
967
+ id: string;
968
+ /** Transport-specific pubkey of author */
969
+ authorTransportPubkey: string;
970
+ content: string;
971
+ tags: string[];
972
+ timestamp: number;
973
+ }
974
+ type BroadcastHandler = (broadcast: IncomingBroadcast) => void;
975
+ type TransportEventType = 'transport:connected' | 'transport:disconnected' | 'transport:reconnecting' | 'transport:error' | 'transport:relay_added' | 'transport:relay_removed' | 'message:received' | 'message:sent' | 'transfer:received' | 'transfer:sent';
976
+ interface TransportEvent {
977
+ type: TransportEventType;
978
+ timestamp: number;
979
+ data?: unknown;
980
+ error?: string;
981
+ }
982
+ type TransportEventCallback = (event: TransportEvent) => void;
983
+ /**
984
+ * Full nametag address information
985
+ * Used for resolving nametag to all address formats
986
+ */
987
+ interface NametagInfo {
988
+ /** Nametag name (without @) */
989
+ nametag: string;
990
+ /** Transport-specific pubkey (for messaging/encryption) */
991
+ transportPubkey: string;
992
+ /** 33-byte compressed secp256k1 public key (for L3 chain) */
993
+ chainPubkey: string;
994
+ /** L1 address (alpha1...) */
995
+ l1Address: string;
996
+ /** L3 DIRECT address (DIRECT://...) */
997
+ directAddress: string;
998
+ /** L3 PROXY address derived from nametag hash (PROXY:...) */
999
+ proxyAddress: string;
1000
+ /** Event timestamp */
1001
+ timestamp: number;
1002
+ }
1003
+
751
1004
  /**
752
1005
  * L1 Payments Sub-Module
753
1006
  *
@@ -817,6 +1070,8 @@ interface L1PaymentsModuleDependencies {
817
1070
  identity: FullIdentity;
818
1071
  chainCode?: string;
819
1072
  addresses?: string[];
1073
+ /** Transport provider for nametag resolution (optional) */
1074
+ transport?: TransportProvider;
820
1075
  }
821
1076
  /**
822
1077
  * L1 Payments Module - Full Implementation
@@ -831,9 +1086,23 @@ declare class L1PaymentsModule$1 {
831
1086
  private _chainCode?;
832
1087
  private _addresses;
833
1088
  private _wallet?;
1089
+ private _transport?;
834
1090
  constructor(config?: L1PaymentsModuleConfig);
835
1091
  initialize(deps: L1PaymentsModuleDependencies): Promise<void>;
836
1092
  destroy(): void;
1093
+ /**
1094
+ * Check if a string looks like an L1 address (alpha1... or alphat1...)
1095
+ */
1096
+ private isL1Address;
1097
+ /**
1098
+ * Resolve recipient to L1 address
1099
+ * Supports: L1 address (alpha1...), nametag (with or without @)
1100
+ */
1101
+ private resolveL1Address;
1102
+ /**
1103
+ * Resolve nametag to L1 address using transport provider
1104
+ */
1105
+ private resolveNametagToL1Address;
837
1106
  send(request: L1SendRequest): Promise<L1SendResult>;
838
1107
  getBalance(): Promise<L1Balance>;
839
1108
  getUtxos(): Promise<L1Utxo[]>;
@@ -1043,209 +1312,6 @@ interface TxfInvalidEntry {
1043
1312
  detectedAt: number;
1044
1313
  }
1045
1314
 
1046
- /**
1047
- * Transport Provider Interface
1048
- * Platform-independent P2P messaging abstraction
1049
- */
1050
-
1051
- /**
1052
- * P2P messaging transport provider
1053
- */
1054
- interface TransportProvider extends BaseProvider {
1055
- /**
1056
- * Set identity for signing/encryption
1057
- */
1058
- setIdentity(identity: FullIdentity): void;
1059
- /**
1060
- * Send encrypted direct message
1061
- * @returns Event ID
1062
- */
1063
- sendMessage(recipientPubkey: string, content: string): Promise<string>;
1064
- /**
1065
- * Subscribe to incoming direct messages
1066
- * @returns Unsubscribe function
1067
- */
1068
- onMessage(handler: MessageHandler): () => void;
1069
- /**
1070
- * Send token transfer payload
1071
- * @returns Event ID
1072
- */
1073
- sendTokenTransfer(recipientPubkey: string, payload: TokenTransferPayload): Promise<string>;
1074
- /**
1075
- * Subscribe to incoming token transfers
1076
- * @returns Unsubscribe function
1077
- */
1078
- onTokenTransfer(handler: TokenTransferHandler): () => void;
1079
- /**
1080
- * Resolve nametag to public key
1081
- */
1082
- resolveNametag?(nametag: string): Promise<string | null>;
1083
- /**
1084
- * Register a nametag for this identity
1085
- * @returns true if successful, false if already taken
1086
- */
1087
- registerNametag?(nametag: string, publicKey: string): Promise<boolean>;
1088
- /**
1089
- * Publish nametag binding
1090
- */
1091
- publishNametag?(nametag: string, address: string): Promise<void>;
1092
- /**
1093
- * Subscribe to broadcast messages (global/channel)
1094
- */
1095
- subscribeToBroadcast?(tags: string[], handler: BroadcastHandler): () => void;
1096
- /**
1097
- * Publish broadcast message
1098
- */
1099
- publishBroadcast?(content: string, tags?: string[]): Promise<string>;
1100
- /**
1101
- * Send payment request to a recipient
1102
- * @returns Event ID
1103
- */
1104
- sendPaymentRequest?(recipientPubkey: string, request: PaymentRequestPayload): Promise<string>;
1105
- /**
1106
- * Subscribe to incoming payment requests
1107
- * @returns Unsubscribe function
1108
- */
1109
- onPaymentRequest?(handler: PaymentRequestHandler): () => void;
1110
- /**
1111
- * Send response to a payment request
1112
- * @returns Event ID
1113
- */
1114
- sendPaymentRequestResponse?(recipientPubkey: string, response: PaymentRequestResponsePayload): Promise<string>;
1115
- /**
1116
- * Subscribe to incoming payment request responses
1117
- * @returns Unsubscribe function
1118
- */
1119
- onPaymentRequestResponse?(handler: PaymentRequestResponseHandler): () => void;
1120
- /**
1121
- * Get list of configured relay URLs
1122
- */
1123
- getRelays?(): string[];
1124
- /**
1125
- * Get list of currently connected relay URLs
1126
- */
1127
- getConnectedRelays?(): string[];
1128
- /**
1129
- * Add a relay dynamically
1130
- * @returns true if added successfully
1131
- */
1132
- addRelay?(relayUrl: string): Promise<boolean>;
1133
- /**
1134
- * Remove a relay dynamically
1135
- * @returns true if removed successfully
1136
- */
1137
- removeRelay?(relayUrl: string): Promise<boolean>;
1138
- /**
1139
- * Check if a relay is configured
1140
- */
1141
- hasRelay?(relayUrl: string): boolean;
1142
- /**
1143
- * Check if a relay is currently connected
1144
- */
1145
- isRelayConnected?(relayUrl: string): boolean;
1146
- }
1147
- interface IncomingMessage {
1148
- id: string;
1149
- senderPubkey: string;
1150
- content: string;
1151
- timestamp: number;
1152
- encrypted: boolean;
1153
- }
1154
- type MessageHandler = (message: IncomingMessage) => void;
1155
- interface TokenTransferPayload {
1156
- /** Serialized token data */
1157
- token: string;
1158
- /** Inclusion proof */
1159
- proof: unknown;
1160
- /** Optional memo */
1161
- memo?: string;
1162
- /** Sender info */
1163
- sender?: {
1164
- pubkey: string;
1165
- nametag?: string;
1166
- };
1167
- }
1168
- interface IncomingTokenTransfer {
1169
- id: string;
1170
- senderPubkey: string;
1171
- payload: TokenTransferPayload;
1172
- timestamp: number;
1173
- }
1174
- type TokenTransferHandler = (transfer: IncomingTokenTransfer) => void;
1175
- interface PaymentRequestPayload {
1176
- /** Amount requested (in smallest units) */
1177
- amount: string | bigint;
1178
- /** Coin/token type ID */
1179
- coinId: string;
1180
- /** Message/memo for recipient */
1181
- message?: string;
1182
- /** Recipient's nametag (who should pay) */
1183
- recipientNametag?: string;
1184
- /** Custom metadata */
1185
- metadata?: Record<string, unknown>;
1186
- }
1187
- interface IncomingPaymentRequest {
1188
- /** Event ID */
1189
- id: string;
1190
- /** Sender's public key */
1191
- senderPubkey: string;
1192
- /** Parsed request data */
1193
- request: {
1194
- requestId: string;
1195
- amount: string;
1196
- coinId: string;
1197
- message?: string;
1198
- recipientNametag?: string;
1199
- metadata?: Record<string, unknown>;
1200
- };
1201
- /** Timestamp */
1202
- timestamp: number;
1203
- }
1204
- type PaymentRequestHandler = (request: IncomingPaymentRequest) => void;
1205
- type PaymentRequestResponseType = 'accepted' | 'rejected' | 'paid';
1206
- interface PaymentRequestResponsePayload {
1207
- /** Original request ID */
1208
- requestId: string;
1209
- /** Response type */
1210
- responseType: PaymentRequestResponseType;
1211
- /** Optional message */
1212
- message?: string;
1213
- /** Transfer ID (if paid) */
1214
- transferId?: string;
1215
- }
1216
- interface IncomingPaymentRequestResponse {
1217
- /** Event ID */
1218
- id: string;
1219
- /** Responder's public key */
1220
- responderPubkey: string;
1221
- /** Parsed response data */
1222
- response: {
1223
- requestId: string;
1224
- responseType: PaymentRequestResponseType;
1225
- message?: string;
1226
- transferId?: string;
1227
- };
1228
- /** Timestamp */
1229
- timestamp: number;
1230
- }
1231
- type PaymentRequestResponseHandler = (response: IncomingPaymentRequestResponse) => void;
1232
- interface IncomingBroadcast {
1233
- id: string;
1234
- authorPubkey: string;
1235
- content: string;
1236
- tags: string[];
1237
- timestamp: number;
1238
- }
1239
- type BroadcastHandler = (broadcast: IncomingBroadcast) => void;
1240
- type TransportEventType = 'transport:connected' | 'transport:disconnected' | 'transport:reconnecting' | 'transport:error' | 'transport:relay_added' | 'transport:relay_removed' | 'message:received' | 'message:sent' | 'transfer:received' | 'transfer:sent';
1241
- interface TransportEvent {
1242
- type: TransportEventType;
1243
- timestamp: number;
1244
- data?: unknown;
1245
- error?: string;
1246
- }
1247
- type TransportEventCallback = (event: TransportEvent) => void;
1248
-
1249
1315
  /**
1250
1316
  * Oracle Provider Interface
1251
1317
  * Platform-independent Unicity oracle abstraction
@@ -1491,6 +1557,14 @@ declare class PaymentsModule$1 {
1491
1557
  * Get coin name from coinId
1492
1558
  */
1493
1559
  private getCoinName;
1560
+ /**
1561
+ * Get coin decimals from coinId
1562
+ */
1563
+ private getCoinDecimals;
1564
+ /**
1565
+ * Get coin icon URL from coinId
1566
+ */
1567
+ private getCoinIconUrl;
1494
1568
  /**
1495
1569
  * Send a payment request to someone
1496
1570
  * @param recipientPubkeyOrNametag - Recipient's pubkey or @nametag
@@ -1743,6 +1817,15 @@ declare class PaymentsModule$1 {
1743
1817
  * Get pending transfers
1744
1818
  */
1745
1819
  getPendingTransfers(): TransferResult[];
1820
+ /**
1821
+ * Detect if a string is an L3 address (not a nametag)
1822
+ * Returns true for: hex pubkeys (64+ chars), PROXY:, DIRECT: prefixed addresses
1823
+ */
1824
+ private isL3Address;
1825
+ /**
1826
+ * Resolve recipient to Nostr pubkey for messaging
1827
+ * Supports: nametag (with or without @), hex pubkey
1828
+ */
1746
1829
  private resolveRecipient;
1747
1830
  /**
1748
1831
  * Create SDK TransferCommitment for a token transfer
@@ -1753,7 +1836,17 @@ declare class PaymentsModule$1 {
1753
1836
  */
1754
1837
  private createSigningService;
1755
1838
  /**
1756
- * Resolve recipient to IAddress
1839
+ * Create DirectAddress from a public key using UnmaskedPredicateReference
1840
+ */
1841
+ private createDirectAddressFromPubkey;
1842
+ /**
1843
+ * Resolve nametag to 33-byte compressed public key using resolveNametagInfo
1844
+ * Returns null if nametag not found or publicKey not available
1845
+ */
1846
+ private resolveNametagToPublicKey;
1847
+ /**
1848
+ * Resolve recipient to IAddress for L3 transfers
1849
+ * Supports: nametag (with or without @), PROXY:, DIRECT:, hex pubkey
1757
1850
  */
1758
1851
  private resolveRecipientAddress;
1759
1852
  private handleIncomingTransfer;
@@ -1863,49 +1956,39 @@ declare function createCommunicationsModule$1(config?: CommunicationsModuleConfi
1863
1956
  * Default configuration values and storage keys
1864
1957
  */
1865
1958
  /** Default prefix for all storage keys */
1866
- declare const STORAGE_PREFIX$1: "sphere_";
1867
- /** Storage keys for wallet data */
1868
- declare const STORAGE_KEYS$1: {
1959
+ declare const STORAGE_PREFIX: "sphere_";
1960
+ /** @deprecated Use STORAGE_KEYS_GLOBAL and STORAGE_KEYS_ADDRESS instead */
1961
+ declare const STORAGE_KEYS: {
1962
+ /** Pending transfers for this address */
1963
+ readonly PENDING_TRANSFERS: "pending_transfers";
1964
+ /** Transfer outbox for this address */
1965
+ readonly OUTBOX: "outbox";
1966
+ /** Conversations for this address */
1967
+ readonly CONVERSATIONS: "conversations";
1968
+ /** Messages for this address */
1969
+ readonly MESSAGES: "messages";
1970
+ /** Transaction history for this address */
1971
+ readonly TRANSACTION_HISTORY: "transaction_history";
1869
1972
  /** Encrypted BIP39 mnemonic */
1870
- readonly MNEMONIC: "sphere_mnemonic";
1973
+ readonly MNEMONIC: "mnemonic";
1871
1974
  /** Encrypted master private key */
1872
- readonly MASTER_KEY: "sphere_master_key";
1975
+ readonly MASTER_KEY: "master_key";
1873
1976
  /** BIP32 chain code */
1874
- readonly CHAIN_CODE: "sphere_chain_code";
1977
+ readonly CHAIN_CODE: "chain_code";
1875
1978
  /** HD derivation path (full path like m/44'/0'/0'/0/0) */
1876
- readonly DERIVATION_PATH: "sphere_derivation_path";
1979
+ readonly DERIVATION_PATH: "derivation_path";
1877
1980
  /** Base derivation path (like m/44'/0'/0' without chain/index) */
1878
- readonly BASE_PATH: "sphere_base_path";
1981
+ readonly BASE_PATH: "base_path";
1879
1982
  /** Derivation mode: bip32, wif_hmac, legacy_hmac */
1880
- readonly DERIVATION_MODE: "sphere_derivation_mode";
1983
+ readonly DERIVATION_MODE: "derivation_mode";
1881
1984
  /** Wallet source: mnemonic, file, unknown */
1882
- readonly WALLET_SOURCE: "sphere_wallet_source";
1985
+ readonly WALLET_SOURCE: "wallet_source";
1883
1986
  /** Wallet existence flag */
1884
- readonly WALLET_EXISTS: "sphere_wallet_exists";
1885
- /** Registered nametag (legacy - single address) */
1886
- readonly NAMETAG: "sphere_nametag";
1987
+ readonly WALLET_EXISTS: "wallet_exists";
1887
1988
  /** Current active address index */
1888
- readonly CURRENT_ADDRESS_INDEX: "sphere_current_address_index";
1889
- /** Address nametags map (JSON: { "0": "alice", "1": "bob" }) */
1890
- readonly ADDRESS_NAMETAGS: "sphere_address_nametags";
1891
- /** Token data */
1892
- readonly TOKENS: "sphere_tokens";
1893
- /** Pending transfers */
1894
- readonly PENDING_TRANSFERS: "sphere_pending_transfers";
1895
- /** Transfer outbox */
1896
- readonly OUTBOX: "sphere_outbox";
1897
- /** Conversations */
1898
- readonly CONVERSATIONS: "sphere_conversations";
1899
- /** Messages */
1900
- readonly MESSAGES: "sphere_messages";
1901
- /** Transaction history */
1902
- readonly TRANSACTION_HISTORY: "sphere_transaction_history";
1903
- /** Archived tokens (spent token history) */
1904
- readonly ARCHIVED_TOKENS: "sphere_archived_tokens";
1905
- /** Tombstones (records of deleted/spent tokens) */
1906
- readonly TOMBSTONES: "sphere_tombstones";
1907
- /** Forked tokens (alternative histories) */
1908
- readonly FORKED_TOKENS: "sphere_forked_tokens";
1989
+ readonly CURRENT_ADDRESS_INDEX: "current_address_index";
1990
+ /** Index of address nametags (JSON: { "0": "alice", "1": "bob" }) - for discovery */
1991
+ readonly ADDRESS_NAMETAGS: "address_nametags";
1909
1992
  };
1910
1993
  /** Default Nostr relays */
1911
1994
  declare const DEFAULT_NOSTR_RELAYS: readonly ["wss://relay.unicity.network", "wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
@@ -1941,7 +2024,7 @@ declare const DEFAULT_IPFS_GATEWAYS: readonly ["https://ipfs.unicity.network", "
1941
2024
  /** Unicity IPFS bootstrap peers */
1942
2025
  declare const DEFAULT_IPFS_BOOTSTRAP_PEERS: readonly ["/dns4/unicity-ipfs2.dyndns.org/tcp/4001/p2p/12D3KooWLNi5NDPPHbrfJakAQqwBqymYTTwMQXQKEWuCrJNDdmfh", "/dns4/unicity-ipfs3.dyndns.org/tcp/4001/p2p/12D3KooWQ4aujVE4ShLjdusNZBdffq3TbzrwT2DuWZY9H1Gxhwn6", "/dns4/unicity-ipfs4.dyndns.org/tcp/4001/p2p/12D3KooWJ1ByPfUzUrpYvgxKU8NZrR8i6PU1tUgMEbQX9Hh2DEn1", "/dns4/unicity-ipfs5.dyndns.org/tcp/4001/p2p/12D3KooWB1MdZZGHN5B8TvWXntbycfe7Cjcz7n6eZ9eykZadvmDv"];
1943
2026
  /** Default BIP32 derivation path (full path with chain/index) */
1944
- declare const DEFAULT_DERIVATION_PATH$1: "m/44'/0'/0'/0/0";
2027
+ declare const DEFAULT_DERIVATION_PATH: "m/44'/0'/0'/0/0";
1945
2028
  /** Coin types */
1946
2029
  declare const COIN_TYPES: {
1947
2030
  /** ALPHA token (L1 blockchain) */
@@ -2191,6 +2274,7 @@ declare class Sphere$1 {
2191
2274
  private _derivationMode;
2192
2275
  private _basePath;
2193
2276
  private _currentAddressIndex;
2277
+ /** Map of addressId -> (nametagIndex -> nametag). Supports multiple nametags per address (e.g., from Nostr recovery) */
2194
2278
  private _addressNametags;
2195
2279
  private _storage;
2196
2280
  private _tokenStorageProviders;
@@ -2244,6 +2328,7 @@ declare class Sphere$1 {
2244
2328
  static import(options: SphereImportOptions): Promise<Sphere$1>;
2245
2329
  /**
2246
2330
  * Clear wallet data from storage
2331
+ * Note: Token data is cleared via TokenStorageProvider, not here
2247
2332
  */
2248
2333
  static clear(storage: StorageProvider): Promise<void>;
2249
2334
  /**
@@ -2462,18 +2547,29 @@ declare class Sphere$1 {
2462
2547
  */
2463
2548
  getCurrentAddressIndex(): number;
2464
2549
  /**
2465
- * Get nametag for a specific address index
2550
+ * Get primary nametag for a specific address
2551
+ *
2552
+ * @param addressId - Address identifier (DIRECT://xxx), defaults to current address
2553
+ * @returns Primary nametag (index 0) or undefined if not registered
2554
+ */
2555
+ getNametagForAddress(addressId?: string): string | undefined;
2556
+ /**
2557
+ * Get all nametags for a specific address
2466
2558
  *
2467
- * @param index - Address index (default: current address)
2468
- * @returns Nametag or undefined if not registered
2559
+ * @param addressId - Address identifier (DIRECT://xxx), defaults to current address
2560
+ * @returns Map of nametagIndex to nametag, or undefined if no nametags
2469
2561
  */
2470
- getNametagForAddress(index?: number): string | undefined;
2562
+ getNametagsForAddress(addressId?: string): Map<number, string> | undefined;
2471
2563
  /**
2472
2564
  * Get all registered address nametags
2473
2565
  *
2474
- * @returns Map of address index to nametag
2566
+ * @returns Map of addressId to (nametagIndex -> nametag)
2475
2567
  */
2476
- getAllAddressNametags(): Map<number, string>;
2568
+ getAllAddressNametags(): Map<string, Map<number, string>>;
2569
+ /**
2570
+ * Get current address identifier (DIRECT://xxx format)
2571
+ */
2572
+ private getCurrentAddressId;
2477
2573
  /**
2478
2574
  * Switch to a different address by index
2479
2575
  * This changes the active identity to the derived address at the specified index.
@@ -2571,6 +2667,13 @@ declare class Sphere$1 {
2571
2667
  * Check if nametag is registered
2572
2668
  */
2573
2669
  hasNametag(): boolean;
2670
+ /**
2671
+ * Get the PROXY address for the current nametag
2672
+ * PROXY addresses are derived from the nametag hash and require
2673
+ * the nametag token to claim funds sent to them
2674
+ * @returns PROXY address string or undefined if no nametag
2675
+ */
2676
+ getProxyAddress(): string | undefined;
2574
2677
  /**
2575
2678
  * Register a nametag for the current active address
2576
2679
  * Each address can have its own independent nametag
@@ -2592,6 +2695,7 @@ declare class Sphere$1 {
2592
2695
  registerNametag(nametag: string): Promise<void>;
2593
2696
  /**
2594
2697
  * Persist address nametags to storage
2698
+ * Format: { "DIRECT://abc...xyz": { "0": "alice", "1": "alice2" }, ... }
2595
2699
  */
2596
2700
  private persistAddressNametags;
2597
2701
  /**
@@ -2621,6 +2725,8 @@ declare class Sphere$1 {
2621
2725
  isNametagAvailable(nametag: string): Promise<boolean>;
2622
2726
  /**
2623
2727
  * Load address nametags from storage
2728
+ * Supports new format: { "DIRECT://abc...xyz": { "0": "alice" } }
2729
+ * And legacy format: { "0": "alice" } (migrates to new format on save)
2624
2730
  */
2625
2731
  private loadAddressNametags;
2626
2732
  /**
@@ -2628,6 +2734,12 @@ declare class Sphere$1 {
2628
2734
  * If local nametag exists but not registered on Nostr, re-register it
2629
2735
  */
2630
2736
  private syncNametagWithNostr;
2737
+ /**
2738
+ * Recover nametag from Nostr after wallet import
2739
+ * Searches for encrypted nametag events authored by this wallet's pubkey
2740
+ * and decrypts them to restore the nametag association
2741
+ */
2742
+ private recoverNametagFromNostr;
2631
2743
  /**
2632
2744
  * Validate nametag format
2633
2745
  */
@@ -4806,6 +4918,7 @@ var L1PaymentsModule = class {
4806
4918
  _chainCode;
4807
4919
  _addresses = [];
4808
4920
  _wallet;
4921
+ _transport;
4809
4922
  constructor(config) {
4810
4923
  this._config = {
4811
4924
  electrumUrl: config?.electrumUrl ?? "wss://fulcrum.alpha.unicity.network:50004",
@@ -4818,13 +4931,14 @@ var L1PaymentsModule = class {
4818
4931
  this._identity = deps.identity;
4819
4932
  this._chainCode = deps.chainCode;
4820
4933
  this._addresses = deps.addresses ?? [];
4934
+ this._transport = deps.transport;
4821
4935
  this._wallet = {
4822
4936
  masterPrivateKey: deps.identity.privateKey,
4823
4937
  chainCode: deps.chainCode,
4824
4938
  addresses: [
4825
4939
  {
4826
- address: deps.identity.address,
4827
- publicKey: deps.identity.publicKey,
4940
+ address: deps.identity.l1Address,
4941
+ publicKey: deps.identity.chainPubkey,
4828
4942
  privateKey: deps.identity.privateKey,
4829
4943
  path: "m/0",
4830
4944
  index: 0
@@ -4832,7 +4946,7 @@ var L1PaymentsModule = class {
4832
4946
  ]
4833
4947
  };
4834
4948
  for (const addr of this._addresses) {
4835
- if (addr !== deps.identity.address) {
4949
+ if (addr !== deps.identity.l1Address) {
4836
4950
  this._wallet.addresses.push({
4837
4951
  address: addr,
4838
4952
  path: null,
@@ -4855,18 +4969,64 @@ var L1PaymentsModule = class {
4855
4969
  this._addresses = [];
4856
4970
  this._wallet = void 0;
4857
4971
  }
4972
+ /**
4973
+ * Check if a string looks like an L1 address (alpha1... or alphat1...)
4974
+ */
4975
+ isL1Address(value) {
4976
+ return value.startsWith("alpha1") || value.startsWith("alphat1");
4977
+ }
4978
+ /**
4979
+ * Resolve recipient to L1 address
4980
+ * Supports: L1 address (alpha1...), nametag (with or without @)
4981
+ */
4982
+ async resolveL1Address(recipient) {
4983
+ if (recipient.startsWith("@")) {
4984
+ const nametag = recipient.slice(1);
4985
+ return this.resolveNametagToL1Address(nametag);
4986
+ }
4987
+ if (this.isL1Address(recipient)) {
4988
+ return recipient;
4989
+ }
4990
+ try {
4991
+ const l1Address = await this.resolveNametagToL1Address(recipient);
4992
+ return l1Address;
4993
+ } catch {
4994
+ throw new Error(
4995
+ `Recipient "${recipient}" is not a valid nametag or L1 address. Use @nametag for explicit nametag or a valid alpha1... address.`
4996
+ );
4997
+ }
4998
+ }
4999
+ /**
5000
+ * Resolve nametag to L1 address using transport provider
5001
+ */
5002
+ async resolveNametagToL1Address(nametag) {
5003
+ if (!this._transport?.resolveNametagInfo) {
5004
+ throw new Error("Transport provider does not support nametag resolution");
5005
+ }
5006
+ const info = await this._transport.resolveNametagInfo(nametag);
5007
+ if (!info) {
5008
+ throw new Error(`Nametag not found: ${nametag}`);
5009
+ }
5010
+ if (!info.l1Address) {
5011
+ throw new Error(
5012
+ `Nametag @${nametag} does not have L1 address information. The owner needs to update their nametag registration.`
5013
+ );
5014
+ }
5015
+ return info.l1Address;
5016
+ }
4858
5017
  async send(request) {
4859
5018
  this.ensureInitialized();
4860
5019
  if (!this._wallet || !this._identity) {
4861
5020
  return { success: false, error: "No wallet available" };
4862
5021
  }
4863
5022
  try {
5023
+ const recipientAddress = await this.resolveL1Address(request.to);
4864
5024
  const amountAlpha = parseInt(request.amount, 10) / 1e8;
4865
5025
  const results = await sendAlpha$1(
4866
5026
  this._wallet,
4867
- request.to,
5027
+ recipientAddress,
4868
5028
  amountAlpha,
4869
- this._identity.address
5029
+ this._identity.l1Address
4870
5030
  );
4871
5031
  if (results && results.length > 0) {
4872
5032
  const txids = results.map((r) => r.txid);
@@ -5088,8 +5248,8 @@ var L1PaymentsModule = class {
5088
5248
  }
5089
5249
  _getWatchedAddresses() {
5090
5250
  const addresses = [...this._addresses];
5091
- if (this._identity?.address && !addresses.includes(this._identity.address)) {
5092
- addresses.unshift(this._identity.address);
5251
+ if (this._identity?.l1Address && !addresses.includes(this._identity.l1Address)) {
5252
+ addresses.unshift(this._identity.l1Address);
5093
5253
  }
5094
5254
  return addresses;
5095
5255
  }
@@ -5531,54 +5691,49 @@ var NametagMinter = class {
5531
5691
  }
5532
5692
  }
5533
5693
  };
5534
-
5535
- // constants.ts
5536
- var STORAGE_PREFIX = "sphere_";
5537
5694
  var DEFAULT_ENCRYPTION_KEY = "sphere-default-key";
5538
- var STORAGE_KEYS = {
5695
+ var STORAGE_KEYS_GLOBAL = {
5539
5696
  /** Encrypted BIP39 mnemonic */
5540
- MNEMONIC: `${STORAGE_PREFIX}mnemonic`,
5697
+ MNEMONIC: "mnemonic",
5541
5698
  /** Encrypted master private key */
5542
- MASTER_KEY: `${STORAGE_PREFIX}master_key`,
5699
+ MASTER_KEY: "master_key",
5543
5700
  /** BIP32 chain code */
5544
- CHAIN_CODE: `${STORAGE_PREFIX}chain_code`,
5701
+ CHAIN_CODE: "chain_code",
5545
5702
  /** HD derivation path (full path like m/44'/0'/0'/0/0) */
5546
- DERIVATION_PATH: `${STORAGE_PREFIX}derivation_path`,
5703
+ DERIVATION_PATH: "derivation_path",
5547
5704
  /** Base derivation path (like m/44'/0'/0' without chain/index) */
5548
- BASE_PATH: `${STORAGE_PREFIX}base_path`,
5705
+ BASE_PATH: "base_path",
5549
5706
  /** Derivation mode: bip32, wif_hmac, legacy_hmac */
5550
- DERIVATION_MODE: `${STORAGE_PREFIX}derivation_mode`,
5707
+ DERIVATION_MODE: "derivation_mode",
5551
5708
  /** Wallet source: mnemonic, file, unknown */
5552
- WALLET_SOURCE: `${STORAGE_PREFIX}wallet_source`,
5709
+ WALLET_SOURCE: "wallet_source",
5553
5710
  /** Wallet existence flag */
5554
- WALLET_EXISTS: `${STORAGE_PREFIX}wallet_exists`,
5555
- /** Registered nametag (legacy - single address) */
5556
- NAMETAG: `${STORAGE_PREFIX}nametag`,
5711
+ WALLET_EXISTS: "wallet_exists",
5557
5712
  /** Current active address index */
5558
- CURRENT_ADDRESS_INDEX: `${STORAGE_PREFIX}current_address_index`,
5559
- /** Address nametags map (JSON: { "0": "alice", "1": "bob" }) */
5560
- ADDRESS_NAMETAGS: `${STORAGE_PREFIX}address_nametags`,
5561
- /** Token data */
5562
- TOKENS: `${STORAGE_PREFIX}tokens`,
5563
- /** Pending transfers */
5564
- PENDING_TRANSFERS: `${STORAGE_PREFIX}pending_transfers`,
5565
- /** Transfer outbox */
5566
- OUTBOX: `${STORAGE_PREFIX}outbox`,
5567
- /** Conversations */
5568
- CONVERSATIONS: `${STORAGE_PREFIX}conversations`,
5569
- /** Messages */
5570
- MESSAGES: `${STORAGE_PREFIX}messages`,
5571
- /** Transaction history */
5572
- TRANSACTION_HISTORY: `${STORAGE_PREFIX}transaction_history`,
5573
- /** Archived tokens (spent token history) */
5574
- ARCHIVED_TOKENS: `${STORAGE_PREFIX}archived_tokens`,
5575
- /** Tombstones (records of deleted/spent tokens) */
5576
- TOMBSTONES: `${STORAGE_PREFIX}tombstones`,
5577
- /** Forked tokens (alternative histories) */
5578
- FORKED_TOKENS: `${STORAGE_PREFIX}forked_tokens`
5713
+ CURRENT_ADDRESS_INDEX: "current_address_index",
5714
+ /** Index of address nametags (JSON: { "0": "alice", "1": "bob" }) - for discovery */
5715
+ ADDRESS_NAMETAGS: "address_nametags"
5579
5716
  };
5717
+ var STORAGE_KEYS_ADDRESS = {
5718
+ /** Pending transfers for this address */
5719
+ PENDING_TRANSFERS: "pending_transfers",
5720
+ /** Transfer outbox for this address */
5721
+ OUTBOX: "outbox",
5722
+ /** Transaction history for this address */
5723
+ TRANSACTION_HISTORY: "transaction_history"
5724
+ };
5725
+ function getAddressId(directAddress) {
5726
+ let hash = directAddress;
5727
+ if (hash.startsWith("DIRECT://")) {
5728
+ hash = hash.slice(9);
5729
+ } else if (hash.startsWith("DIRECT:")) {
5730
+ hash = hash.slice(7);
5731
+ }
5732
+ const first = hash.slice(0, 6).toLowerCase();
5733
+ const last = hash.slice(-6).toLowerCase();
5734
+ return `DIRECT_${first}_${last}`;
5735
+ }
5580
5736
  var DEFAULT_BASE_PATH = "m/44'/0'/0'";
5581
- var DEFAULT_DERIVATION_PATH = `${DEFAULT_BASE_PATH}/0/0`;
5582
5737
  var LIMITS = {
5583
5738
  /** Min nametag length */
5584
5739
  NAMETAG_MIN_LENGTH: 3,
@@ -5740,6 +5895,7 @@ function txfToToken(tokenId, txf) {
5740
5895
  coinId,
5741
5896
  symbol: isNft ? "NFT" : "UCT",
5742
5897
  name: isNft ? "NFT" : "Token",
5898
+ decimals: isNft ? 0 : 8,
5743
5899
  amount: totalAmount.toString(),
5744
5900
  status: determineTokenStatus(txf),
5745
5901
  createdAt: now,
@@ -5754,9 +5910,6 @@ async function buildTxfStorageData(tokens, meta, options) {
5754
5910
  formatVersion: "2.0"
5755
5911
  }
5756
5912
  };
5757
- if (options?.nametag) {
5758
- storageData._nametag = options.nametag;
5759
- }
5760
5913
  if (options?.tombstones && options.tombstones.length > 0) {
5761
5914
  storageData._tombstones = options.tombstones;
5762
5915
  }
@@ -5880,26 +6033,335 @@ function parseTxfStorageData(data) {
5880
6033
  }
5881
6034
  }
5882
6035
  }
5883
- return result;
5884
- }
5885
- function getCurrentStateHash(txf) {
5886
- if (txf.transactions && txf.transactions.length > 0) {
5887
- const lastTx = txf.transactions[txf.transactions.length - 1];
5888
- if (lastTx?.newStateHash) {
5889
- return lastTx.newStateHash;
6036
+ return result;
6037
+ }
6038
+ function getCurrentStateHash(txf) {
6039
+ if (txf.transactions && txf.transactions.length > 0) {
6040
+ const lastTx = txf.transactions[txf.transactions.length - 1];
6041
+ if (lastTx?.newStateHash) {
6042
+ return lastTx.newStateHash;
6043
+ }
6044
+ return void 0;
6045
+ }
6046
+ if (txf._integrity?.currentStateHash) {
6047
+ return txf._integrity.currentStateHash;
6048
+ }
6049
+ return void 0;
6050
+ }
6051
+
6052
+ // registry/token-registry.testnet.json
6053
+ var token_registry_testnet_default = [
6054
+ {
6055
+ network: "unicity:testnet",
6056
+ assetKind: "non-fungible",
6057
+ name: "unicity",
6058
+ description: "Unicity testnet token type",
6059
+ id: "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509"
6060
+ },
6061
+ {
6062
+ network: "unicity:testnet",
6063
+ assetKind: "fungible",
6064
+ name: "unicity",
6065
+ symbol: "UCT",
6066
+ decimals: 18,
6067
+ description: "Unicity testnet native coin",
6068
+ icons: [
6069
+ { url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/unicity_logo_32.png" }
6070
+ ],
6071
+ id: "455ad8720656b08e8dbd5bac1f3c73eeea5431565f6c1c3af742b1aa12d41d89"
6072
+ },
6073
+ {
6074
+ network: "unicity:testnet",
6075
+ assetKind: "fungible",
6076
+ name: "unicity-usd",
6077
+ symbol: "USDU",
6078
+ decimals: 6,
6079
+ description: "Unicity testnet USD stablecoin",
6080
+ icons: [
6081
+ { url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/usdu_logo_32.png" }
6082
+ ],
6083
+ id: "8f0f3d7a5e7297be0ee98c63b81bcebb2740f43f616566fc290f9823a54f52d7"
6084
+ },
6085
+ {
6086
+ network: "unicity:testnet",
6087
+ assetKind: "fungible",
6088
+ name: "unicity-eur",
6089
+ symbol: "EURU",
6090
+ decimals: 6,
6091
+ description: "Unicity testnet EUR stablecoin",
6092
+ icons: [
6093
+ { url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/euru_logo_32.png" }
6094
+ ],
6095
+ id: "5e160d5e9fdbb03b553fb9c3f6e6c30efa41fa807be39fb4f18e43776e492925"
6096
+ },
6097
+ {
6098
+ network: "unicity:testnet",
6099
+ assetKind: "fungible",
6100
+ name: "solana",
6101
+ symbol: "SOL",
6102
+ decimals: 9,
6103
+ description: "Solana testnet coin on Unicity",
6104
+ icons: [
6105
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/sol.svg" },
6106
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/sol.png" }
6107
+ ],
6108
+ id: "dee5f8ce778562eec90e9c38a91296a023210ccc76ff4c29d527ac3eb64ade93"
6109
+ },
6110
+ {
6111
+ network: "unicity:testnet",
6112
+ assetKind: "fungible",
6113
+ name: "bitcoin",
6114
+ symbol: "BTC",
6115
+ decimals: 8,
6116
+ description: "Bitcoin testnet coin on Unicity",
6117
+ icons: [
6118
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/btc.svg" },
6119
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/btc.png" }
6120
+ ],
6121
+ id: "86bc190fcf7b2d07c6078de93db803578760148b16d4431aa2f42a3241ff0daa"
6122
+ },
6123
+ {
6124
+ network: "unicity:testnet",
6125
+ assetKind: "fungible",
6126
+ name: "ethereum",
6127
+ symbol: "ETH",
6128
+ decimals: 18,
6129
+ description: "Ethereum testnet coin on Unicity",
6130
+ icons: [
6131
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/eth.svg" },
6132
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/eth.png" }
6133
+ ],
6134
+ id: "3c2450f2fd867e7bb60c6a69d7ad0e53ce967078c201a3ecaa6074ed4c0deafb"
6135
+ },
6136
+ {
6137
+ network: "unicity:testnet",
6138
+ assetKind: "fungible",
6139
+ name: "alpha_test",
6140
+ symbol: "ALPHT",
6141
+ decimals: 8,
6142
+ description: "ALPHA testnet coin on Unicity",
6143
+ icons: [
6144
+ { url: "https://raw.githubusercontent.com/unicitynetwork/unicity-ids/refs/heads/main/alpha_coin.png" }
6145
+ ],
6146
+ id: "cde78ded16ef65818a51f43138031c4284e519300ab0cb60c30a8f9078080e5f"
6147
+ },
6148
+ {
6149
+ network: "unicity:testnet",
6150
+ assetKind: "fungible",
6151
+ name: "tether",
6152
+ symbol: "USDT",
6153
+ decimals: 6,
6154
+ description: "Tether (Ethereum) testnet coin on Unicity",
6155
+ icons: [
6156
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdt.svg" },
6157
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdt.png" }
6158
+ ],
6159
+ id: "40d25444648418fe7efd433e147187a3a6adf049ac62bc46038bda5b960bf690"
6160
+ },
6161
+ {
6162
+ network: "unicity:testnet",
6163
+ assetKind: "fungible",
6164
+ name: "usd-coin",
6165
+ symbol: "USDC",
6166
+ decimals: 6,
6167
+ description: "USDC (Ethereum) testnet coin on Unicity",
6168
+ icons: [
6169
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/svg/icon/usdc.svg" },
6170
+ { url: "https://raw.githubusercontent.com/spothq/cryptocurrency-icons/master/32/icon/usdc.png" }
6171
+ ],
6172
+ id: "2265121770fa6f41131dd9a6cc571e28679263d09a53eb2642e145b5b9a5b0a2"
6173
+ }
6174
+ ];
6175
+
6176
+ // registry/TokenRegistry.ts
6177
+ var TokenRegistry$1 = class _TokenRegistry {
6178
+ static instance = null;
6179
+ definitionsById;
6180
+ definitionsBySymbol;
6181
+ definitionsByName;
6182
+ constructor() {
6183
+ this.definitionsById = /* @__PURE__ */ new Map();
6184
+ this.definitionsBySymbol = /* @__PURE__ */ new Map();
6185
+ this.definitionsByName = /* @__PURE__ */ new Map();
6186
+ this.loadRegistry();
6187
+ }
6188
+ /**
6189
+ * Get singleton instance of TokenRegistry
6190
+ */
6191
+ static getInstance() {
6192
+ if (!_TokenRegistry.instance) {
6193
+ _TokenRegistry.instance = new _TokenRegistry();
6194
+ }
6195
+ return _TokenRegistry.instance;
6196
+ }
6197
+ /**
6198
+ * Reset the singleton instance (useful for testing)
6199
+ */
6200
+ static resetInstance() {
6201
+ _TokenRegistry.instance = null;
6202
+ }
6203
+ /**
6204
+ * Load registry data from bundled JSON
6205
+ */
6206
+ loadRegistry() {
6207
+ const definitions = token_registry_testnet_default;
6208
+ for (const def of definitions) {
6209
+ const idLower = def.id.toLowerCase();
6210
+ this.definitionsById.set(idLower, def);
6211
+ if (def.symbol) {
6212
+ this.definitionsBySymbol.set(def.symbol.toUpperCase(), def);
6213
+ }
6214
+ this.definitionsByName.set(def.name.toLowerCase(), def);
6215
+ }
6216
+ }
6217
+ // ===========================================================================
6218
+ // Lookup Methods
6219
+ // ===========================================================================
6220
+ /**
6221
+ * Get token definition by hex coin ID
6222
+ * @param coinId - 64-character hex string
6223
+ * @returns Token definition or undefined if not found
6224
+ */
6225
+ getDefinition(coinId) {
6226
+ if (!coinId) return void 0;
6227
+ return this.definitionsById.get(coinId.toLowerCase());
6228
+ }
6229
+ /**
6230
+ * Get token definition by symbol (e.g., "UCT", "BTC")
6231
+ * @param symbol - Token symbol (case-insensitive)
6232
+ * @returns Token definition or undefined if not found
6233
+ */
6234
+ getDefinitionBySymbol(symbol) {
6235
+ if (!symbol) return void 0;
6236
+ return this.definitionsBySymbol.get(symbol.toUpperCase());
6237
+ }
6238
+ /**
6239
+ * Get token definition by name (e.g., "bitcoin", "ethereum")
6240
+ * @param name - Token name (case-insensitive)
6241
+ * @returns Token definition or undefined if not found
6242
+ */
6243
+ getDefinitionByName(name) {
6244
+ if (!name) return void 0;
6245
+ return this.definitionsByName.get(name.toLowerCase());
6246
+ }
6247
+ /**
6248
+ * Get token symbol for a coin ID
6249
+ * @param coinId - 64-character hex string
6250
+ * @returns Symbol (e.g., "UCT") or truncated ID if not found
6251
+ */
6252
+ getSymbol(coinId) {
6253
+ const def = this.getDefinition(coinId);
6254
+ if (def?.symbol) {
6255
+ return def.symbol;
6256
+ }
6257
+ return coinId.slice(0, 6).toUpperCase();
6258
+ }
6259
+ /**
6260
+ * Get token name for a coin ID
6261
+ * @param coinId - 64-character hex string
6262
+ * @returns Name (e.g., "Bitcoin") or coin ID if not found
6263
+ */
6264
+ getName(coinId) {
6265
+ const def = this.getDefinition(coinId);
6266
+ if (def?.name) {
6267
+ return def.name.charAt(0).toUpperCase() + def.name.slice(1);
5890
6268
  }
5891
- return void 0;
6269
+ return coinId;
5892
6270
  }
5893
- if (txf._integrity?.currentStateHash) {
5894
- return txf._integrity.currentStateHash;
6271
+ /**
6272
+ * Get decimal places for a coin ID
6273
+ * @param coinId - 64-character hex string
6274
+ * @returns Decimals or 0 if not found
6275
+ */
6276
+ getDecimals(coinId) {
6277
+ const def = this.getDefinition(coinId);
6278
+ return def?.decimals ?? 0;
5895
6279
  }
5896
- return void 0;
6280
+ /**
6281
+ * Get icon URL for a coin ID
6282
+ * @param coinId - 64-character hex string
6283
+ * @param preferPng - Prefer PNG format over SVG
6284
+ * @returns Icon URL or null if not found
6285
+ */
6286
+ getIconUrl(coinId, preferPng = true) {
6287
+ const def = this.getDefinition(coinId);
6288
+ if (!def?.icons || def.icons.length === 0) {
6289
+ return null;
6290
+ }
6291
+ if (preferPng) {
6292
+ const pngIcon = def.icons.find((i) => i.url.toLowerCase().includes(".png"));
6293
+ if (pngIcon) return pngIcon.url;
6294
+ }
6295
+ return def.icons[0].url;
6296
+ }
6297
+ /**
6298
+ * Check if a coin ID is known in the registry
6299
+ * @param coinId - 64-character hex string
6300
+ * @returns true if the coin is in the registry
6301
+ */
6302
+ isKnown(coinId) {
6303
+ return this.definitionsById.has(coinId.toLowerCase());
6304
+ }
6305
+ /**
6306
+ * Get all token definitions
6307
+ * @returns Array of all token definitions
6308
+ */
6309
+ getAllDefinitions() {
6310
+ return Array.from(this.definitionsById.values());
6311
+ }
6312
+ /**
6313
+ * Get all fungible token definitions
6314
+ * @returns Array of fungible token definitions
6315
+ */
6316
+ getFungibleTokens() {
6317
+ return this.getAllDefinitions().filter((def) => def.assetKind === "fungible");
6318
+ }
6319
+ /**
6320
+ * Get all non-fungible token definitions
6321
+ * @returns Array of non-fungible token definitions
6322
+ */
6323
+ getNonFungibleTokens() {
6324
+ return this.getAllDefinitions().filter((def) => def.assetKind === "non-fungible");
6325
+ }
6326
+ /**
6327
+ * Get coin ID by symbol
6328
+ * @param symbol - Token symbol (e.g., "UCT")
6329
+ * @returns Coin ID hex string or undefined if not found
6330
+ */
6331
+ getCoinIdBySymbol(symbol) {
6332
+ const def = this.getDefinitionBySymbol(symbol);
6333
+ return def?.id;
6334
+ }
6335
+ /**
6336
+ * Get coin ID by name
6337
+ * @param name - Token name (e.g., "bitcoin")
6338
+ * @returns Coin ID hex string or undefined if not found
6339
+ */
6340
+ getCoinIdByName(name) {
6341
+ const def = this.getDefinitionByName(name);
6342
+ return def?.id;
6343
+ }
6344
+ };
6345
+ function enrichWithRegistry(info) {
6346
+ const registry = TokenRegistry$1.getInstance();
6347
+ const def = registry.getDefinition(info.coinId);
6348
+ if (def) {
6349
+ return {
6350
+ ...info,
6351
+ symbol: def.symbol || info.symbol,
6352
+ name: def.name.charAt(0).toUpperCase() + def.name.slice(1),
6353
+ decimals: def.decimals ?? 0,
6354
+ iconUrl: registry.getIconUrl(info.coinId) ?? void 0
6355
+ };
6356
+ }
6357
+ return info;
5897
6358
  }
5898
6359
  async function parseTokenInfo(tokenData) {
5899
6360
  const defaultInfo = {
5900
6361
  coinId: "ALPHA",
5901
6362
  symbol: "ALPHA",
5902
6363
  name: "Alpha Token",
6364
+ decimals: 0,
5903
6365
  amount: "0"
5904
6366
  };
5905
6367
  try {
@@ -5920,23 +6382,25 @@ async function parseTokenInfo(tokenData) {
5920
6382
  }
5921
6383
  if (coinIdObj instanceof CoinId) {
5922
6384
  const coinIdHex = coinIdObj.toJSON();
5923
- return {
6385
+ return enrichWithRegistry({
5924
6386
  coinId: coinIdHex,
5925
6387
  symbol: coinIdHex.slice(0, 8),
5926
6388
  name: `Token ${coinIdHex.slice(0, 8)}`,
6389
+ decimals: 0,
5927
6390
  amount: String(amount ?? "0"),
5928
6391
  tokenId: defaultInfo.tokenId
5929
- };
6392
+ });
5930
6393
  } else if (coinIdObj && typeof coinIdObj === "object" && "bytes" in coinIdObj) {
5931
6394
  const bytes = coinIdObj.bytes;
5932
6395
  const coinIdHex = Buffer.isBuffer(bytes) ? bytes.toString("hex") : Array.isArray(bytes) ? Buffer.from(bytes).toString("hex") : String(bytes);
5933
- return {
6396
+ return enrichWithRegistry({
5934
6397
  coinId: coinIdHex,
5935
6398
  symbol: coinIdHex.slice(0, 8),
5936
6399
  name: `Token ${coinIdHex.slice(0, 8)}`,
6400
+ decimals: 0,
5937
6401
  amount: String(amount ?? "0"),
5938
6402
  tokenId: defaultInfo.tokenId
5939
- };
6403
+ });
5940
6404
  }
5941
6405
  }
5942
6406
  }
@@ -5951,13 +6415,14 @@ async function parseTokenInfo(tokenData) {
5951
6415
  if (Array.isArray(firstEntry) && firstEntry.length === 2) {
5952
6416
  const [coinIdHex, amount] = firstEntry;
5953
6417
  const coinIdStr = typeof coinIdHex === "string" ? coinIdHex : String(coinIdHex);
5954
- return {
6418
+ return enrichWithRegistry({
5955
6419
  coinId: coinIdStr,
5956
6420
  symbol: coinIdStr.slice(0, 8),
5957
6421
  name: `Token ${coinIdStr.slice(0, 8)}`,
6422
+ decimals: 0,
5958
6423
  amount: String(amount),
5959
6424
  tokenId: defaultInfo.tokenId
5960
- };
6425
+ });
5961
6426
  }
5962
6427
  }
5963
6428
  }
@@ -5972,25 +6437,27 @@ async function parseTokenInfo(tokenData) {
5972
6437
  const firstEntry = coinData[0];
5973
6438
  if (Array.isArray(firstEntry) && firstEntry.length === 2) {
5974
6439
  const [coinIdHex, amount] = firstEntry;
5975
- return {
6440
+ return enrichWithRegistry({
5976
6441
  coinId: String(coinIdHex),
5977
6442
  symbol: String(coinIdHex).slice(0, 8),
5978
6443
  name: `Token ${String(coinIdHex).slice(0, 8)}`,
6444
+ decimals: 0,
5979
6445
  amount: String(amount),
5980
6446
  tokenId: genesis.tokenId
5981
- };
6447
+ });
5982
6448
  }
5983
6449
  } else if (typeof coinData === "object") {
5984
6450
  const coinEntries = Object.entries(coinData);
5985
6451
  if (coinEntries.length > 0) {
5986
6452
  const [coinId, amount] = coinEntries[0];
5987
- return {
6453
+ return enrichWithRegistry({
5988
6454
  coinId,
5989
6455
  symbol: coinId.slice(0, 8),
5990
6456
  name: `Token ${coinId.slice(0, 8)}`,
6457
+ decimals: 0,
5991
6458
  amount: String(amount),
5992
6459
  tokenId: genesis.tokenId
5993
- };
6460
+ });
5994
6461
  }
5995
6462
  }
5996
6463
  }
@@ -6004,25 +6471,27 @@ async function parseTokenInfo(tokenData) {
6004
6471
  const firstEntry = coinData[0];
6005
6472
  if (Array.isArray(firstEntry) && firstEntry.length === 2) {
6006
6473
  const [coinIdHex, amount] = firstEntry;
6007
- return {
6474
+ return enrichWithRegistry({
6008
6475
  coinId: String(coinIdHex),
6009
6476
  symbol: String(coinIdHex).slice(0, 8),
6010
6477
  name: `Token ${String(coinIdHex).slice(0, 8)}`,
6478
+ decimals: 0,
6011
6479
  amount: String(amount),
6012
6480
  tokenId: defaultInfo.tokenId
6013
- };
6481
+ });
6014
6482
  }
6015
6483
  } else if (typeof coinData === "object") {
6016
6484
  const coinEntries = Object.entries(coinData);
6017
6485
  if (coinEntries.length > 0) {
6018
6486
  const [coinId, amount] = coinEntries[0];
6019
- return {
6487
+ return enrichWithRegistry({
6020
6488
  coinId,
6021
6489
  symbol: coinId.slice(0, 8),
6022
6490
  name: `Token ${coinId.slice(0, 8)}`,
6491
+ decimals: 0,
6023
6492
  amount: String(amount),
6024
6493
  tokenId: defaultInfo.tokenId
6025
- };
6494
+ });
6026
6495
  }
6027
6496
  }
6028
6497
  }
@@ -6181,7 +6650,8 @@ var PaymentsModule = class {
6181
6650
  this.l1.initialize({
6182
6651
  identity: deps.identity,
6183
6652
  chainCode: deps.chainCode,
6184
- addresses: deps.l1Addresses
6653
+ addresses: deps.l1Addresses,
6654
+ transport: deps.transport
6185
6655
  });
6186
6656
  }
6187
6657
  this.unsubscribeTransfers = deps.transport.onTokenTransfer((transfer) => {
@@ -6203,37 +6673,24 @@ var PaymentsModule = class {
6203
6673
  */
6204
6674
  async load() {
6205
6675
  this.ensureInitialized();
6206
- const data = await this.deps.storage.get(STORAGE_KEYS.TOKENS);
6207
- if (data) {
6676
+ const providers = this.getTokenStorageProviders();
6677
+ for (const [id, provider] of providers) {
6208
6678
  try {
6209
- const parsed = JSON.parse(data);
6210
- const tokens = parsed.tokens || [];
6211
- this.tokens.clear();
6212
- for (const token of tokens) {
6213
- this.tokens.set(token.id, token);
6214
- }
6215
- if (Array.isArray(parsed.tombstones)) {
6216
- this.tombstones = parsed.tombstones.filter(
6217
- (t) => typeof t === "object" && t !== null && typeof t.tokenId === "string" && typeof t.stateHash === "string"
6218
- );
6219
- }
6220
- if (parsed.archivedTokens && typeof parsed.archivedTokens === "object") {
6221
- this.archivedTokens = new Map(Object.entries(parsed.archivedTokens));
6222
- }
6223
- if (parsed.forkedTokens && typeof parsed.forkedTokens === "object") {
6224
- this.forkedTokens = new Map(Object.entries(parsed.forkedTokens));
6225
- }
6226
- if (parsed.nametag) {
6227
- this.nametag = parsed.nametag;
6679
+ const result = await provider.load();
6680
+ if (result.success && result.data) {
6681
+ this.loadFromStorageData(result.data);
6682
+ this.log(`Loaded from provider ${id}: ${this.tokens.size} tokens`);
6683
+ break;
6228
6684
  }
6229
- this.log(`Loaded ${this.tokens.size} tokens, ${this.tombstones.length} tombstones, ${this.archivedTokens.size} archived`);
6230
6685
  } catch (err) {
6231
- console.error("[Payments] Failed to parse stored data:", err);
6686
+ console.error(`[Payments] Failed to load from provider ${id}:`, err);
6232
6687
  }
6233
6688
  }
6234
- await this.loadTokensFromFileStorage();
6689
+ if (this.tokens.size === 0) {
6690
+ await this.loadTokensFromFileStorage();
6691
+ }
6235
6692
  await this.loadNametagFromFileStorage();
6236
- const historyData = await this.deps.storage.get(STORAGE_KEYS.TRANSACTION_HISTORY);
6693
+ const historyData = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY);
6237
6694
  if (historyData) {
6238
6695
  try {
6239
6696
  this.transactionHistory = JSON.parse(historyData);
@@ -6241,7 +6698,7 @@ var PaymentsModule = class {
6241
6698
  this.transactionHistory = [];
6242
6699
  }
6243
6700
  }
6244
- const pending2 = await this.deps.storage.get(STORAGE_KEYS.PENDING_TRANSFERS);
6701
+ const pending2 = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
6245
6702
  if (pending2) {
6246
6703
  const transfers = JSON.parse(pending2);
6247
6704
  for (const transfer of transfers) {
@@ -6339,6 +6796,8 @@ var PaymentsModule = class {
6339
6796
  coinId: request.coinId,
6340
6797
  symbol: this.getCoinSymbol(request.coinId),
6341
6798
  name: this.getCoinName(request.coinId),
6799
+ decimals: this.getCoinDecimals(request.coinId),
6800
+ iconUrl: this.getCoinIconUrl(request.coinId),
6342
6801
  amount: splitPlan.remainderAmount.toString(),
6343
6802
  status: "confirmed",
6344
6803
  createdAt: Date.now(),
@@ -6407,20 +6866,25 @@ var PaymentsModule = class {
6407
6866
  * Get coin symbol from coinId
6408
6867
  */
6409
6868
  getCoinSymbol(coinId) {
6410
- const symbols = {
6411
- "UCT": "UCT"
6412
- // Add more as needed
6413
- };
6414
- return symbols[coinId] || coinId.slice(0, 6).toUpperCase();
6869
+ return TokenRegistry$1.getInstance().getSymbol(coinId);
6415
6870
  }
6416
6871
  /**
6417
6872
  * Get coin name from coinId
6418
6873
  */
6419
6874
  getCoinName(coinId) {
6420
- const names = {
6421
- "UCT": "Unicity Token"
6422
- };
6423
- return names[coinId] || coinId;
6875
+ return TokenRegistry$1.getInstance().getName(coinId);
6876
+ }
6877
+ /**
6878
+ * Get coin decimals from coinId
6879
+ */
6880
+ getCoinDecimals(coinId) {
6881
+ return TokenRegistry$1.getInstance().getDecimals(coinId);
6882
+ }
6883
+ /**
6884
+ * Get coin icon URL from coinId
6885
+ */
6886
+ getCoinIconUrl(coinId) {
6887
+ return TokenRegistry$1.getInstance().getIconUrl(coinId) ?? void 0;
6424
6888
  }
6425
6889
  // ===========================================================================
6426
6890
  // Public API - Payment Requests
@@ -6578,7 +7042,7 @@ var PaymentsModule = class {
6578
7042
  }
6579
7043
  const request = {
6580
7044
  id: transportRequest.id,
6581
- senderPubkey: transportRequest.senderPubkey,
7045
+ senderPubkey: transportRequest.senderTransportPubkey,
6582
7046
  amount: transportRequest.request.amount,
6583
7047
  coinId: transportRequest.request.coinId,
6584
7048
  symbol: transportRequest.request.coinId,
@@ -6690,7 +7154,7 @@ var PaymentsModule = class {
6690
7154
  }
6691
7155
  const response = {
6692
7156
  id: transportResponse.id,
6693
- responderPubkey: transportResponse.responderPubkey,
7157
+ responderPubkey: transportResponse.responderTransportPubkey,
6694
7158
  requestId: transportResponse.response.requestId,
6695
7159
  responseType: transportResponse.response.responseType,
6696
7160
  message: transportResponse.response.message,
@@ -6895,6 +7359,8 @@ var PaymentsModule = class {
6895
7359
  coinId: tokenInfo.coinId,
6896
7360
  symbol: tokenInfo.symbol,
6897
7361
  name: tokenInfo.name,
7362
+ decimals: tokenInfo.decimals,
7363
+ iconUrl: tokenInfo.iconUrl,
6898
7364
  amount: tokenInfo.amount,
6899
7365
  status: "confirmed",
6900
7366
  createdAt: data.receivedAt || Date.now(),
@@ -7150,7 +7616,7 @@ var PaymentsModule = class {
7150
7616
  };
7151
7617
  this.transactionHistory.push(historyEntry);
7152
7618
  await this.deps.storage.set(
7153
- STORAGE_KEYS.TRANSACTION_HISTORY,
7619
+ STORAGE_KEYS_ADDRESS.TRANSACTION_HISTORY,
7154
7620
  JSON.stringify(this.transactionHistory)
7155
7621
  );
7156
7622
  }
@@ -7444,6 +7910,23 @@ var PaymentsModule = class {
7444
7910
  // ===========================================================================
7445
7911
  // Private: Transfer Operations
7446
7912
  // ===========================================================================
7913
+ /**
7914
+ * Detect if a string is an L3 address (not a nametag)
7915
+ * Returns true for: hex pubkeys (64+ chars), PROXY:, DIRECT: prefixed addresses
7916
+ */
7917
+ isL3Address(value) {
7918
+ if (value.startsWith("PROXY:") || value.startsWith("DIRECT:")) {
7919
+ return true;
7920
+ }
7921
+ if (value.length >= 64 && /^[0-9a-fA-F]+$/.test(value)) {
7922
+ return true;
7923
+ }
7924
+ return false;
7925
+ }
7926
+ /**
7927
+ * Resolve recipient to Nostr pubkey for messaging
7928
+ * Supports: nametag (with or without @), hex pubkey
7929
+ */
7447
7930
  async resolveRecipient(recipient) {
7448
7931
  if (recipient.startsWith("@")) {
7449
7932
  const nametag = recipient.slice(1);
@@ -7453,7 +7936,19 @@ var PaymentsModule = class {
7453
7936
  }
7454
7937
  return pubkey;
7455
7938
  }
7456
- return recipient;
7939
+ if (this.isL3Address(recipient)) {
7940
+ return recipient;
7941
+ }
7942
+ if (this.deps?.transport.resolveNametag) {
7943
+ const pubkey = await this.deps.transport.resolveNametag(recipient);
7944
+ if (pubkey) {
7945
+ this.log(`Resolved "${recipient}" as nametag to pubkey`);
7946
+ return pubkey;
7947
+ }
7948
+ }
7949
+ throw new Error(
7950
+ `Recipient "${recipient}" is not a valid nametag or address. Use @nametag for explicit nametag or a valid hex pubkey/PROXY:/DIRECT: address.`
7951
+ );
7457
7952
  }
7458
7953
  /**
7459
7954
  * Create SDK TransferCommitment for a token transfer
@@ -7485,19 +7980,74 @@ var PaymentsModule = class {
7485
7980
  return SigningService.createFromSecret(privateKeyBytes);
7486
7981
  }
7487
7982
  /**
7488
- * Resolve recipient to IAddress
7983
+ * Create DirectAddress from a public key using UnmaskedPredicateReference
7984
+ */
7985
+ async createDirectAddressFromPubkey(pubkeyHex) {
7986
+ const { UnmaskedPredicateReference: UnmaskedPredicateReference3 } = await import('@unicitylabs/state-transition-sdk/lib/predicate/embedded/UnmaskedPredicateReference');
7987
+ const { TokenType: TokenType3 } = await import('@unicitylabs/state-transition-sdk/lib/token/TokenType');
7988
+ const UNICITY_TOKEN_TYPE_HEX3 = "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509";
7989
+ const tokenType = new TokenType3(Buffer.from(UNICITY_TOKEN_TYPE_HEX3, "hex"));
7990
+ const pubkeyBytes = new Uint8Array(
7991
+ pubkeyHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
7992
+ );
7993
+ const addressRef = await UnmaskedPredicateReference3.create(
7994
+ tokenType,
7995
+ "secp256k1",
7996
+ pubkeyBytes,
7997
+ HashAlgorithm.SHA256
7998
+ );
7999
+ return addressRef.toAddress();
8000
+ }
8001
+ /**
8002
+ * Resolve nametag to 33-byte compressed public key using resolveNametagInfo
8003
+ * Returns null if nametag not found or publicKey not available
8004
+ */
8005
+ async resolveNametagToPublicKey(nametag) {
8006
+ if (!this.deps?.transport.resolveNametagInfo) {
8007
+ this.log("resolveNametagInfo not available on transport");
8008
+ return null;
8009
+ }
8010
+ const info = await this.deps.transport.resolveNametagInfo(nametag);
8011
+ if (!info) {
8012
+ this.log(`Nametag "${nametag}" not found`);
8013
+ return null;
8014
+ }
8015
+ if (!info.chainPubkey) {
8016
+ this.log(`Nametag "${nametag}" has no 33-byte chainPubkey (legacy event)`);
8017
+ return null;
8018
+ }
8019
+ return info.chainPubkey;
8020
+ }
8021
+ /**
8022
+ * Resolve recipient to IAddress for L3 transfers
8023
+ * Supports: nametag (with or without @), PROXY:, DIRECT:, hex pubkey
7489
8024
  */
7490
8025
  async resolveRecipientAddress(recipient) {
8026
+ const { AddressFactory } = await import('@unicitylabs/state-transition-sdk/lib/address/AddressFactory');
7491
8027
  if (recipient.startsWith("@")) {
7492
8028
  const nametag = recipient.slice(1);
7493
- const tokenId2 = await TokenId.fromNameTag(nametag);
7494
- return ProxyAddress.fromTokenId(tokenId2);
8029
+ const publicKey2 = await this.resolveNametagToPublicKey(nametag);
8030
+ if (publicKey2) {
8031
+ this.log(`Resolved @${nametag} to 33-byte publicKey for DirectAddress`);
8032
+ return this.createDirectAddressFromPubkey(publicKey2);
8033
+ }
8034
+ throw new Error(`Nametag "${nametag}" not found or missing publicKey`);
7495
8035
  }
7496
- const pubkeyBytes = new Uint8Array(
7497
- recipient.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
8036
+ if (recipient.startsWith("PROXY:") || recipient.startsWith("DIRECT:")) {
8037
+ return AddressFactory.createAddress(recipient);
8038
+ }
8039
+ if (recipient.length === 66 && /^[0-9a-fA-F]+$/.test(recipient)) {
8040
+ this.log(`Creating DirectAddress from 33-byte compressed pubkey`);
8041
+ return this.createDirectAddressFromPubkey(recipient);
8042
+ }
8043
+ const publicKey = await this.resolveNametagToPublicKey(recipient);
8044
+ if (publicKey) {
8045
+ this.log(`Resolved "${recipient}" as nametag to 33-byte publicKey for DirectAddress`);
8046
+ return this.createDirectAddressFromPubkey(publicKey);
8047
+ }
8048
+ throw new Error(
8049
+ `Recipient "${recipient}" is not a valid nametag or L3 address. Use @nametag for explicit nametag or a valid 33-byte hex pubkey/PROXY:/DIRECT: address.`
7498
8050
  );
7499
- const tokenId = new TokenId(pubkeyBytes.slice(0, 32));
7500
- return ProxyAddress.fromTokenId(tokenId);
7501
8051
  }
7502
8052
  async handleIncomingTransfer(transfer) {
7503
8053
  try {
@@ -7555,7 +8105,39 @@ var PaymentsModule = class {
7555
8105
  }
7556
8106
  }
7557
8107
  } else {
7558
- tokenData = sourceTokenInput;
8108
+ this.log("Finalizing DIRECT address transfer for state tracking...");
8109
+ try {
8110
+ const signingService = await this.createSigningService();
8111
+ const transferSalt = transferTx.data.salt;
8112
+ const recipientPredicate = await UnmaskedPredicate.create(
8113
+ sourceToken.id,
8114
+ sourceToken.type,
8115
+ signingService,
8116
+ HashAlgorithm.SHA256,
8117
+ transferSalt
8118
+ );
8119
+ const recipientState = new TokenState$1(recipientPredicate, null);
8120
+ const stClient = this.deps.oracle.getStateTransitionClient?.();
8121
+ const trustBase = this.deps.oracle.getTrustBase?.();
8122
+ if (!stClient || !trustBase) {
8123
+ this.log("Cannot finalize DIRECT transfer - missing client, using source token");
8124
+ tokenData = sourceTokenInput;
8125
+ } else {
8126
+ finalizedSdkToken = await stClient.finalizeTransaction(
8127
+ trustBase,
8128
+ sourceToken,
8129
+ recipientState,
8130
+ transferTx,
8131
+ []
8132
+ // No nametag tokens needed for DIRECT
8133
+ );
8134
+ tokenData = finalizedSdkToken.toJSON();
8135
+ this.log("DIRECT transfer finalized successfully");
8136
+ }
8137
+ } catch (finalizeError) {
8138
+ this.log("DIRECT finalization failed, using source token:", finalizeError);
8139
+ tokenData = sourceTokenInput;
8140
+ }
7559
8141
  }
7560
8142
  } else if (payload.token) {
7561
8143
  tokenData = payload.token;
@@ -7574,6 +8156,8 @@ var PaymentsModule = class {
7574
8156
  coinId: tokenInfo.coinId,
7575
8157
  symbol: tokenInfo.symbol,
7576
8158
  name: tokenInfo.name,
8159
+ decimals: tokenInfo.decimals,
8160
+ iconUrl: tokenInfo.iconUrl,
7577
8161
  amount: tokenInfo.amount,
7578
8162
  status: "confirmed",
7579
8163
  createdAt: Date.now(),
@@ -7589,7 +8173,7 @@ var PaymentsModule = class {
7589
8173
  await this.addToken(token);
7590
8174
  const incomingTransfer = {
7591
8175
  id: transfer.id,
7592
- senderPubkey: transfer.senderPubkey,
8176
+ senderPubkey: transfer.senderTransportPubkey,
7593
8177
  tokens: [token],
7594
8178
  memo: payload.memo,
7595
8179
  receivedAt: transfer.timestamp
@@ -7627,28 +8211,32 @@ var PaymentsModule = class {
7627
8211
  // Private: Storage
7628
8212
  // ===========================================================================
7629
8213
  async save() {
7630
- const tokens = Array.from(this.tokens.values());
7631
- const data = {
7632
- tokens,
7633
- tombstones: this.tombstones.length > 0 ? this.tombstones : void 0,
7634
- archivedTokens: this.archivedTokens.size > 0 ? Object.fromEntries(this.archivedTokens) : void 0,
7635
- forkedTokens: this.forkedTokens.size > 0 ? Object.fromEntries(this.forkedTokens) : void 0,
7636
- nametag: this.nametag || void 0
7637
- };
7638
- await this.deps.storage.set(STORAGE_KEYS.TOKENS, JSON.stringify(data));
8214
+ const providers = this.getTokenStorageProviders();
8215
+ if (providers.size === 0) {
8216
+ this.log("No token storage providers - tokens not persisted");
8217
+ return;
8218
+ }
8219
+ const data = await this.createStorageData();
8220
+ for (const [id, provider] of providers) {
8221
+ try {
8222
+ await provider.save(data);
8223
+ } catch (err) {
8224
+ console.error(`[Payments] Failed to save to provider ${id}:`, err);
8225
+ }
8226
+ }
7639
8227
  }
7640
8228
  async saveToOutbox(transfer, recipient) {
7641
8229
  const outbox = await this.loadOutbox();
7642
8230
  outbox.push({ transfer, recipient, createdAt: Date.now() });
7643
- await this.deps.storage.set(STORAGE_KEYS.OUTBOX, JSON.stringify(outbox));
8231
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(outbox));
7644
8232
  }
7645
8233
  async removeFromOutbox(transferId) {
7646
8234
  const outbox = await this.loadOutbox();
7647
8235
  const filtered = outbox.filter((e) => e.transfer.id !== transferId);
7648
- await this.deps.storage.set(STORAGE_KEYS.OUTBOX, JSON.stringify(filtered));
8236
+ await this.deps.storage.set(STORAGE_KEYS_ADDRESS.OUTBOX, JSON.stringify(filtered));
7649
8237
  }
7650
8238
  async loadOutbox() {
7651
- const data = await this.deps.storage.get(STORAGE_KEYS.OUTBOX);
8239
+ const data = await this.deps.storage.get(STORAGE_KEYS_ADDRESS.OUTBOX);
7652
8240
  return data ? JSON.parse(data) : [];
7653
8241
  }
7654
8242
  async createStorageData() {
@@ -7657,11 +8245,10 @@ var PaymentsModule = class {
7657
8245
  tokens,
7658
8246
  {
7659
8247
  version: 1,
7660
- address: this.deps.identity.address,
8248
+ address: this.deps.identity.l1Address,
7661
8249
  ipnsName: this.deps.identity.ipnsName ?? ""
7662
8250
  },
7663
8251
  {
7664
- nametag: this.nametag || void 0,
7665
8252
  tombstones: this.tombstones,
7666
8253
  archivedTokens: this.archivedTokens,
7667
8254
  forkedTokens: this.forkedTokens
@@ -7761,7 +8348,7 @@ var CommunicationsModule = class {
7761
8348
  const eventId = await this.deps.transport.sendMessage(recipientPubkey, content);
7762
8349
  const message = {
7763
8350
  id: eventId,
7764
- senderPubkey: this.deps.identity.publicKey,
8351
+ senderPubkey: this.deps.identity.chainPubkey,
7765
8352
  senderNametag: this.deps.identity.nametag,
7766
8353
  recipientPubkey,
7767
8354
  content,
@@ -7788,7 +8375,7 @@ var CommunicationsModule = class {
7788
8375
  getConversations() {
7789
8376
  const conversations = /* @__PURE__ */ new Map();
7790
8377
  for (const message of this.messages.values()) {
7791
- const peer = message.senderPubkey === this.deps?.identity.publicKey ? message.recipientPubkey : message.senderPubkey;
8378
+ const peer = message.senderPubkey === this.deps?.identity.chainPubkey ? message.recipientPubkey : message.senderPubkey;
7792
8379
  if (!conversations.has(peer)) {
7793
8380
  conversations.set(peer, []);
7794
8381
  }
@@ -7818,7 +8405,7 @@ var CommunicationsModule = class {
7818
8405
  */
7819
8406
  getUnreadCount(peerPubkey) {
7820
8407
  let messages = Array.from(this.messages.values()).filter(
7821
- (m) => !m.isRead && m.senderPubkey !== this.deps?.identity.publicKey
8408
+ (m) => !m.isRead && m.senderPubkey !== this.deps?.identity.chainPubkey
7822
8409
  );
7823
8410
  if (peerPubkey) {
7824
8411
  messages = messages.filter((m) => m.senderPubkey === peerPubkey);
@@ -7843,7 +8430,7 @@ var CommunicationsModule = class {
7843
8430
  const eventId = await this.deps.transport.publishBroadcast?.(content, tags);
7844
8431
  const message = {
7845
8432
  id: eventId ?? crypto.randomUUID(),
7846
- authorPubkey: this.deps.identity.publicKey,
8433
+ authorPubkey: this.deps.identity.chainPubkey,
7847
8434
  authorNametag: this.deps.identity.nametag,
7848
8435
  content,
7849
8436
  timestamp: Date.now(),
@@ -7894,11 +8481,12 @@ var CommunicationsModule = class {
7894
8481
  // Private: Message Handling
7895
8482
  // ===========================================================================
7896
8483
  handleIncomingMessage(msg) {
7897
- if (msg.senderPubkey === this.deps?.identity.publicKey) return;
8484
+ if (msg.senderTransportPubkey === this.deps?.identity.chainPubkey) return;
7898
8485
  const message = {
7899
8486
  id: msg.id,
7900
- senderPubkey: msg.senderPubkey,
7901
- recipientPubkey: this.deps.identity.publicKey,
8487
+ senderPubkey: msg.senderTransportPubkey,
8488
+ senderNametag: msg.senderNametag,
8489
+ recipientPubkey: this.deps.identity.chainPubkey,
7902
8490
  content: msg.content,
7903
8491
  timestamp: msg.timestamp,
7904
8492
  isRead: false
@@ -7920,7 +8508,7 @@ var CommunicationsModule = class {
7920
8508
  handleIncomingBroadcast(incoming) {
7921
8509
  const message = {
7922
8510
  id: incoming.id,
7923
- authorPubkey: incoming.authorPubkey,
8511
+ authorPubkey: incoming.authorTransportPubkey,
7924
8512
  content: incoming.content,
7925
8513
  timestamp: incoming.timestamp,
7926
8514
  tags: incoming.tags
@@ -8638,6 +9226,7 @@ var Sphere = class _Sphere {
8638
9226
  _derivationMode = "bip32";
8639
9227
  _basePath = DEFAULT_BASE_PATH;
8640
9228
  _currentAddressIndex = 0;
9229
+ /** Map of addressId -> (nametagIndex -> nametag). Supports multiple nametags per address (e.g., from Nostr recovery) */
8641
9230
  _addressNametags = /* @__PURE__ */ new Map();
8642
9231
  // Providers
8643
9232
  _storage;
@@ -8673,9 +9262,9 @@ var Sphere = class _Sphere {
8673
9262
  if (!storage.isConnected()) {
8674
9263
  await storage.connect();
8675
9264
  }
8676
- const mnemonic = await storage.get(STORAGE_KEYS.MNEMONIC);
9265
+ const mnemonic = await storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
8677
9266
  if (mnemonic) return true;
8678
- const masterKey = await storage.get(STORAGE_KEYS.MASTER_KEY);
9267
+ const masterKey = await storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
8679
9268
  if (masterKey) return true;
8680
9269
  return false;
8681
9270
  } catch {
@@ -8769,6 +9358,8 @@ var Sphere = class _Sphere {
8769
9358
  _Sphere.instance = sphere;
8770
9359
  if (options.nametag) {
8771
9360
  await sphere.registerNametag(options.nametag);
9361
+ } else {
9362
+ await sphere.recoverNametagFromNostr();
8772
9363
  }
8773
9364
  return sphere;
8774
9365
  }
@@ -8831,6 +9422,9 @@ var Sphere = class _Sphere {
8831
9422
  }
8832
9423
  await sphere.initializeProviders();
8833
9424
  await sphere.initializeModules();
9425
+ if (!options.nametag) {
9426
+ await sphere.recoverNametagFromNostr();
9427
+ }
8834
9428
  await sphere.finalizeWalletCreation();
8835
9429
  sphere._initialized = true;
8836
9430
  _Sphere.instance = sphere;
@@ -8841,20 +9435,20 @@ var Sphere = class _Sphere {
8841
9435
  }
8842
9436
  /**
8843
9437
  * Clear wallet data from storage
9438
+ * Note: Token data is cleared via TokenStorageProvider, not here
8844
9439
  */
8845
9440
  static async clear(storage) {
8846
- await storage.remove(STORAGE_KEYS.MNEMONIC);
8847
- await storage.remove(STORAGE_KEYS.MASTER_KEY);
8848
- await storage.remove(STORAGE_KEYS.CHAIN_CODE);
8849
- await storage.remove(STORAGE_KEYS.DERIVATION_PATH);
8850
- await storage.remove(STORAGE_KEYS.BASE_PATH);
8851
- await storage.remove(STORAGE_KEYS.DERIVATION_MODE);
8852
- await storage.remove(STORAGE_KEYS.WALLET_SOURCE);
8853
- await storage.remove(STORAGE_KEYS.WALLET_EXISTS);
8854
- await storage.remove(STORAGE_KEYS.NAMETAG);
8855
- await storage.remove(STORAGE_KEYS.TOKENS);
8856
- await storage.remove(STORAGE_KEYS.PENDING_TRANSFERS);
8857
- await storage.remove(STORAGE_KEYS.OUTBOX);
9441
+ await storage.remove(STORAGE_KEYS_GLOBAL.MNEMONIC);
9442
+ await storage.remove(STORAGE_KEYS_GLOBAL.MASTER_KEY);
9443
+ await storage.remove(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
9444
+ await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
9445
+ await storage.remove(STORAGE_KEYS_GLOBAL.BASE_PATH);
9446
+ await storage.remove(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
9447
+ await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
9448
+ await storage.remove(STORAGE_KEYS_GLOBAL.WALLET_EXISTS);
9449
+ await storage.remove(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
9450
+ await storage.remove(STORAGE_KEYS_ADDRESS.PENDING_TRANSFERS);
9451
+ await storage.remove(STORAGE_KEYS_ADDRESS.OUTBOX);
8858
9452
  if (_Sphere.instance) {
8859
9453
  await _Sphere.instance.destroy();
8860
9454
  }
@@ -8904,9 +9498,9 @@ var Sphere = class _Sphere {
8904
9498
  get identity() {
8905
9499
  if (!this._identity) return null;
8906
9500
  return {
8907
- publicKey: this._identity.publicKey,
8908
- address: this._identity.address,
8909
- predicateAddress: this._identity.predicateAddress,
9501
+ chainPubkey: this._identity.chainPubkey,
9502
+ l1Address: this._identity.l1Address,
9503
+ directAddress: this._identity.directAddress,
8910
9504
  ipnsName: this._identity.ipnsName,
8911
9505
  nametag: this._identity.nametag
8912
9506
  };
@@ -9023,7 +9617,7 @@ var Sphere = class _Sphere {
9023
9617
  if (this._masterKey) {
9024
9618
  address0 = this.deriveAddress(0).address;
9025
9619
  } else if (this._identity) {
9026
- address0 = this._identity.address;
9620
+ address0 = this._identity.l1Address;
9027
9621
  }
9028
9622
  } catch {
9029
9623
  }
@@ -9070,8 +9664,8 @@ var Sphere = class _Sphere {
9070
9664
  } catch {
9071
9665
  if (i === 0 && this._identity) {
9072
9666
  addresses.push({
9073
- address: this._identity.address,
9074
- publicKey: this._identity.publicKey,
9667
+ address: this._identity.l1Address,
9668
+ publicKey: this._identity.chainPubkey,
9075
9669
  path: this.getDefaultAddressPath(),
9076
9670
  index: 0
9077
9671
  });
@@ -9150,7 +9744,7 @@ var Sphere = class _Sphere {
9150
9744
  } catch {
9151
9745
  if (i === 0 && this._identity) {
9152
9746
  addresses.push({
9153
- address: this._identity.address,
9747
+ address: this._identity.l1Address,
9154
9748
  path: this.getDefaultAddressPath(),
9155
9749
  index: 0,
9156
9750
  isChange: false
@@ -9454,22 +10048,47 @@ var Sphere = class _Sphere {
9454
10048
  return this._currentAddressIndex;
9455
10049
  }
9456
10050
  /**
9457
- * Get nametag for a specific address index
10051
+ * Get primary nametag for a specific address
9458
10052
  *
9459
- * @param index - Address index (default: current address)
9460
- * @returns Nametag or undefined if not registered
10053
+ * @param addressId - Address identifier (DIRECT://xxx), defaults to current address
10054
+ * @returns Primary nametag (index 0) or undefined if not registered
9461
10055
  */
9462
- getNametagForAddress(index) {
9463
- const addressIndex = index ?? this._currentAddressIndex;
9464
- return this._addressNametags.get(addressIndex);
10056
+ getNametagForAddress(addressId) {
10057
+ const id = addressId ?? this.getCurrentAddressId();
10058
+ if (!id) return void 0;
10059
+ const nametagsMap = this._addressNametags.get(id);
10060
+ return nametagsMap?.get(0);
10061
+ }
10062
+ /**
10063
+ * Get all nametags for a specific address
10064
+ *
10065
+ * @param addressId - Address identifier (DIRECT://xxx), defaults to current address
10066
+ * @returns Map of nametagIndex to nametag, or undefined if no nametags
10067
+ */
10068
+ getNametagsForAddress(addressId) {
10069
+ const id = addressId ?? this.getCurrentAddressId();
10070
+ if (!id) return void 0;
10071
+ const nametagsMap = this._addressNametags.get(id);
10072
+ return nametagsMap ? new Map(nametagsMap) : void 0;
9465
10073
  }
9466
10074
  /**
9467
10075
  * Get all registered address nametags
9468
10076
  *
9469
- * @returns Map of address index to nametag
10077
+ * @returns Map of addressId to (nametagIndex -> nametag)
9470
10078
  */
9471
10079
  getAllAddressNametags() {
9472
- return new Map(this._addressNametags);
10080
+ const result = /* @__PURE__ */ new Map();
10081
+ this._addressNametags.forEach((nametagsMap, addressId) => {
10082
+ result.set(addressId, new Map(nametagsMap));
10083
+ });
10084
+ return result;
10085
+ }
10086
+ /**
10087
+ * Get current address identifier (DIRECT://xxx format)
10088
+ */
10089
+ getCurrentAddressId() {
10090
+ if (!this._identity?.directAddress) return void 0;
10091
+ return getAddressId(this._identity.directAddress);
9473
10092
  }
9474
10093
  /**
9475
10094
  * Switch to a different address by index
@@ -9501,17 +10120,19 @@ var Sphere = class _Sphere {
9501
10120
  const addressInfo = this.deriveAddress(index, false);
9502
10121
  const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
9503
10122
  const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
9504
- const nametag = this._addressNametags.get(index);
10123
+ const addressId = getAddressId(predicateAddress);
10124
+ const nametagsMap = this._addressNametags.get(addressId);
10125
+ const nametag = nametagsMap?.get(0);
9505
10126
  this._identity = {
9506
10127
  privateKey: addressInfo.privateKey,
9507
- publicKey: addressInfo.publicKey,
9508
- address: addressInfo.address,
9509
- predicateAddress,
10128
+ chainPubkey: addressInfo.publicKey,
10129
+ l1Address: addressInfo.address,
10130
+ directAddress: predicateAddress,
9510
10131
  ipnsName: "12D3KooW" + ipnsHash,
9511
10132
  nametag
9512
10133
  };
9513
10134
  this._currentAddressIndex = index;
9514
- await this._storage.set(STORAGE_KEYS.CURRENT_ADDRESS_INDEX, index.toString());
10135
+ await this._storage.set(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX, index.toString());
9515
10136
  this._storage.setIdentity(this._identity);
9516
10137
  this._transport.setIdentity(this._identity);
9517
10138
  for (const provider of this._tokenStorageProviders.values()) {
@@ -9519,13 +10140,13 @@ var Sphere = class _Sphere {
9519
10140
  }
9520
10141
  await this.reinitializeModulesForNewAddress();
9521
10142
  this.emitEvent("identity:changed", {
9522
- address: this._identity.address,
9523
- predicateAddress: this._identity.predicateAddress,
9524
- publicKey: this._identity.publicKey,
10143
+ l1Address: this._identity.l1Address,
10144
+ directAddress: this._identity.directAddress,
10145
+ chainPubkey: this._identity.chainPubkey,
9525
10146
  nametag: this._identity.nametag,
9526
10147
  addressIndex: index
9527
10148
  });
9528
- console.log(`[Sphere] Switched to address ${index}:`, this._identity.address);
10149
+ console.log(`[Sphere] Switched to address ${index}:`, this._identity.l1Address);
9529
10150
  }
9530
10151
  /**
9531
10152
  * Re-initialize modules after address switch
@@ -9583,7 +10204,7 @@ var Sphere = class _Sphere {
9583
10204
  );
9584
10205
  return {
9585
10206
  ...info,
9586
- address: "alpha1" + info.address.slice(0, 38)
10207
+ address: publicKeyToAddress(info.publicKey, "alpha")
9587
10208
  };
9588
10209
  }
9589
10210
  /**
@@ -9610,11 +10231,10 @@ var Sphere = class _Sphere {
9610
10231
  path
9611
10232
  );
9612
10233
  const publicKey = getPublicKey(derived.privateKey);
9613
- const addressHash = hash160(publicKey);
9614
10234
  return {
9615
10235
  privateKey: derived.privateKey,
9616
10236
  publicKey,
9617
- address: "alpha1" + addressHash.slice(0, 38),
10237
+ address: publicKeyToAddress(publicKey, "alpha"),
9618
10238
  path,
9619
10239
  index
9620
10240
  };
@@ -9702,6 +10322,17 @@ var Sphere = class _Sphere {
9702
10322
  hasNametag() {
9703
10323
  return !!this._identity?.nametag;
9704
10324
  }
10325
+ /**
10326
+ * Get the PROXY address for the current nametag
10327
+ * PROXY addresses are derived from the nametag hash and require
10328
+ * the nametag token to claim funds sent to them
10329
+ * @returns PROXY address string or undefined if no nametag
10330
+ */
10331
+ getProxyAddress() {
10332
+ const nametag = this._identity?.nametag;
10333
+ if (!nametag) return void 0;
10334
+ return `PROXY:${hashNametag(nametag)}`;
10335
+ }
9705
10336
  /**
9706
10337
  * Register a nametag for the current active address
9707
10338
  * Each address can have its own independent nametag
@@ -9730,14 +10361,25 @@ var Sphere = class _Sphere {
9730
10361
  throw new Error(`Nametag already registered for address ${this._currentAddressIndex}: @${this._identity.nametag}`);
9731
10362
  }
9732
10363
  if (this._transport.registerNametag) {
9733
- const success = await this._transport.registerNametag(cleanNametag, this._identity.publicKey);
10364
+ const success = await this._transport.registerNametag(
10365
+ cleanNametag,
10366
+ this._identity.chainPubkey,
10367
+ this._identity.directAddress || ""
10368
+ );
9734
10369
  if (!success) {
9735
10370
  throw new Error("Failed to register nametag. It may already be taken.");
9736
10371
  }
9737
10372
  }
9738
10373
  this._identity.nametag = cleanNametag;
9739
- this._addressNametags.set(this._currentAddressIndex, cleanNametag);
9740
- await this._storage.set(STORAGE_KEYS.NAMETAG, cleanNametag);
10374
+ const addressId = this.getCurrentAddressId();
10375
+ if (addressId) {
10376
+ let nametagsMap = this._addressNametags.get(addressId);
10377
+ if (!nametagsMap) {
10378
+ nametagsMap = /* @__PURE__ */ new Map();
10379
+ this._addressNametags.set(addressId, nametagsMap);
10380
+ }
10381
+ nametagsMap.set(0, cleanNametag);
10382
+ }
9741
10383
  await this.persistAddressNametags();
9742
10384
  if (!this._payments.hasNametag()) {
9743
10385
  console.log(`[Sphere] Minting nametag token for @${cleanNametag}...`);
@@ -9756,13 +10398,18 @@ var Sphere = class _Sphere {
9756
10398
  }
9757
10399
  /**
9758
10400
  * Persist address nametags to storage
10401
+ * Format: { "DIRECT://abc...xyz": { "0": "alice", "1": "alice2" }, ... }
9759
10402
  */
9760
10403
  async persistAddressNametags() {
9761
- const nametagsObj = {};
9762
- this._addressNametags.forEach((nametag, index) => {
9763
- nametagsObj[index.toString()] = nametag;
10404
+ const result = {};
10405
+ this._addressNametags.forEach((nametagsMap, addressId) => {
10406
+ const innerObj = {};
10407
+ nametagsMap.forEach((nametag, index) => {
10408
+ innerObj[index.toString()] = nametag;
10409
+ });
10410
+ result[addressId] = innerObj;
9764
10411
  });
9765
- await this._storage.set(STORAGE_KEYS.ADDRESS_NAMETAGS, JSON.stringify(nametagsObj));
10412
+ await this._storage.set(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS, JSON.stringify(result));
9766
10413
  }
9767
10414
  /**
9768
10415
  * Mint a nametag token on-chain (like Sphere wallet and lottery)
@@ -9797,15 +10444,24 @@ var Sphere = class _Sphere {
9797
10444
  }
9798
10445
  /**
9799
10446
  * Load address nametags from storage
10447
+ * Supports new format: { "DIRECT://abc...xyz": { "0": "alice" } }
10448
+ * And legacy format: { "0": "alice" } (migrates to new format on save)
9800
10449
  */
9801
10450
  async loadAddressNametags() {
9802
10451
  try {
9803
- const saved = await this._storage.get(STORAGE_KEYS.ADDRESS_NAMETAGS);
10452
+ const saved = await this._storage.get(STORAGE_KEYS_GLOBAL.ADDRESS_NAMETAGS);
9804
10453
  if (saved) {
9805
- const nametagsObj = JSON.parse(saved);
10454
+ const parsed = JSON.parse(saved);
9806
10455
  this._addressNametags.clear();
9807
- for (const [indexStr, nametag] of Object.entries(nametagsObj)) {
9808
- this._addressNametags.set(parseInt(indexStr, 10), nametag);
10456
+ for (const [key, value] of Object.entries(parsed)) {
10457
+ if (typeof value === "object" && value !== null) {
10458
+ const nametagsMap = /* @__PURE__ */ new Map();
10459
+ for (const [indexStr, nametag] of Object.entries(value)) {
10460
+ nametagsMap.set(parseInt(indexStr, 10), nametag);
10461
+ }
10462
+ this._addressNametags.set(key, nametagsMap);
10463
+ } else if (typeof value === "string") {
10464
+ }
9809
10465
  }
9810
10466
  }
9811
10467
  } catch {
@@ -9824,7 +10480,11 @@ var Sphere = class _Sphere {
9824
10480
  return;
9825
10481
  }
9826
10482
  try {
9827
- const success = await this._transport.registerNametag(nametag, this._identity.publicKey);
10483
+ const success = await this._transport.registerNametag(
10484
+ nametag,
10485
+ this._identity.chainPubkey,
10486
+ this._identity.directAddress || ""
10487
+ );
9828
10488
  if (success) {
9829
10489
  console.log(`[Sphere] Nametag @${nametag} synced with Nostr`);
9830
10490
  } else {
@@ -9834,6 +10494,47 @@ var Sphere = class _Sphere {
9834
10494
  console.warn(`[Sphere] Nametag sync failed:`, error);
9835
10495
  }
9836
10496
  }
10497
+ /**
10498
+ * Recover nametag from Nostr after wallet import
10499
+ * Searches for encrypted nametag events authored by this wallet's pubkey
10500
+ * and decrypts them to restore the nametag association
10501
+ */
10502
+ async recoverNametagFromNostr() {
10503
+ if (this._identity?.nametag) {
10504
+ return;
10505
+ }
10506
+ if (!this._transport.recoverNametag) {
10507
+ return;
10508
+ }
10509
+ try {
10510
+ const recoveredNametag = await this._transport.recoverNametag();
10511
+ if (recoveredNametag) {
10512
+ if (this._identity) {
10513
+ this._identity.nametag = recoveredNametag;
10514
+ }
10515
+ const addressId = this.getCurrentAddressId();
10516
+ if (addressId) {
10517
+ let nametagsMap = this._addressNametags.get(addressId);
10518
+ if (!nametagsMap) {
10519
+ nametagsMap = /* @__PURE__ */ new Map();
10520
+ this._addressNametags.set(addressId, nametagsMap);
10521
+ }
10522
+ const nextIndex = nametagsMap.size;
10523
+ nametagsMap.set(nextIndex, recoveredNametag);
10524
+ }
10525
+ await this.persistAddressNametags();
10526
+ if (this._transport.registerNametag) {
10527
+ await this._transport.registerNametag(
10528
+ recoveredNametag,
10529
+ this._identity.chainPubkey,
10530
+ this._identity.directAddress || ""
10531
+ );
10532
+ }
10533
+ this.emitEvent("nametag:recovered", { nametag: recoveredNametag });
10534
+ }
10535
+ } catch {
10536
+ }
10537
+ }
9837
10538
  /**
9838
10539
  * Validate nametag format
9839
10540
  */
@@ -9864,22 +10565,22 @@ var Sphere = class _Sphere {
9864
10565
  // ===========================================================================
9865
10566
  async storeMnemonic(mnemonic, derivationPath, basePath) {
9866
10567
  const encrypted = this.encrypt(mnemonic);
9867
- await this._storage.set(STORAGE_KEYS.MNEMONIC, encrypted);
10568
+ await this._storage.set(STORAGE_KEYS_GLOBAL.MNEMONIC, encrypted);
9868
10569
  this._mnemonic = mnemonic;
9869
10570
  this._source = "mnemonic";
9870
10571
  this._derivationMode = "bip32";
9871
10572
  if (derivationPath) {
9872
- await this._storage.set(STORAGE_KEYS.DERIVATION_PATH, derivationPath);
10573
+ await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
9873
10574
  }
9874
10575
  const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
9875
10576
  this._basePath = effectiveBasePath;
9876
- await this._storage.set(STORAGE_KEYS.BASE_PATH, effectiveBasePath);
9877
- await this._storage.set(STORAGE_KEYS.DERIVATION_MODE, this._derivationMode);
9878
- await this._storage.set(STORAGE_KEYS.WALLET_SOURCE, this._source);
10577
+ await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
10578
+ await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
10579
+ await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
9879
10580
  }
9880
10581
  async storeMasterKey(masterKey, chainCode, derivationPath, basePath, derivationMode) {
9881
10582
  const encrypted = this.encrypt(masterKey);
9882
- await this._storage.set(STORAGE_KEYS.MASTER_KEY, encrypted);
10583
+ await this._storage.set(STORAGE_KEYS_GLOBAL.MASTER_KEY, encrypted);
9883
10584
  this._source = "file";
9884
10585
  this._mnemonic = null;
9885
10586
  if (derivationMode) {
@@ -9888,16 +10589,16 @@ var Sphere = class _Sphere {
9888
10589
  this._derivationMode = chainCode ? "bip32" : "wif_hmac";
9889
10590
  }
9890
10591
  if (chainCode) {
9891
- await this._storage.set(STORAGE_KEYS.CHAIN_CODE, chainCode);
10592
+ await this._storage.set(STORAGE_KEYS_GLOBAL.CHAIN_CODE, chainCode);
9892
10593
  }
9893
10594
  if (derivationPath) {
9894
- await this._storage.set(STORAGE_KEYS.DERIVATION_PATH, derivationPath);
10595
+ await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_PATH, derivationPath);
9895
10596
  }
9896
10597
  const effectiveBasePath = basePath ?? DEFAULT_BASE_PATH;
9897
10598
  this._basePath = effectiveBasePath;
9898
- await this._storage.set(STORAGE_KEYS.BASE_PATH, effectiveBasePath);
9899
- await this._storage.set(STORAGE_KEYS.DERIVATION_MODE, this._derivationMode);
9900
- await this._storage.set(STORAGE_KEYS.WALLET_SOURCE, this._source);
10599
+ await this._storage.set(STORAGE_KEYS_GLOBAL.BASE_PATH, effectiveBasePath);
10600
+ await this._storage.set(STORAGE_KEYS_GLOBAL.DERIVATION_MODE, this._derivationMode);
10601
+ await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_SOURCE, this._source);
9901
10602
  }
9902
10603
  /**
9903
10604
  * Mark wallet as fully created (after successful initialization)
@@ -9905,20 +10606,20 @@ var Sphere = class _Sphere {
9905
10606
  * marked as existing after all initialization steps succeed.
9906
10607
  */
9907
10608
  async finalizeWalletCreation() {
9908
- await this._storage.set(STORAGE_KEYS.WALLET_EXISTS, "true");
10609
+ await this._storage.set(STORAGE_KEYS_GLOBAL.WALLET_EXISTS, "true");
9909
10610
  }
9910
10611
  // ===========================================================================
9911
10612
  // Private: Identity Initialization
9912
10613
  // ===========================================================================
9913
10614
  async loadIdentityFromStorage() {
9914
- const encryptedMnemonic = await this._storage.get(STORAGE_KEYS.MNEMONIC);
9915
- const encryptedMasterKey = await this._storage.get(STORAGE_KEYS.MASTER_KEY);
9916
- const chainCode = await this._storage.get(STORAGE_KEYS.CHAIN_CODE);
9917
- const derivationPath = await this._storage.get(STORAGE_KEYS.DERIVATION_PATH);
9918
- const savedBasePath = await this._storage.get(STORAGE_KEYS.BASE_PATH);
9919
- const savedDerivationMode = await this._storage.get(STORAGE_KEYS.DERIVATION_MODE);
9920
- const savedSource = await this._storage.get(STORAGE_KEYS.WALLET_SOURCE);
9921
- const savedAddressIndex = await this._storage.get(STORAGE_KEYS.CURRENT_ADDRESS_INDEX);
10615
+ const encryptedMnemonic = await this._storage.get(STORAGE_KEYS_GLOBAL.MNEMONIC);
10616
+ const encryptedMasterKey = await this._storage.get(STORAGE_KEYS_GLOBAL.MASTER_KEY);
10617
+ const chainCode = await this._storage.get(STORAGE_KEYS_GLOBAL.CHAIN_CODE);
10618
+ const derivationPath = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_PATH);
10619
+ const savedBasePath = await this._storage.get(STORAGE_KEYS_GLOBAL.BASE_PATH);
10620
+ const savedDerivationMode = await this._storage.get(STORAGE_KEYS_GLOBAL.DERIVATION_MODE);
10621
+ const savedSource = await this._storage.get(STORAGE_KEYS_GLOBAL.WALLET_SOURCE);
10622
+ const savedAddressIndex = await this._storage.get(STORAGE_KEYS_GLOBAL.CURRENT_ADDRESS_INDEX);
9922
10623
  this._basePath = savedBasePath ?? DEFAULT_BASE_PATH;
9923
10624
  this._derivationMode = savedDerivationMode ?? "bip32";
9924
10625
  this._source = savedSource ?? "unknown";
@@ -9952,65 +10653,60 @@ var Sphere = class _Sphere {
9952
10653
  this._storage.setIdentity(this._identity);
9953
10654
  }
9954
10655
  await this.loadAddressNametags();
9955
- const savedNametag = await this._storage.get(STORAGE_KEYS.NAMETAG);
9956
10656
  if (this._currentAddressIndex > 0 && this._masterKey) {
9957
10657
  const addressInfo = this.deriveAddress(this._currentAddressIndex, false);
9958
10658
  const ipnsHash = sha256(addressInfo.publicKey, "hex").slice(0, 40);
9959
10659
  const predicateAddress = await deriveL3PredicateAddress(addressInfo.privateKey);
9960
- const nametag = this._addressNametags.get(this._currentAddressIndex);
10660
+ const addressId = getAddressId(predicateAddress);
10661
+ const nametagsMap = this._addressNametags.get(addressId);
10662
+ const nametag = nametagsMap?.get(0);
9961
10663
  this._identity = {
9962
10664
  privateKey: addressInfo.privateKey,
9963
- publicKey: addressInfo.publicKey,
9964
- address: addressInfo.address,
9965
- predicateAddress,
10665
+ chainPubkey: addressInfo.publicKey,
10666
+ l1Address: addressInfo.address,
10667
+ directAddress: predicateAddress,
9966
10668
  ipnsName: "12D3KooW" + ipnsHash,
9967
10669
  nametag
9968
10670
  };
9969
10671
  this._storage.setIdentity(this._identity);
9970
- console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.address);
9971
- } else {
9972
- if (savedNametag && this._identity) {
9973
- this._identity.nametag = savedNametag;
9974
- if (!this._addressNametags.has(0)) {
9975
- this._addressNametags.set(0, savedNametag);
9976
- }
9977
- console.log("[Sphere] Restored nametag:", savedNametag);
9978
- } else if (this._identity) {
9979
- const nametag = this._addressNametags.get(0);
9980
- if (nametag) {
9981
- this._identity.nametag = nametag;
9982
- console.log("[Sphere] Restored nametag from map:", nametag);
9983
- }
10672
+ console.log(`[Sphere] Restored to address ${this._currentAddressIndex}:`, this._identity.l1Address);
10673
+ } else if (this._identity) {
10674
+ const addressId = this.getCurrentAddressId();
10675
+ const nametagsMap = addressId ? this._addressNametags.get(addressId) : void 0;
10676
+ const nametag = nametagsMap?.get(0);
10677
+ if (nametag) {
10678
+ this._identity.nametag = nametag;
9984
10679
  }
9985
10680
  }
9986
10681
  }
9987
10682
  async initializeIdentityFromMnemonic(mnemonic, derivationPath) {
9988
- const path = derivationPath ?? DEFAULT_DERIVATION_PATH;
10683
+ const basePath = derivationPath ?? DEFAULT_BASE_PATH;
10684
+ const fullPath = `${basePath}/0/0`;
9989
10685
  const masterKey = identityFromMnemonicSync(mnemonic);
9990
10686
  const derivedKey = deriveKeyAtPath$1(
9991
10687
  masterKey.privateKey,
9992
10688
  masterKey.chainCode,
9993
- `${path}/0/0`
10689
+ fullPath
9994
10690
  );
9995
10691
  const publicKey = getPublicKey(derivedKey.privateKey);
9996
- const addressHash = hash160(publicKey);
10692
+ const address = publicKeyToAddress(publicKey, "alpha");
9997
10693
  const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
9998
10694
  const predicateAddress = await deriveL3PredicateAddress(derivedKey.privateKey);
9999
10695
  this._identity = {
10000
10696
  privateKey: derivedKey.privateKey,
10001
- publicKey,
10002
- address: "alpha1" + addressHash.slice(0, 38),
10003
- predicateAddress,
10697
+ chainPubkey: publicKey,
10698
+ l1Address: address,
10699
+ directAddress: predicateAddress,
10004
10700
  ipnsName: "12D3KooW" + ipnsHash
10005
10701
  };
10006
10702
  this._masterKey = masterKey;
10007
- console.log("[Sphere] Identity initialized from mnemonic, path:", path);
10008
10703
  }
10009
10704
  async initializeIdentityFromMasterKey(masterKey, chainCode, derivationPath) {
10010
- const path = derivationPath ?? DEFAULT_DERIVATION_PATH;
10705
+ const basePath = derivationPath ?? DEFAULT_BASE_PATH;
10706
+ const fullPath = `${basePath}/0/0`;
10011
10707
  let privateKey;
10012
10708
  if (chainCode) {
10013
- const derivedKey = deriveKeyAtPath$1(masterKey, chainCode, `${path}/0/0`);
10709
+ const derivedKey = deriveKeyAtPath$1(masterKey, chainCode, fullPath);
10014
10710
  privateKey = derivedKey.privateKey;
10015
10711
  this._masterKey = {
10016
10712
  privateKey: masterKey,
@@ -10021,17 +10717,16 @@ var Sphere = class _Sphere {
10021
10717
  this._masterKey = null;
10022
10718
  }
10023
10719
  const publicKey = getPublicKey(privateKey);
10024
- const addressHash = hash160(publicKey);
10720
+ const address = publicKeyToAddress(publicKey, "alpha");
10025
10721
  const ipnsHash = sha256(publicKey, "hex").slice(0, 40);
10026
10722
  const predicateAddress = await deriveL3PredicateAddress(privateKey);
10027
10723
  this._identity = {
10028
10724
  privateKey,
10029
- publicKey,
10030
- address: "alpha1" + addressHash.slice(0, 38),
10031
- predicateAddress,
10725
+ chainPubkey: publicKey,
10726
+ l1Address: address,
10727
+ directAddress: predicateAddress,
10032
10728
  ipnsName: "12D3KooW" + ipnsHash
10033
10729
  };
10034
- console.log("[Sphere] Identity initialized from master key, path:", path, "chainCode:", !!chainCode);
10035
10730
  }
10036
10731
  // ===========================================================================
10037
10732
  // Private: Provider & Module Initialization
@@ -10526,4 +11221,201 @@ declare namespace index {
10526
11221
  export { type index_BlockHeader as BlockHeader, CHARSET$1 as CHARSET, type index_ClassificationResult as ClassificationResult, type index_ClassifiedUTXO as ClassifiedUTXO, type index_ExportOptions as ExportOptions, type index_RestoreWalletResult as RestoreWalletResult, type index_StoredWallet as StoredWallet, type index_Transaction as Transaction, type index_TransactionDetail as TransactionDetail, type index_TransactionHistoryItem as TransactionHistoryItem, type index_TransactionInput as TransactionInput, type index_TransactionOutput as TransactionOutput, type index_TransactionPlan as TransactionPlan, type index_UTXO as UTXO, index_VESTING_THRESHOLD as VESTING_THRESHOLD, type index_VestingBalances as VestingBalances, type index_VestingMode as VestingMode, type index_Wallet as Wallet, type index_WalletAddress as WalletAddress, index_WalletAddressHelper as WalletAddressHelper, type index_WalletJSON as WalletJSON, type index_WalletJSONAddress as WalletJSONAddress, type index_WalletJSONDerivationMode as WalletJSONDerivationMode, type index_WalletJSONExportOptions as WalletJSONExportOptions, type index_WalletJSONImportResult as WalletJSONImportResult, type index_WalletJSONSource as WalletJSONSource, addressToScriptHash$1 as addressToScriptHash, index_broadcast as broadcast, index_buildSegWitTransaction as buildSegWitTransaction, index_collectUtxosForAmount as collectUtxosForAmount, computeHash160$1 as computeHash160, index_connect as connect, convertBits$1 as convertBits, index_createAndSignTransaction as createAndSignTransaction, createBech32$1 as createBech32, index_createScriptPubKey as createScriptPubKey, index_createTransactionPlan as createTransactionPlan, decodeBech32$1 as decodeBech32, decrypt$1 as decrypt, decryptWallet$1 as decryptWallet, index_deriveChildKey as deriveChildKey, index_deriveChildKeyBIP32 as deriveChildKeyBIP32, index_deriveKeyAtPath as deriveKeyAtPath, index_disconnect as disconnect, domIdToPath$1 as domIdToPath, ec$1 as ec, encodeBech32$1 as encodeBech32, encrypt$1 as encrypt, encryptWallet$1 as encryptWallet, index_generateAddressFromMasterKey as generateAddressFromMasterKey, generateAddressInfo$1 as generateAddressInfo, index_generateHDAddress as generateHDAddress, index_generateHDAddressBIP32 as generateHDAddressBIP32, index_generateMasterKeyFromSeed as generateMasterKeyFromSeed, generatePrivateKey$1 as generatePrivateKey, index_getBalance as getBalance, index_getBlockHeader as getBlockHeader, index_getCurrentBlockHeight as getCurrentBlockHeight, getIndexFromPath$1 as getIndexFromPath, index_getTransaction as getTransaction, index_getTransactionHistory as getTransactionHistory, index_getUtxo as getUtxo, hash160$1 as hash160, hash160ToBytes$1 as hash160ToBytes, hexToWIF$1 as hexToWIF, isChangePath$1 as isChangePath, index_isWebSocketConnected as isWebSocketConnected, parsePathComponents$1 as parsePathComponents, pathToDOMId$1 as pathToDOMId, privateKeyToAddressInfo$1 as privateKeyToAddressInfo, publicKeyToAddress$1 as publicKeyToAddress, index_rpc as rpc, index_sendAlpha as sendAlpha, index_subscribeBlocks as subscribeBlocks, index_vestingClassifier as vestingClassifier, index_vestingState as vestingState, index_waitForConnection as waitForConnection };
10527
11222
  }
10528
11223
 
10529
- export { type AddressInfo, type AggregatorClient, type AggregatorEvent, type AggregatorEventCallback, type AggregatorEventType, type AggregatorProvider, type AggregatorProviderConfig, type BaseProvider, type BroadcastHandler, type BroadcastMessage, type CMasterKeyData, COIN_TYPES, CommunicationsModule$1 as CommunicationsModule, type CommunicationsModuleConfig, type CommunicationsModuleDependencies, DEFAULT_AGGREGATOR_TIMEOUT, DEFAULT_AGGREGATOR_URL, DEFAULT_DERIVATION_PATH$1 as DEFAULT_DERIVATION_PATH, DEFAULT_ELECTRUM_URL, DEFAULT_IPFS_BOOTSTRAP_PEERS, DEFAULT_IPFS_GATEWAYS, DEFAULT_NOSTR_RELAYS, DEV_AGGREGATOR_URL, type DecryptionProgressCallback, type DerivationMode, type DirectMessage, type ExtendedValidationResult, type FullIdentity, type Identity, type IdentityConfig, type InclusionProof, type IncomingBroadcast, type IncomingMessage, type IncomingPaymentRequest$1 as IncomingPaymentRequest, type IncomingTokenTransfer, type IncomingTransfer, type InvalidatedNametagEntry, index as L1, type L1Balance, L1PaymentsModule$1 as L1PaymentsModule, type L1PaymentsModuleConfig, type L1PaymentsModuleDependencies, type L1SendRequest, type L1SendResult, type L1Transaction, type L1Utxo, LIMITS$1 as LIMITS, type LegacyFileImportOptions, type LegacyFileInfo, type LegacyFileParseResult, type LegacyFileParsedData, type LegacyFileType, type LoadResult, type LoggingConfig, type MessageHandler, type MintOutboxEntry, type MintParams, type MintResult, NETWORKS, NOSTR_EVENT_KINDS, type NametagData, type NetworkType, type OracleEvent, type OracleEventCallback, type OracleEventType, type OracleProvider, type OutboxEntry, type OutgoingPaymentRequest, type ParsedStorageData, type PaymentRequest, type PaymentRequestHandler$1 as PaymentRequestHandler, type PaymentRequestResponse, type PaymentRequestResponseHandler$1 as PaymentRequestResponseHandler, type PaymentRequestResponseType$1 as PaymentRequestResponseType, type PaymentRequestResult, type PaymentRequestStatus, PaymentsModule$1 as PaymentsModule, type PaymentsModuleConfig, type PaymentsModuleDependencies, type ProviderMetadata, type ProviderStatus, STORAGE_KEYS$1 as STORAGE_KEYS, STORAGE_PREFIX$1 as STORAGE_PREFIX, type SaveResult, type SpentTokenInfo, type SpentTokenResult, Sphere$1 as Sphere, type SphereConfig, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereEventHandler, type SphereEventMap, type SphereEventType, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type StorageEvent, type StorageEventCallback, type StorageEventType, type StorageProvider, type StorageProviderConfig, type SubmitResult, type SyncResult, TEST_AGGREGATOR_URL, TEST_ELECTRUM_URL, TEST_NOSTR_RELAYS, TIMEOUTS, type Token, type TokenBalance, type TokenState, type TokenStatus, type TokenStorageProvider, type TokenTransferHandler, type TokenTransferPayload, type ValidationResult as TokenValidationResult, TokenValidator, type TombstoneEntry, type TransferCommitment, type TransferRequest, type TransferResult, type TransferStatus, type TransportEvent, type TransportEventCallback, type TransportEventType, type TransportProvider, type TransportProviderConfig, type TrustBaseLoader, type TxfAuthenticator, type TxfGenesis, type TxfGenesisData, type TxfInclusionProof, type TxfIntegrity, type TxfInvalidEntry, type TxfMerkleStep, type TxfMerkleTreePath, type TxfMeta, type TxfOutboxEntry, type TxfSentEntry, type TxfState, type TxfStorageData, type TxfStorageDataBase, type TxfToken, type TxfTombstone, type TxfTransaction, type ValidationAction, type ValidationIssue, type ValidationResult$1 as ValidationResult, type WaitOptions, type WalletDatInfo, type WalletInfo, type WalletJSON$1 as WalletJSON, type WalletJSONExportOptions$1 as WalletJSONExportOptions, type WalletSource, archivedKeyFromTokenId$1 as archivedKeyFromTokenId, base58Decode$1 as base58Decode, base58Encode$1 as base58Encode, buildTxfStorageData$1 as buildTxfStorageData, bytesToHex$1 as bytesToHex, countCommittedTransactions, createAddress, createCommunicationsModule$1 as createCommunicationsModule, createKeyPair, createL1PaymentsModule, createPaymentsModule$1 as createPaymentsModule, createSphere, createTokenValidator, decodeBech32$1 as decodeBech32, decryptCMasterKey$1 as decryptCMasterKey, decryptPrivateKey$1 as decryptPrivateKey, decryptTextFormatKey$1 as decryptTextFormatKey, deriveAddressInfo$1 as deriveAddressInfo, deriveChildKey$2 as deriveChildKey, deriveKeyAtPath$2 as deriveKeyAtPath, doubleSha256, encodeBech32$1 as encodeBech32, extractFromText$1 as extractFromText, findPattern$1 as findPattern, forkedKeyFromTokenIdAndState$1 as forkedKeyFromTokenIdAndState, formatAmount, generateMasterKey$1 as generateMasterKey, generateMnemonic, getAddressHrp, getCurrentStateHash$1 as getCurrentStateHash, getPublicKey$1 as getPublicKey, getSphere, getTokenId, hasMissingNewStateHash, hasUncommittedTransactions, hasValidTxfData, hash160$1 as hash160, hexToBytes, identityFromMnemonicSync$1 as identityFromMnemonicSync, initSphere, isArchivedKey$1 as isArchivedKey, isForkedKey$1 as isForkedKey, isSQLiteDatabase$1 as isSQLiteDatabase, isTextWalletEncrypted$1 as isTextWalletEncrypted, isTokenKey$1 as isTokenKey, isValidBech32, isValidPrivateKey$1 as isValidPrivateKey, isValidTokenId, isWalletDatEncrypted$1 as isWalletDatEncrypted, isWalletTextFormat$1 as isWalletTextFormat, keyFromTokenId$1 as keyFromTokenId, loadSphere, mnemonicToSeedSync, normalizeSdkTokenToStorage$1 as normalizeSdkTokenToStorage, objectToTxf, parseAndDecryptWalletDat$1 as parseAndDecryptWalletDat, parseAndDecryptWalletText$1 as parseAndDecryptWalletText, parseForkedKey$1 as parseForkedKey, parseTxfStorageData$1 as parseTxfStorageData, parseWalletDat$1 as parseWalletDat, parseWalletText$1 as parseWalletText, randomBytes, randomHex, randomUUID, ripemd160$1 as ripemd160, sha256$1 as sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, tokenIdFromArchivedKey$1 as tokenIdFromArchivedKey, tokenIdFromKey$1 as tokenIdFromKey, tokenToTxf$1 as tokenToTxf, txfToToken$1 as txfToToken, validateMnemonic };
11224
+ /**
11225
+ * Token Registry
11226
+ *
11227
+ * Provides token definitions (metadata) for known tokens on the Unicity network.
11228
+ * Uses bundled static data for offline access and consistency.
11229
+ */
11230
+ /**
11231
+ * Icon entry for token
11232
+ */
11233
+ interface TokenIcon {
11234
+ url: string;
11235
+ }
11236
+ /**
11237
+ * Token definition with full metadata
11238
+ */
11239
+ interface TokenDefinition {
11240
+ /** Network identifier (e.g., "unicity:testnet") */
11241
+ network: string;
11242
+ /** Asset kind - fungible or non-fungible */
11243
+ assetKind: 'fungible' | 'non-fungible';
11244
+ /** Token name (e.g., "bitcoin", "ethereum") */
11245
+ name: string;
11246
+ /** Token symbol (e.g., "BTC", "ETH") - only for fungible tokens */
11247
+ symbol?: string;
11248
+ /** Decimal places for display - only for fungible tokens */
11249
+ decimals?: number;
11250
+ /** Human-readable description */
11251
+ description: string;
11252
+ /** Icon URLs array */
11253
+ icons?: TokenIcon[];
11254
+ /** Hex-encoded coin ID (64 characters) */
11255
+ id: string;
11256
+ }
11257
+ /**
11258
+ * Network type for registry lookup
11259
+ */
11260
+ type RegistryNetwork = 'testnet' | 'mainnet' | 'dev';
11261
+ /**
11262
+ * Token Registry service
11263
+ *
11264
+ * Provides lookup functionality for token definitions by coin ID.
11265
+ * Uses singleton pattern for efficient memory usage.
11266
+ *
11267
+ * @example
11268
+ * ```ts
11269
+ * import { TokenRegistry } from '@unicitylabs/sphere-sdk';
11270
+ *
11271
+ * const registry = TokenRegistry.getInstance();
11272
+ * const def = registry.getDefinition('455ad8720656b08e8dbd5bac1f3c73eeea5431565f6c1c3af742b1aa12d41d89');
11273
+ * console.log(def?.symbol); // 'UCT'
11274
+ * ```
11275
+ */
11276
+ declare class TokenRegistry {
11277
+ private static instance;
11278
+ private readonly definitionsById;
11279
+ private readonly definitionsBySymbol;
11280
+ private readonly definitionsByName;
11281
+ private constructor();
11282
+ /**
11283
+ * Get singleton instance of TokenRegistry
11284
+ */
11285
+ static getInstance(): TokenRegistry;
11286
+ /**
11287
+ * Reset the singleton instance (useful for testing)
11288
+ */
11289
+ static resetInstance(): void;
11290
+ /**
11291
+ * Load registry data from bundled JSON
11292
+ */
11293
+ private loadRegistry;
11294
+ /**
11295
+ * Get token definition by hex coin ID
11296
+ * @param coinId - 64-character hex string
11297
+ * @returns Token definition or undefined if not found
11298
+ */
11299
+ getDefinition(coinId: string): TokenDefinition | undefined;
11300
+ /**
11301
+ * Get token definition by symbol (e.g., "UCT", "BTC")
11302
+ * @param symbol - Token symbol (case-insensitive)
11303
+ * @returns Token definition or undefined if not found
11304
+ */
11305
+ getDefinitionBySymbol(symbol: string): TokenDefinition | undefined;
11306
+ /**
11307
+ * Get token definition by name (e.g., "bitcoin", "ethereum")
11308
+ * @param name - Token name (case-insensitive)
11309
+ * @returns Token definition or undefined if not found
11310
+ */
11311
+ getDefinitionByName(name: string): TokenDefinition | undefined;
11312
+ /**
11313
+ * Get token symbol for a coin ID
11314
+ * @param coinId - 64-character hex string
11315
+ * @returns Symbol (e.g., "UCT") or truncated ID if not found
11316
+ */
11317
+ getSymbol(coinId: string): string;
11318
+ /**
11319
+ * Get token name for a coin ID
11320
+ * @param coinId - 64-character hex string
11321
+ * @returns Name (e.g., "Bitcoin") or coin ID if not found
11322
+ */
11323
+ getName(coinId: string): string;
11324
+ /**
11325
+ * Get decimal places for a coin ID
11326
+ * @param coinId - 64-character hex string
11327
+ * @returns Decimals or 0 if not found
11328
+ */
11329
+ getDecimals(coinId: string): number;
11330
+ /**
11331
+ * Get icon URL for a coin ID
11332
+ * @param coinId - 64-character hex string
11333
+ * @param preferPng - Prefer PNG format over SVG
11334
+ * @returns Icon URL or null if not found
11335
+ */
11336
+ getIconUrl(coinId: string, preferPng?: boolean): string | null;
11337
+ /**
11338
+ * Check if a coin ID is known in the registry
11339
+ * @param coinId - 64-character hex string
11340
+ * @returns true if the coin is in the registry
11341
+ */
11342
+ isKnown(coinId: string): boolean;
11343
+ /**
11344
+ * Get all token definitions
11345
+ * @returns Array of all token definitions
11346
+ */
11347
+ getAllDefinitions(): TokenDefinition[];
11348
+ /**
11349
+ * Get all fungible token definitions
11350
+ * @returns Array of fungible token definitions
11351
+ */
11352
+ getFungibleTokens(): TokenDefinition[];
11353
+ /**
11354
+ * Get all non-fungible token definitions
11355
+ * @returns Array of non-fungible token definitions
11356
+ */
11357
+ getNonFungibleTokens(): TokenDefinition[];
11358
+ /**
11359
+ * Get coin ID by symbol
11360
+ * @param symbol - Token symbol (e.g., "UCT")
11361
+ * @returns Coin ID hex string or undefined if not found
11362
+ */
11363
+ getCoinIdBySymbol(symbol: string): string | undefined;
11364
+ /**
11365
+ * Get coin ID by name
11366
+ * @param name - Token name (e.g., "bitcoin")
11367
+ * @returns Coin ID hex string or undefined if not found
11368
+ */
11369
+ getCoinIdByName(name: string): string | undefined;
11370
+ }
11371
+ /**
11372
+ * Get token definition by coin ID
11373
+ * @param coinId - 64-character hex string
11374
+ * @returns Token definition or undefined
11375
+ */
11376
+ declare function getTokenDefinition(coinId: string): TokenDefinition | undefined;
11377
+ /**
11378
+ * Get token symbol by coin ID
11379
+ * @param coinId - 64-character hex string
11380
+ * @returns Symbol or truncated ID
11381
+ */
11382
+ declare function getTokenSymbol(coinId: string): string;
11383
+ /**
11384
+ * Get token name by coin ID
11385
+ * @param coinId - 64-character hex string
11386
+ * @returns Name or coin ID
11387
+ */
11388
+ declare function getTokenName(coinId: string): string;
11389
+ /**
11390
+ * Get token decimals by coin ID
11391
+ * @param coinId - 64-character hex string
11392
+ * @returns Decimals or 0
11393
+ */
11394
+ declare function getTokenDecimals(coinId: string): number;
11395
+ /**
11396
+ * Get token icon URL by coin ID
11397
+ * @param coinId - 64-character hex string
11398
+ * @param preferPng - Prefer PNG over SVG
11399
+ * @returns Icon URL or null
11400
+ */
11401
+ declare function getTokenIconUrl(coinId: string, preferPng?: boolean): string | null;
11402
+ /**
11403
+ * Check if coin ID is in registry
11404
+ * @param coinId - 64-character hex string
11405
+ * @returns true if known
11406
+ */
11407
+ declare function isKnownToken(coinId: string): boolean;
11408
+ /**
11409
+ * Get coin ID by symbol
11410
+ * @param symbol - Token symbol (e.g., "UCT")
11411
+ * @returns Coin ID or undefined
11412
+ */
11413
+ declare function getCoinIdBySymbol(symbol: string): string | undefined;
11414
+ /**
11415
+ * Get coin ID by name
11416
+ * @param name - Token name (e.g., "bitcoin")
11417
+ * @returns Coin ID or undefined
11418
+ */
11419
+ declare function getCoinIdByName(name: string): string | undefined;
11420
+
11421
+ export { type AddressInfo, type AggregatorClient, type AggregatorEvent, type AggregatorEventCallback, type AggregatorEventType, type AggregatorProvider, type AggregatorProviderConfig, type BaseProvider, type BroadcastHandler, type BroadcastMessage, type CMasterKeyData, COIN_TYPES, CommunicationsModule$1 as CommunicationsModule, type CommunicationsModuleConfig, type CommunicationsModuleDependencies, DEFAULT_AGGREGATOR_TIMEOUT, DEFAULT_AGGREGATOR_URL, DEFAULT_DERIVATION_PATH, DEFAULT_ELECTRUM_URL, DEFAULT_IPFS_BOOTSTRAP_PEERS, DEFAULT_IPFS_GATEWAYS, DEFAULT_NOSTR_RELAYS, DEV_AGGREGATOR_URL, type DecryptionProgressCallback, type DerivationMode, type DirectMessage, type ExtendedValidationResult, type FullIdentity, type Identity, type IdentityConfig, type InclusionProof, type IncomingBroadcast, type IncomingMessage, type IncomingPaymentRequest$1 as IncomingPaymentRequest, type IncomingTokenTransfer, type IncomingTransfer, type InvalidatedNametagEntry, index as L1, type L1Balance, L1PaymentsModule$1 as L1PaymentsModule, type L1PaymentsModuleConfig, type L1PaymentsModuleDependencies, type L1SendRequest, type L1SendResult, type L1Transaction, type L1Utxo, LIMITS$1 as LIMITS, type LegacyFileImportOptions, type LegacyFileInfo, type LegacyFileParseResult, type LegacyFileParsedData, type LegacyFileType, type LoadResult, type LoggingConfig, type MessageHandler, type MintOutboxEntry, type MintParams, type MintResult, NETWORKS, NOSTR_EVENT_KINDS, type NametagData, type NetworkType, type OracleEvent, type OracleEventCallback, type OracleEventType, type OracleProvider, type OutboxEntry, type OutgoingPaymentRequest, type ParsedStorageData, type PaymentRequest, type PaymentRequestHandler$1 as PaymentRequestHandler, type PaymentRequestResponse, type PaymentRequestResponseHandler$1 as PaymentRequestResponseHandler, type PaymentRequestResponseType$1 as PaymentRequestResponseType, type PaymentRequestResult, type PaymentRequestStatus, PaymentsModule$1 as PaymentsModule, type PaymentsModuleConfig, type PaymentsModuleDependencies, type ProviderMetadata, type ProviderStatus, type RegistryNetwork, STORAGE_KEYS, STORAGE_PREFIX, type SaveResult, type SpentTokenInfo, type SpentTokenResult, Sphere$1 as Sphere, type SphereConfig, type SphereCreateOptions, SphereError, type SphereErrorCode, type SphereEventHandler, type SphereEventMap, type SphereEventType, type SphereInitOptions, type SphereInitResult, type SphereLoadOptions, type StorageEvent, type StorageEventCallback, type StorageEventType, type StorageProvider, type StorageProviderConfig, type SubmitResult, type SyncResult, TEST_AGGREGATOR_URL, TEST_ELECTRUM_URL, TEST_NOSTR_RELAYS, TIMEOUTS, type Token, type TokenBalance, type TokenDefinition, type TokenIcon, TokenRegistry, type TokenState, type TokenStatus, type TokenStorageProvider, type TokenTransferHandler, type TokenTransferPayload, type ValidationResult as TokenValidationResult, TokenValidator, type TombstoneEntry, type TransferCommitment, type TransferRequest, type TransferResult, type TransferStatus, type TransportEvent, type TransportEventCallback, type TransportEventType, type TransportProvider, type TransportProviderConfig, type TrustBaseLoader, type TxfAuthenticator, type TxfGenesis, type TxfGenesisData, type TxfInclusionProof, type TxfIntegrity, type TxfInvalidEntry, type TxfMerkleStep, type TxfMerkleTreePath, type TxfMeta, type TxfOutboxEntry, type TxfSentEntry, type TxfState, type TxfStorageData, type TxfStorageDataBase, type TxfToken, type TxfTombstone, type TxfTransaction, type ValidationAction, type ValidationIssue, type ValidationResult$1 as ValidationResult, type WaitOptions, type WalletDatInfo, type WalletInfo, type WalletJSON$1 as WalletJSON, type WalletJSONExportOptions$1 as WalletJSONExportOptions, type WalletSource, archivedKeyFromTokenId$1 as archivedKeyFromTokenId, base58Decode$1 as base58Decode, base58Encode$1 as base58Encode, buildTxfStorageData$1 as buildTxfStorageData, bytesToHex$1 as bytesToHex, countCommittedTransactions, createAddress, createCommunicationsModule$1 as createCommunicationsModule, createKeyPair, createL1PaymentsModule, createPaymentsModule$1 as createPaymentsModule, createSphere, createTokenValidator, decodeBech32$1 as decodeBech32, decryptCMasterKey$1 as decryptCMasterKey, decryptPrivateKey$1 as decryptPrivateKey, decryptTextFormatKey$1 as decryptTextFormatKey, deriveAddressInfo$1 as deriveAddressInfo, deriveChildKey$2 as deriveChildKey, deriveKeyAtPath$2 as deriveKeyAtPath, doubleSha256, encodeBech32$1 as encodeBech32, extractFromText$1 as extractFromText, findPattern$1 as findPattern, forkedKeyFromTokenIdAndState$1 as forkedKeyFromTokenIdAndState, formatAmount, generateMasterKey$1 as generateMasterKey, generateMnemonic, getAddressHrp, getCoinIdByName, getCoinIdBySymbol, getCurrentStateHash$1 as getCurrentStateHash, getPublicKey$1 as getPublicKey, getSphere, getTokenDecimals, getTokenDefinition, getTokenIconUrl, getTokenId, getTokenName, getTokenSymbol, hasMissingNewStateHash, hasUncommittedTransactions, hasValidTxfData, hash160$1 as hash160, hexToBytes, identityFromMnemonicSync$1 as identityFromMnemonicSync, initSphere, isArchivedKey$1 as isArchivedKey, isForkedKey$1 as isForkedKey, isKnownToken, isSQLiteDatabase$1 as isSQLiteDatabase, isTextWalletEncrypted$1 as isTextWalletEncrypted, isTokenKey$1 as isTokenKey, isValidBech32, isValidPrivateKey$1 as isValidPrivateKey, isValidTokenId, isWalletDatEncrypted$1 as isWalletDatEncrypted, isWalletTextFormat$1 as isWalletTextFormat, keyFromTokenId$1 as keyFromTokenId, loadSphere, mnemonicToSeedSync, normalizeSdkTokenToStorage$1 as normalizeSdkTokenToStorage, objectToTxf, parseAndDecryptWalletDat$1 as parseAndDecryptWalletDat, parseAndDecryptWalletText$1 as parseAndDecryptWalletText, parseForkedKey$1 as parseForkedKey, parseTxfStorageData$1 as parseTxfStorageData, parseWalletDat$1 as parseWalletDat, parseWalletText$1 as parseWalletText, randomBytes, randomHex, randomUUID, ripemd160$1 as ripemd160, sha256$1 as sha256, sleep, sphereExists, toHumanReadable, toSmallestUnit, tokenIdFromArchivedKey$1 as tokenIdFromArchivedKey, tokenIdFromKey$1 as tokenIdFromKey, tokenToTxf$1 as tokenToTxf, txfToToken$1 as txfToToken, validateMnemonic };