@zubari/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +324 -0
  3. package/dist/SecureStorage-jO783AhC.d.mts +89 -0
  4. package/dist/SecureStorage-jO783AhC.d.ts +89 -0
  5. package/dist/SwapService-C0G8IXW2.d.mts +35 -0
  6. package/dist/SwapService-DZD0OJI_.d.ts +35 -0
  7. package/dist/WalletManager-DJjdq89b.d.mts +6106 -0
  8. package/dist/WalletManager-TiAdzqrn.d.ts +6106 -0
  9. package/dist/index-BLuxEdLp.d.mts +156 -0
  10. package/dist/index-BLuxEdLp.d.ts +156 -0
  11. package/dist/index-DO3T2HVe.d.ts +135 -0
  12. package/dist/index-fXVD8_D0.d.mts +135 -0
  13. package/dist/index.d.mts +67 -0
  14. package/dist/index.d.ts +67 -0
  15. package/dist/index.js +2411 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.mjs +2386 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/protocols/index.d.mts +181 -0
  20. package/dist/protocols/index.d.ts +181 -0
  21. package/dist/protocols/index.js +415 -0
  22. package/dist/protocols/index.js.map +1 -0
  23. package/dist/protocols/index.mjs +410 -0
  24. package/dist/protocols/index.mjs.map +1 -0
  25. package/dist/react/index.d.mts +49 -0
  26. package/dist/react/index.d.ts +49 -0
  27. package/dist/react/index.js +1573 -0
  28. package/dist/react/index.js.map +1 -0
  29. package/dist/react/index.mjs +1570 -0
  30. package/dist/react/index.mjs.map +1 -0
  31. package/dist/services/index.d.mts +198 -0
  32. package/dist/services/index.d.ts +198 -0
  33. package/dist/services/index.js +554 -0
  34. package/dist/services/index.js.map +1 -0
  35. package/dist/services/index.mjs +547 -0
  36. package/dist/services/index.mjs.map +1 -0
  37. package/dist/storage/index.d.mts +57 -0
  38. package/dist/storage/index.d.ts +57 -0
  39. package/dist/storage/index.js +442 -0
  40. package/dist/storage/index.js.map +1 -0
  41. package/dist/storage/index.mjs +435 -0
  42. package/dist/storage/index.mjs.map +1 -0
  43. package/dist/wallet/index.d.mts +8 -0
  44. package/dist/wallet/index.d.ts +8 -0
  45. package/dist/wallet/index.js +1678 -0
  46. package/dist/wallet/index.js.map +1 -0
  47. package/dist/wallet/index.mjs +1674 -0
  48. package/dist/wallet/index.mjs.map +1 -0
  49. package/package.json +136 -0
@@ -0,0 +1,435 @@
1
+ // src/storage/SecureStorage.ts
2
+ var KeychainStorageAdapter = class {
3
+ serviceName;
4
+ constructor(serviceName = "com.zubari.wallet") {
5
+ this.serviceName = serviceName;
6
+ }
7
+ async setItem(key, value) {
8
+ if (typeof global !== "undefined" && global.KeychainModule) {
9
+ await global.KeychainModule.setItem(this.serviceName, key, value);
10
+ } else {
11
+ throw new Error("Keychain not available on this platform");
12
+ }
13
+ }
14
+ async getItem(key) {
15
+ if (typeof global !== "undefined" && global.KeychainModule) {
16
+ return global.KeychainModule.getItem(this.serviceName, key);
17
+ }
18
+ throw new Error("Keychain not available on this platform");
19
+ }
20
+ async removeItem(key) {
21
+ if (typeof global !== "undefined" && global.KeychainModule) {
22
+ await global.KeychainModule.removeItem(this.serviceName, key);
23
+ } else {
24
+ throw new Error("Keychain not available on this platform");
25
+ }
26
+ }
27
+ async hasItem(key) {
28
+ const value = await this.getItem(key);
29
+ return value !== null;
30
+ }
31
+ async clear() {
32
+ if (typeof global !== "undefined" && global.KeychainModule) {
33
+ await global.KeychainModule.clear(this.serviceName);
34
+ } else {
35
+ throw new Error("Keychain not available on this platform");
36
+ }
37
+ }
38
+ };
39
+ var KeystoreStorageAdapter = class {
40
+ alias;
41
+ constructor(alias = "zubari_wallet_keys") {
42
+ this.alias = alias;
43
+ }
44
+ async setItem(key, value) {
45
+ if (typeof global !== "undefined" && global.KeystoreModule) {
46
+ await global.KeystoreModule.setItem(this.alias, key, value);
47
+ } else {
48
+ throw new Error("Keystore not available on this platform");
49
+ }
50
+ }
51
+ async getItem(key) {
52
+ if (typeof global !== "undefined" && global.KeystoreModule) {
53
+ return global.KeystoreModule.getItem(this.alias, key);
54
+ }
55
+ throw new Error("Keystore not available on this platform");
56
+ }
57
+ async removeItem(key) {
58
+ if (typeof global !== "undefined" && global.KeystoreModule) {
59
+ await global.KeystoreModule.removeItem(this.alias, key);
60
+ } else {
61
+ throw new Error("Keystore not available on this platform");
62
+ }
63
+ }
64
+ async hasItem(key) {
65
+ const value = await this.getItem(key);
66
+ return value !== null;
67
+ }
68
+ async clear() {
69
+ if (typeof global !== "undefined" && global.KeystoreModule) {
70
+ await global.KeystoreModule.clear(this.alias);
71
+ } else {
72
+ throw new Error("Keystore not available on this platform");
73
+ }
74
+ }
75
+ };
76
+ var WebEncryptedStorageAdapter = class {
77
+ encryptionKey = null;
78
+ storagePrefix;
79
+ constructor(storagePrefix = "zubari_") {
80
+ this.storagePrefix = storagePrefix;
81
+ }
82
+ /**
83
+ * Initialize with a password-derived key
84
+ */
85
+ async initialize(password) {
86
+ const encoder = new TextEncoder();
87
+ const salt = this.getSalt();
88
+ const keyMaterial = await crypto.subtle.importKey(
89
+ "raw",
90
+ encoder.encode(password),
91
+ "PBKDF2",
92
+ false,
93
+ ["deriveKey"]
94
+ );
95
+ this.encryptionKey = await crypto.subtle.deriveKey(
96
+ {
97
+ name: "PBKDF2",
98
+ salt: salt.buffer,
99
+ iterations: 1e5,
100
+ hash: "SHA-256"
101
+ },
102
+ keyMaterial,
103
+ { name: "AES-GCM", length: 256 },
104
+ false,
105
+ ["encrypt", "decrypt"]
106
+ );
107
+ }
108
+ getSalt() {
109
+ const saltKey = `${this.storagePrefix}salt`;
110
+ let saltHex = localStorage.getItem(saltKey);
111
+ if (!saltHex) {
112
+ const salt = crypto.getRandomValues(new Uint8Array(16));
113
+ saltHex = Array.from(salt).map((b) => b.toString(16).padStart(2, "0")).join("");
114
+ localStorage.setItem(saltKey, saltHex);
115
+ }
116
+ return new Uint8Array(
117
+ saltHex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16))
118
+ );
119
+ }
120
+ async setItem(key, value) {
121
+ if (!this.encryptionKey) {
122
+ throw new Error("Storage not initialized. Call initialize() first.");
123
+ }
124
+ const encoder = new TextEncoder();
125
+ const iv = crypto.getRandomValues(new Uint8Array(12));
126
+ const encrypted = await crypto.subtle.encrypt(
127
+ { name: "AES-GCM", iv },
128
+ this.encryptionKey,
129
+ encoder.encode(value)
130
+ );
131
+ const combined = new Uint8Array(iv.length + encrypted.byteLength);
132
+ combined.set(iv);
133
+ combined.set(new Uint8Array(encrypted), iv.length);
134
+ const base64 = btoa(String.fromCharCode(...combined));
135
+ localStorage.setItem(`${this.storagePrefix}${key}`, base64);
136
+ }
137
+ async getItem(key) {
138
+ if (!this.encryptionKey) {
139
+ throw new Error("Storage not initialized. Call initialize() first.");
140
+ }
141
+ const base64 = localStorage.getItem(`${this.storagePrefix}${key}`);
142
+ if (!base64) return null;
143
+ try {
144
+ const combined = new Uint8Array(
145
+ atob(base64).split("").map((c) => c.charCodeAt(0))
146
+ );
147
+ const iv = combined.slice(0, 12);
148
+ const encrypted = combined.slice(12);
149
+ const decrypted = await crypto.subtle.decrypt(
150
+ { name: "AES-GCM", iv },
151
+ this.encryptionKey,
152
+ encrypted
153
+ );
154
+ const decoder = new TextDecoder();
155
+ return decoder.decode(decrypted);
156
+ } catch {
157
+ return null;
158
+ }
159
+ }
160
+ async removeItem(key) {
161
+ localStorage.removeItem(`${this.storagePrefix}${key}`);
162
+ }
163
+ async hasItem(key) {
164
+ return localStorage.getItem(`${this.storagePrefix}${key}`) !== null;
165
+ }
166
+ async clear() {
167
+ const keysToRemove = [];
168
+ for (let i = 0; i < localStorage.length; i++) {
169
+ const key = localStorage.key(i);
170
+ if (key?.startsWith(this.storagePrefix)) {
171
+ keysToRemove.push(key);
172
+ }
173
+ }
174
+ keysToRemove.forEach((key) => localStorage.removeItem(key));
175
+ }
176
+ };
177
+ var MemoryStorageAdapter = class {
178
+ storage = /* @__PURE__ */ new Map();
179
+ async setItem(key, value) {
180
+ this.storage.set(key, value);
181
+ }
182
+ async getItem(key) {
183
+ return this.storage.get(key) || null;
184
+ }
185
+ async removeItem(key) {
186
+ this.storage.delete(key);
187
+ }
188
+ async hasItem(key) {
189
+ return this.storage.has(key);
190
+ }
191
+ async clear() {
192
+ this.storage.clear();
193
+ }
194
+ };
195
+ function createSecureStorage() {
196
+ if (typeof global !== "undefined" && global.nativeModuleProxy !== void 0) {
197
+ const Platform = global.Platform;
198
+ if (Platform?.OS === "ios") {
199
+ return new KeychainStorageAdapter();
200
+ } else if (Platform?.OS === "android") {
201
+ return new KeystoreStorageAdapter();
202
+ }
203
+ }
204
+ if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
205
+ return new WebEncryptedStorageAdapter();
206
+ }
207
+ return new MemoryStorageAdapter();
208
+ }
209
+
210
+ // src/security/KeyManager.ts
211
+ var KeyManager = class {
212
+ static ALGORITHM = "AES-GCM";
213
+ static KEY_LENGTH = 256;
214
+ static IV_LENGTH = 12;
215
+ static SALT_LENGTH = 16;
216
+ static PBKDF2_ITERATIONS = 1e5;
217
+ /**
218
+ * Encrypt a seed phrase with a password
219
+ */
220
+ static async encryptSeed(seed, password) {
221
+ const encoder = new TextEncoder();
222
+ const seedData = encoder.encode(seed);
223
+ const salt = crypto.getRandomValues(new Uint8Array(this.SALT_LENGTH));
224
+ const iv = crypto.getRandomValues(new Uint8Array(this.IV_LENGTH));
225
+ const key = await this.deriveKey(password, salt);
226
+ const encrypted = await crypto.subtle.encrypt(
227
+ { name: this.ALGORITHM, iv },
228
+ key,
229
+ seedData
230
+ );
231
+ const combined = new Uint8Array(salt.length + iv.length + encrypted.byteLength);
232
+ combined.set(salt, 0);
233
+ combined.set(iv, salt.length);
234
+ combined.set(new Uint8Array(encrypted), salt.length + iv.length);
235
+ return btoa(String.fromCharCode(...combined));
236
+ }
237
+ /**
238
+ * Decrypt a seed phrase with a password
239
+ */
240
+ static async decryptSeed(encryptedData, password) {
241
+ const combined = new Uint8Array(
242
+ atob(encryptedData).split("").map((c) => c.charCodeAt(0))
243
+ );
244
+ const salt = combined.slice(0, this.SALT_LENGTH);
245
+ const iv = combined.slice(this.SALT_LENGTH, this.SALT_LENGTH + this.IV_LENGTH);
246
+ const encrypted = combined.slice(this.SALT_LENGTH + this.IV_LENGTH);
247
+ const key = await this.deriveKey(password, salt);
248
+ const decrypted = await crypto.subtle.decrypt(
249
+ { name: this.ALGORITHM, iv },
250
+ key,
251
+ encrypted
252
+ );
253
+ const decoder = new TextDecoder();
254
+ return decoder.decode(decrypted);
255
+ }
256
+ /**
257
+ * Derive encryption key from password using PBKDF2
258
+ */
259
+ static async deriveKey(password, salt) {
260
+ const encoder = new TextEncoder();
261
+ const passwordData = encoder.encode(password);
262
+ const keyMaterial = await crypto.subtle.importKey(
263
+ "raw",
264
+ passwordData,
265
+ "PBKDF2",
266
+ false,
267
+ ["deriveKey"]
268
+ );
269
+ return crypto.subtle.deriveKey(
270
+ {
271
+ name: "PBKDF2",
272
+ salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength),
273
+ iterations: this.PBKDF2_ITERATIONS,
274
+ hash: "SHA-256"
275
+ },
276
+ keyMaterial,
277
+ { name: this.ALGORITHM, length: this.KEY_LENGTH },
278
+ false,
279
+ ["encrypt", "decrypt"]
280
+ );
281
+ }
282
+ /**
283
+ * Validate a BIP-39 seed phrase (basic validation)
284
+ */
285
+ static validateSeedPhrase(seed) {
286
+ const words = seed.trim().split(/\s+/);
287
+ const validWordCounts = [12, 15, 18, 21, 24];
288
+ return validWordCounts.includes(words.length);
289
+ }
290
+ /**
291
+ * Generate a random encryption key (for backup purposes)
292
+ */
293
+ static generateBackupKey() {
294
+ const bytes = crypto.getRandomValues(new Uint8Array(32));
295
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
296
+ }
297
+ };
298
+
299
+ // src/storage/BackupService.ts
300
+ var BackupService = class {
301
+ apiUrl;
302
+ accessToken;
303
+ constructor(apiUrl, accessToken) {
304
+ this.apiUrl = apiUrl;
305
+ this.accessToken = accessToken;
306
+ }
307
+ /**
308
+ * Export encrypted seed to S3
309
+ */
310
+ async exportSeedEncrypted(seed, password, networks = []) {
311
+ const encryptedSeed = await KeyManager.encryptSeed(seed, password);
312
+ const checksum = await this.generateChecksum(encryptedSeed);
313
+ const backup = {
314
+ metadata: {
315
+ version: 1,
316
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
317
+ checksum,
318
+ networks
319
+ },
320
+ encryptedSeed,
321
+ salt: this.extractSalt(encryptedSeed),
322
+ iv: this.extractIV(encryptedSeed)
323
+ };
324
+ const response = await fetch(`${this.apiUrl}/backups`, {
325
+ method: "POST",
326
+ headers: {
327
+ "Content-Type": "application/json",
328
+ Authorization: `Bearer ${this.accessToken}`
329
+ },
330
+ body: JSON.stringify({ backup: JSON.stringify(backup) })
331
+ });
332
+ if (!response.ok) {
333
+ const error = await response.json();
334
+ throw new Error(error.message || "Failed to create backup");
335
+ }
336
+ const result = await response.json();
337
+ return {
338
+ backupId: result.backupId,
339
+ checksum
340
+ };
341
+ }
342
+ /**
343
+ * Import encrypted seed from S3
344
+ */
345
+ async importSeedEncrypted(password) {
346
+ const response = await fetch(`${this.apiUrl}/backups/latest`, {
347
+ headers: {
348
+ Authorization: `Bearer ${this.accessToken}`
349
+ }
350
+ });
351
+ if (!response.ok) {
352
+ if (response.status === 404) {
353
+ throw new Error("No backup found");
354
+ }
355
+ const error = await response.json();
356
+ throw new Error(error.message || "Failed to fetch backup");
357
+ }
358
+ const result = await response.json();
359
+ const backup = JSON.parse(result.backup);
360
+ const checksum = await this.generateChecksum(backup.encryptedSeed);
361
+ if (checksum !== backup.metadata.checksum) {
362
+ throw new Error("Backup integrity check failed");
363
+ }
364
+ const seed = await KeyManager.decryptSeed(backup.encryptedSeed, password);
365
+ return seed;
366
+ }
367
+ /**
368
+ * List all backups
369
+ */
370
+ async listBackups() {
371
+ const response = await fetch(`${this.apiUrl}/backups`, {
372
+ headers: {
373
+ Authorization: `Bearer ${this.accessToken}`
374
+ }
375
+ });
376
+ if (!response.ok) {
377
+ const error = await response.json();
378
+ throw new Error(error.message || "Failed to list backups");
379
+ }
380
+ const result = await response.json();
381
+ return result.backups.map((b) => b.metadata);
382
+ }
383
+ /**
384
+ * Delete a backup
385
+ */
386
+ async deleteBackup(backupId) {
387
+ const response = await fetch(`${this.apiUrl}/backups/${backupId}`, {
388
+ method: "DELETE",
389
+ headers: {
390
+ Authorization: `Bearer ${this.accessToken}`
391
+ }
392
+ });
393
+ if (!response.ok) {
394
+ const error = await response.json();
395
+ throw new Error(error.message || "Failed to delete backup");
396
+ }
397
+ }
398
+ /**
399
+ * Verify backup can be decrypted
400
+ */
401
+ async verifyBackup(password) {
402
+ try {
403
+ await this.importSeedEncrypted(password);
404
+ return true;
405
+ } catch {
406
+ return false;
407
+ }
408
+ }
409
+ /**
410
+ * Generate SHA-256 checksum
411
+ */
412
+ async generateChecksum(data) {
413
+ const encoder = new TextEncoder();
414
+ const dataBuffer = encoder.encode(data);
415
+ const hashBuffer = await crypto.subtle.digest("SHA-256", dataBuffer);
416
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
417
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
418
+ }
419
+ /**
420
+ * Extract salt from encrypted data (first 32 hex chars)
421
+ */
422
+ extractSalt(encryptedData) {
423
+ return encryptedData.substring(0, 32);
424
+ }
425
+ /**
426
+ * Extract IV from encrypted data (chars 32-56)
427
+ */
428
+ extractIV(encryptedData) {
429
+ return encryptedData.substring(32, 56);
430
+ }
431
+ };
432
+
433
+ export { BackupService, KeychainStorageAdapter, KeystoreStorageAdapter, MemoryStorageAdapter, WebEncryptedStorageAdapter, createSecureStorage };
434
+ //# sourceMappingURL=index.mjs.map
435
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/SecureStorage.ts","../../src/security/KeyManager.ts","../../src/storage/BackupService.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Secure Storage Interface\n * Platform-agnostic interface for secure key storage\n */\nexport interface SecureStorageAdapter {\n /**\n * Store a value securely\n */\n setItem(key: string, value: string): Promise<void>;\n\n /**\n * Retrieve a value\n */\n getItem(key: string): Promise<string | null>;\n\n /**\n * Remove a value\n */\n removeItem(key: string): Promise<void>;\n\n /**\n * Check if a key exists\n */\n hasItem(key: string): Promise<boolean>;\n\n /**\n * Clear all stored values\n */\n clear(): Promise<void>;\n}\n\n/**\n * iOS Keychain Storage Adapter\n * Uses react-native-keychain for iOS Keychain access\n */\nexport class KeychainStorageAdapter implements SecureStorageAdapter {\n private serviceName: string;\n\n constructor(serviceName: string = 'com.zubari.wallet') {\n this.serviceName = serviceName;\n }\n\n async setItem(key: string, value: string): Promise<void> {\n // In React Native, use react-native-keychain\n // const Keychain = require('react-native-keychain');\n // await Keychain.setGenericPassword(key, value, { service: this.serviceName });\n\n // Placeholder for native implementation\n if (typeof global !== 'undefined' && (global as any).KeychainModule) {\n await (global as any).KeychainModule.setItem(this.serviceName, key, value);\n } else {\n throw new Error('Keychain not available on this platform');\n }\n }\n\n async getItem(key: string): Promise<string | null> {\n if (typeof global !== 'undefined' && (global as any).KeychainModule) {\n return (global as any).KeychainModule.getItem(this.serviceName, key);\n }\n throw new Error('Keychain not available on this platform');\n }\n\n async removeItem(key: string): Promise<void> {\n if (typeof global !== 'undefined' && (global as any).KeychainModule) {\n await (global as any).KeychainModule.removeItem(this.serviceName, key);\n } else {\n throw new Error('Keychain not available on this platform');\n }\n }\n\n async hasItem(key: string): Promise<boolean> {\n const value = await this.getItem(key);\n return value !== null;\n }\n\n async clear(): Promise<void> {\n if (typeof global !== 'undefined' && (global as any).KeychainModule) {\n await (global as any).KeychainModule.clear(this.serviceName);\n } else {\n throw new Error('Keychain not available on this platform');\n }\n }\n}\n\n/**\n * Android Keystore Storage Adapter\n * Uses Android Keystore for secure storage\n */\nexport class KeystoreStorageAdapter implements SecureStorageAdapter {\n private alias: string;\n\n constructor(alias: string = 'zubari_wallet_keys') {\n this.alias = alias;\n }\n\n async setItem(key: string, value: string): Promise<void> {\n // In React Native, use react-native-encrypted-storage or similar\n // const EncryptedStorage = require('react-native-encrypted-storage');\n // await EncryptedStorage.setItem(key, value);\n\n if (typeof global !== 'undefined' && (global as any).KeystoreModule) {\n await (global as any).KeystoreModule.setItem(this.alias, key, value);\n } else {\n throw new Error('Keystore not available on this platform');\n }\n }\n\n async getItem(key: string): Promise<string | null> {\n if (typeof global !== 'undefined' && (global as any).KeystoreModule) {\n return (global as any).KeystoreModule.getItem(this.alias, key);\n }\n throw new Error('Keystore not available on this platform');\n }\n\n async removeItem(key: string): Promise<void> {\n if (typeof global !== 'undefined' && (global as any).KeystoreModule) {\n await (global as any).KeystoreModule.removeItem(this.alias, key);\n } else {\n throw new Error('Keystore not available on this platform');\n }\n }\n\n async hasItem(key: string): Promise<boolean> {\n const value = await this.getItem(key);\n return value !== null;\n }\n\n async clear(): Promise<void> {\n if (typeof global !== 'undefined' && (global as any).KeystoreModule) {\n await (global as any).KeystoreModule.clear(this.alias);\n } else {\n throw new Error('Keystore not available on this platform');\n }\n }\n}\n\n/**\n * Web Encrypted LocalStorage Adapter\n * Uses Web Crypto API for encryption with localStorage\n */\nexport class WebEncryptedStorageAdapter implements SecureStorageAdapter {\n private encryptionKey: CryptoKey | null = null;\n private storagePrefix: string;\n\n constructor(storagePrefix: string = 'zubari_') {\n this.storagePrefix = storagePrefix;\n }\n\n /**\n * Initialize with a password-derived key\n */\n async initialize(password: string): Promise<void> {\n const encoder = new TextEncoder();\n const salt = this.getSalt();\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(password),\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n\n this.encryptionKey = await crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt.buffer as ArrayBuffer,\n iterations: 100000,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: 'AES-GCM', length: 256 },\n false,\n ['encrypt', 'decrypt']\n );\n }\n\n private getSalt(): Uint8Array {\n const saltKey = `${this.storagePrefix}salt`;\n let saltHex = localStorage.getItem(saltKey);\n\n if (!saltHex) {\n const salt = crypto.getRandomValues(new Uint8Array(16));\n saltHex = Array.from(salt)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n localStorage.setItem(saltKey, saltHex);\n }\n\n return new Uint8Array(\n saltHex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))\n );\n }\n\n async setItem(key: string, value: string): Promise<void> {\n if (!this.encryptionKey) {\n throw new Error('Storage not initialized. Call initialize() first.');\n }\n\n const encoder = new TextEncoder();\n const iv = crypto.getRandomValues(new Uint8Array(12));\n\n const encrypted = await crypto.subtle.encrypt(\n { name: 'AES-GCM', iv },\n this.encryptionKey,\n encoder.encode(value)\n );\n\n const combined = new Uint8Array(iv.length + encrypted.byteLength);\n combined.set(iv);\n combined.set(new Uint8Array(encrypted), iv.length);\n\n const base64 = btoa(String.fromCharCode(...combined));\n localStorage.setItem(`${this.storagePrefix}${key}`, base64);\n }\n\n async getItem(key: string): Promise<string | null> {\n if (!this.encryptionKey) {\n throw new Error('Storage not initialized. Call initialize() first.');\n }\n\n const base64 = localStorage.getItem(`${this.storagePrefix}${key}`);\n if (!base64) return null;\n\n try {\n const combined = new Uint8Array(\n atob(base64)\n .split('')\n .map((c) => c.charCodeAt(0))\n );\n\n const iv = combined.slice(0, 12);\n const encrypted = combined.slice(12);\n\n const decrypted = await crypto.subtle.decrypt(\n { name: 'AES-GCM', iv },\n this.encryptionKey,\n encrypted\n );\n\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n } catch {\n return null;\n }\n }\n\n async removeItem(key: string): Promise<void> {\n localStorage.removeItem(`${this.storagePrefix}${key}`);\n }\n\n async hasItem(key: string): Promise<boolean> {\n return localStorage.getItem(`${this.storagePrefix}${key}`) !== null;\n }\n\n async clear(): Promise<void> {\n const keysToRemove: string[] = [];\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key?.startsWith(this.storagePrefix)) {\n keysToRemove.push(key);\n }\n }\n\n keysToRemove.forEach((key) => localStorage.removeItem(key));\n }\n}\n\n/**\n * In-Memory Storage Adapter (for testing)\n */\nexport class MemoryStorageAdapter implements SecureStorageAdapter {\n private storage: Map<string, string> = new Map();\n\n async setItem(key: string, value: string): Promise<void> {\n this.storage.set(key, value);\n }\n\n async getItem(key: string): Promise<string | null> {\n return this.storage.get(key) || null;\n }\n\n async removeItem(key: string): Promise<void> {\n this.storage.delete(key);\n }\n\n async hasItem(key: string): Promise<boolean> {\n return this.storage.has(key);\n }\n\n async clear(): Promise<void> {\n this.storage.clear();\n }\n}\n\n/**\n * Secure Storage Factory\n * Creates appropriate storage adapter based on platform\n */\nexport function createSecureStorage(): SecureStorageAdapter {\n // Check for React Native\n if (\n typeof global !== 'undefined' &&\n (global as any).nativeModuleProxy !== undefined\n ) {\n // Check platform\n const Platform = (global as any).Platform;\n if (Platform?.OS === 'ios') {\n return new KeychainStorageAdapter();\n } else if (Platform?.OS === 'android') {\n return new KeystoreStorageAdapter();\n }\n }\n\n // Check for browser environment\n if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {\n return new WebEncryptedStorageAdapter();\n }\n\n // Fallback to memory storage (for Node.js/testing)\n return new MemoryStorageAdapter();\n}\n","/**\n * KeyManager - Secure key storage and encryption\n *\n * Handles seed phrase encryption using AES-256-GCM\n * with PBKDF2 key derivation from user password.\n */\nexport class KeyManager {\n private static readonly ALGORITHM = 'AES-GCM';\n private static readonly KEY_LENGTH = 256;\n private static readonly IV_LENGTH = 12;\n private static readonly SALT_LENGTH = 16;\n private static readonly PBKDF2_ITERATIONS = 100000;\n\n /**\n * Encrypt a seed phrase with a password\n */\n static async encryptSeed(seed: string, password: string): Promise<string> {\n const encoder = new TextEncoder();\n const seedData = encoder.encode(seed);\n\n // Generate random salt and IV\n const salt = crypto.getRandomValues(new Uint8Array(this.SALT_LENGTH));\n const iv = crypto.getRandomValues(new Uint8Array(this.IV_LENGTH));\n\n // Derive key from password\n const key = await this.deriveKey(password, salt);\n\n // Encrypt\n const encrypted = await crypto.subtle.encrypt(\n { name: this.ALGORITHM, iv },\n key,\n seedData\n );\n\n // Combine salt + iv + encrypted data\n const combined = new Uint8Array(salt.length + iv.length + encrypted.byteLength);\n combined.set(salt, 0);\n combined.set(iv, salt.length);\n combined.set(new Uint8Array(encrypted), salt.length + iv.length);\n\n // Return as base64\n return btoa(String.fromCharCode(...combined));\n }\n\n /**\n * Decrypt a seed phrase with a password\n */\n static async decryptSeed(encryptedData: string, password: string): Promise<string> {\n // Decode from base64\n const combined = new Uint8Array(\n atob(encryptedData)\n .split('')\n .map(c => c.charCodeAt(0))\n );\n\n // Extract salt, iv, and encrypted data\n const salt = combined.slice(0, this.SALT_LENGTH);\n const iv = combined.slice(this.SALT_LENGTH, this.SALT_LENGTH + this.IV_LENGTH);\n const encrypted = combined.slice(this.SALT_LENGTH + this.IV_LENGTH);\n\n // Derive key from password\n const key = await this.deriveKey(password, salt);\n\n // Decrypt\n const decrypted = await crypto.subtle.decrypt(\n { name: this.ALGORITHM, iv },\n key,\n encrypted\n );\n\n const decoder = new TextDecoder();\n return decoder.decode(decrypted);\n }\n\n /**\n * Derive encryption key from password using PBKDF2\n */\n private static async deriveKey(\n password: string,\n salt: Uint8Array\n ): Promise<CryptoKey> {\n const encoder = new TextEncoder();\n const passwordData = encoder.encode(password);\n\n // Import password as key material\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n passwordData,\n 'PBKDF2',\n false,\n ['deriveKey']\n );\n\n // Derive AES key\n return crypto.subtle.deriveKey(\n {\n name: 'PBKDF2',\n salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength) as ArrayBuffer,\n iterations: this.PBKDF2_ITERATIONS,\n hash: 'SHA-256',\n },\n keyMaterial,\n { name: this.ALGORITHM, length: this.KEY_LENGTH },\n false,\n ['encrypt', 'decrypt']\n );\n }\n\n /**\n * Validate a BIP-39 seed phrase (basic validation)\n */\n static validateSeedPhrase(seed: string): boolean {\n const words = seed.trim().split(/\\s+/);\n // BIP-39 supports 12, 15, 18, 21, or 24 words\n const validWordCounts = [12, 15, 18, 21, 24];\n return validWordCounts.includes(words.length);\n }\n\n /**\n * Generate a random encryption key (for backup purposes)\n */\n static generateBackupKey(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n}\n","import { KeyManager } from '../security/KeyManager';\n\n/**\n * Backup metadata\n */\nexport interface BackupMetadata {\n version: number;\n createdAt: string;\n checksum: string;\n networks: string[];\n}\n\n/**\n * Encrypted backup payload\n */\nexport interface EncryptedBackup {\n metadata: BackupMetadata;\n encryptedSeed: string;\n salt: string;\n iv: string;\n}\n\n/**\n * Backup Service\n * Handles encrypted seed backup to S3 and recovery\n */\nexport class BackupService {\n private apiUrl: string;\n private accessToken: string;\n\n constructor(apiUrl: string, accessToken: string) {\n this.apiUrl = apiUrl;\n this.accessToken = accessToken;\n }\n\n /**\n * Export encrypted seed to S3\n */\n async exportSeedEncrypted(\n seed: string,\n password: string,\n networks: string[] = []\n ): Promise<{ backupId: string; checksum: string }> {\n // Encrypt the seed\n const encryptedSeed = await KeyManager.encryptSeed(seed, password);\n\n // Generate checksum for integrity verification\n const checksum = await this.generateChecksum(encryptedSeed);\n\n // Create backup payload\n const backup: EncryptedBackup = {\n metadata: {\n version: 1,\n createdAt: new Date().toISOString(),\n checksum,\n networks,\n },\n encryptedSeed,\n salt: this.extractSalt(encryptedSeed),\n iv: this.extractIV(encryptedSeed),\n };\n\n // Upload to API (which stores in S3)\n const response = await fetch(`${this.apiUrl}/backups`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.accessToken}`,\n },\n body: JSON.stringify({ backup: JSON.stringify(backup) }),\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to create backup');\n }\n\n const result = await response.json();\n\n return {\n backupId: result.backupId,\n checksum,\n };\n }\n\n /**\n * Import encrypted seed from S3\n */\n async importSeedEncrypted(password: string): Promise<string> {\n // Fetch backup from API\n const response = await fetch(`${this.apiUrl}/backups/latest`, {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new Error('No backup found');\n }\n const error = await response.json();\n throw new Error(error.message || 'Failed to fetch backup');\n }\n\n const result = await response.json();\n const backup: EncryptedBackup = JSON.parse(result.backup);\n\n // Verify integrity\n const checksum = await this.generateChecksum(backup.encryptedSeed);\n if (checksum !== backup.metadata.checksum) {\n throw new Error('Backup integrity check failed');\n }\n\n // Decrypt the seed\n const seed = await KeyManager.decryptSeed(backup.encryptedSeed, password);\n\n return seed;\n }\n\n /**\n * List all backups\n */\n async listBackups(): Promise<BackupMetadata[]> {\n const response = await fetch(`${this.apiUrl}/backups`, {\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to list backups');\n }\n\n const result = await response.json();\n return result.backups.map((b: any) => b.metadata);\n }\n\n /**\n * Delete a backup\n */\n async deleteBackup(backupId: string): Promise<void> {\n const response = await fetch(`${this.apiUrl}/backups/${backupId}`, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.message || 'Failed to delete backup');\n }\n }\n\n /**\n * Verify backup can be decrypted\n */\n async verifyBackup(password: string): Promise<boolean> {\n try {\n await this.importSeedEncrypted(password);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Generate SHA-256 checksum\n */\n private async generateChecksum(data: string): Promise<string> {\n const encoder = new TextEncoder();\n const dataBuffer = encoder.encode(data);\n\n const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n\n /**\n * Extract salt from encrypted data (first 32 hex chars)\n */\n private extractSalt(encryptedData: string): string {\n return encryptedData.substring(0, 32);\n }\n\n /**\n * Extract IV from encrypted data (chars 32-56)\n */\n private extractIV(encryptedData: string): string {\n return encryptedData.substring(32, 56);\n }\n}\n\n/**\n * Backup routes handler (for API)\n */\nexport interface BackupRoutesConfig {\n s3Bucket: string;\n s3Prefix: string;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export { Z as ZubariWallet } from '../index-fXVD8_D0.mjs';
2
+ export { C as ChainBalance, M as MultiChainAddresses, S as SUPPORTED_CHAINS, W as WalletManager, b as WalletManagerConfig, a as WalletState } from '../WalletManager-DJjdq89b.mjs';
3
+ import '../index-BLuxEdLp.mjs';
4
+ import 'node_modules/viem/_types/actions/siwe/verifySiweMessage';
5
+ import 'node_modules/viem/_types/utils/ccip';
6
+ import 'viem';
7
+ import 'ethers';
8
+ import '../SecureStorage-jO783AhC.mjs';
@@ -0,0 +1,8 @@
1
+ export { Z as ZubariWallet } from '../index-DO3T2HVe.js';
2
+ export { C as ChainBalance, M as MultiChainAddresses, S as SUPPORTED_CHAINS, W as WalletManager, b as WalletManagerConfig, a as WalletState } from '../WalletManager-TiAdzqrn.js';
3
+ import '../index-BLuxEdLp.js';
4
+ import 'node_modules/viem/_types/actions/siwe/verifySiweMessage';
5
+ import 'node_modules/viem/_types/utils/ccip';
6
+ import 'viem';
7
+ import 'ethers';
8
+ import '../SecureStorage-jO783AhC.js';