@spacesops/wdk-react-native-core 1.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +551 -0
- package/dist/__mocks__/react.d.ts +40 -0
- package/dist/__mocks__/react.js +33 -0
- package/dist/__mocks__/react.js.map +1 -0
- package/dist/__mocks__/secureStorage.d.ts +26 -0
- package/dist/__mocks__/secureStorage.js +80 -0
- package/dist/__mocks__/secureStorage.js.map +1 -0
- package/dist/__tests__/hooks/useBalance.test.d.ts +6 -0
- package/dist/__tests__/hooks/useBalance.test.js +217 -0
- package/dist/__tests__/hooks/useBalance.test.js.map +1 -0
- package/dist/__tests__/hooks/useWallet.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWallet.test.js +105 -0
- package/dist/__tests__/hooks/useWallet.test.js.map +1 -0
- package/dist/__tests__/hooks/useWalletManager.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWalletManager.test.js +193 -0
- package/dist/__tests__/hooks/useWalletManager.test.js.map +1 -0
- package/dist/__tests__/hooks/useWdkApp.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWdkApp.test.js +55 -0
- package/dist/__tests__/hooks/useWdkApp.test.js.map +1 -0
- package/dist/__tests__/hooks/useWorklet.test.d.ts +6 -0
- package/dist/__tests__/hooks/useWorklet.test.js +168 -0
- package/dist/__tests__/hooks/useWorklet.test.js.map +1 -0
- package/dist/__tests__/provider/WdkAppProvider.test.d.ts +6 -0
- package/dist/__tests__/provider/WdkAppProvider.test.js +57 -0
- package/dist/__tests__/provider/WdkAppProvider.test.js.map +1 -0
- package/dist/__tests__/services/accountService.test.d.ts +6 -0
- package/dist/__tests__/services/accountService.test.js +216 -0
- package/dist/__tests__/services/accountService.test.js.map +1 -0
- package/dist/__tests__/services/addressService.test.d.ts +6 -0
- package/dist/__tests__/services/addressService.test.js +246 -0
- package/dist/__tests__/services/addressService.test.js.map +1 -0
- package/dist/__tests__/services/balanceService.test.d.ts +6 -0
- package/dist/__tests__/services/balanceService.test.js +333 -0
- package/dist/__tests__/services/balanceService.test.js.map +1 -0
- package/dist/__tests__/services/walletSetupService.test.d.ts +6 -0
- package/dist/__tests__/services/walletSetupService.test.js +304 -0
- package/dist/__tests__/services/walletSetupService.test.js.map +1 -0
- package/dist/__tests__/services/walletSwitchingService.test.d.ts +6 -0
- package/dist/__tests__/services/walletSwitchingService.test.js +209 -0
- package/dist/__tests__/services/walletSwitchingService.test.js.map +1 -0
- package/dist/__tests__/services/workletLifecycleService.test.d.ts +6 -0
- package/dist/__tests__/services/workletLifecycleService.test.js +451 -0
- package/dist/__tests__/services/workletLifecycleService.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +7 -0
- package/dist/__tests__/setup.js +49 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/storage/mmkvStorage.test.d.ts +6 -0
- package/dist/__tests__/storage/mmkvStorage.test.js +213 -0
- package/dist/__tests__/storage/mmkvStorage.test.js.map +1 -0
- package/dist/__tests__/store/walletStore.test.d.ts +4 -0
- package/dist/__tests__/store/walletStore.test.js +86 -0
- package/dist/__tests__/store/walletStore.test.js.map +1 -0
- package/dist/__tests__/store/workletStore.test.d.ts +4 -0
- package/dist/__tests__/store/workletStore.test.js +255 -0
- package/dist/__tests__/store/workletStore.test.js.map +1 -0
- package/dist/__tests__/types/hrpc.test.d.ts +4 -0
- package/dist/__tests__/types/hrpc.test.js +99 -0
- package/dist/__tests__/types/hrpc.test.js.map +1 -0
- package/dist/__tests__/utils/balanceUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/balanceUtils.test.js +133 -0
- package/dist/__tests__/utils/balanceUtils.test.js.map +1 -0
- package/dist/__tests__/utils/errorHandling.test.d.ts +6 -0
- package/dist/__tests__/utils/errorHandling.test.js +119 -0
- package/dist/__tests__/utils/errorHandling.test.js.map +1 -0
- package/dist/__tests__/utils/errorUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/errorUtils.test.js +133 -0
- package/dist/__tests__/utils/errorUtils.test.js.map +1 -0
- package/dist/__tests__/utils/initializationState.test.d.ts +6 -0
- package/dist/__tests__/utils/initializationState.test.js +243 -0
- package/dist/__tests__/utils/initializationState.test.js.map +1 -0
- package/dist/__tests__/utils/jsonUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/jsonUtils.test.js +118 -0
- package/dist/__tests__/utils/jsonUtils.test.js.map +1 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.d.ts +6 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.js +158 -0
- package/dist/__tests__/utils/mmkvKeyManager.test.js.map +1 -0
- package/dist/__tests__/utils/mnemonicUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/mnemonicUtils.test.js +40 -0
- package/dist/__tests__/utils/mnemonicUtils.test.js.map +1 -0
- package/dist/__tests__/utils/raceConditions.test.d.ts +6 -0
- package/dist/__tests__/utils/raceConditions.test.js +239 -0
- package/dist/__tests__/utils/raceConditions.test.js.map +1 -0
- package/dist/__tests__/utils/result.test.d.ts +4 -0
- package/dist/__tests__/utils/result.test.js +66 -0
- package/dist/__tests__/utils/result.test.js.map +1 -0
- package/dist/__tests__/utils/schemas.test.d.ts +4 -0
- package/dist/__tests__/utils/schemas.test.js +66 -0
- package/dist/__tests__/utils/schemas.test.js.map +1 -0
- package/dist/__tests__/utils/storeHelpers.test.d.ts +4 -0
- package/dist/__tests__/utils/storeHelpers.test.js +227 -0
- package/dist/__tests__/utils/storeHelpers.test.js.map +1 -0
- package/dist/__tests__/utils/typeGuards.test.d.ts +4 -0
- package/dist/__tests__/utils/typeGuards.test.js +175 -0
- package/dist/__tests__/utils/typeGuards.test.js.map +1 -0
- package/dist/__tests__/utils/validation.test.d.ts +4 -0
- package/dist/__tests__/utils/validation.test.js +126 -0
- package/dist/__tests__/utils/validation.test.js.map +1 -0
- package/dist/__tests__/utils/walletUtils.test.d.ts +4 -0
- package/dist/__tests__/utils/walletUtils.test.js +156 -0
- package/dist/__tests__/utils/walletUtils.test.js.map +1 -0
- package/dist/hooks/useBalance.d.ts +170 -0
- package/dist/hooks/useBalance.js +442 -0
- package/dist/hooks/useBalance.js.map +1 -0
- package/dist/hooks/useWallet.d.ts +43 -0
- package/dist/hooks/useWallet.js +193 -0
- package/dist/hooks/useWallet.js.map +1 -0
- package/dist/hooks/useWalletManager.d.ts +100 -0
- package/dist/hooks/useWalletManager.js +526 -0
- package/dist/hooks/useWalletManager.js.map +1 -0
- package/dist/hooks/useWdkApp.d.ts +66 -0
- package/dist/hooks/useWdkApp.js +74 -0
- package/dist/hooks/useWdkApp.js.map +1 -0
- package/dist/hooks/useWorklet.d.ts +66 -0
- package/dist/hooks/useWorklet.js +42 -0
- package/dist/hooks/useWorklet.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/provider/WdkAppProvider.d.ts +112 -0
- package/dist/provider/WdkAppProvider.js +558 -0
- package/dist/provider/WdkAppProvider.js.map +1 -0
- package/dist/services/accountService.d.ts +52 -0
- package/dist/services/accountService.js +119 -0
- package/dist/services/accountService.js.map +1 -0
- package/dist/services/addressService.d.ts +22 -0
- package/dist/services/addressService.js +110 -0
- package/dist/services/addressService.js.map +1 -0
- package/dist/services/balanceService.d.ts +114 -0
- package/dist/services/balanceService.js +208 -0
- package/dist/services/balanceService.js.map +1 -0
- package/dist/services/walletSetupService.d.ts +217 -0
- package/dist/services/walletSetupService.js +535 -0
- package/dist/services/walletSetupService.js.map +1 -0
- package/dist/services/walletSwitchingService.d.ts +48 -0
- package/dist/services/walletSwitchingService.js +143 -0
- package/dist/services/walletSwitchingService.js.map +1 -0
- package/dist/services/workletLifecycleService.d.ts +117 -0
- package/dist/services/workletLifecycleService.js +433 -0
- package/dist/services/workletLifecycleService.js.map +1 -0
- package/dist/storage/mmkvStorage.d.ts +44 -0
- package/dist/storage/mmkvStorage.js +348 -0
- package/dist/storage/mmkvStorage.js.map +1 -0
- package/dist/store/walletStore.d.ts +130 -0
- package/dist/store/walletStore.js +204 -0
- package/dist/store/walletStore.js.map +1 -0
- package/dist/store/workletStore.d.ts +121 -0
- package/dist/store/workletStore.js +256 -0
- package/dist/store/workletStore.js.map +1 -0
- package/dist/types/hrpc.d.ts +60 -0
- package/dist/types/hrpc.js +26 -0
- package/dist/types/hrpc.js.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/balanceUtils.d.ts +30 -0
- package/dist/utils/balanceUtils.js +86 -0
- package/dist/utils/balanceUtils.js.map +1 -0
- package/dist/utils/constants.d.ts +66 -0
- package/dist/utils/constants.js +73 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/errorHandling.d.ts +47 -0
- package/dist/utils/errorHandling.js +54 -0
- package/dist/utils/errorHandling.js.map +1 -0
- package/dist/utils/errorUtils.d.ts +89 -0
- package/dist/utils/errorUtils.js +264 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/dist/utils/initializationState.d.ts +129 -0
- package/dist/utils/initializationState.js +220 -0
- package/dist/utils/initializationState.js.map +1 -0
- package/dist/utils/jsonUtils.d.ts +21 -0
- package/dist/utils/jsonUtils.js +67 -0
- package/dist/utils/jsonUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +27 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mmkvKeyManager.d.ts +57 -0
- package/dist/utils/mmkvKeyManager.js +214 -0
- package/dist/utils/mmkvKeyManager.js.map +1 -0
- package/dist/utils/mnemonicUtils.d.ts +17 -0
- package/dist/utils/mnemonicUtils.js +28 -0
- package/dist/utils/mnemonicUtils.js.map +1 -0
- package/dist/utils/operationMutex.d.ts +69 -0
- package/dist/utils/operationMutex.js +150 -0
- package/dist/utils/operationMutex.js.map +1 -0
- package/dist/utils/result.d.ts +34 -0
- package/dist/utils/result.js +43 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/schemas.d.ts +365 -0
- package/dist/utils/schemas.js +152 -0
- package/dist/utils/schemas.js.map +1 -0
- package/dist/utils/storeHelpers.d.ts +112 -0
- package/dist/utils/storeHelpers.js +198 -0
- package/dist/utils/storeHelpers.js.map +1 -0
- package/dist/utils/typeGuards.d.ts +70 -0
- package/dist/utils/typeGuards.js +95 -0
- package/dist/utils/typeGuards.js.map +1 -0
- package/dist/utils/validation.d.ts +53 -0
- package/dist/utils/validation.js +152 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/walletStateHelpers.d.ts +62 -0
- package/dist/utils/walletStateHelpers.js +81 -0
- package/dist/utils/walletStateHelpers.js.map +1 -0
- package/dist/utils/walletUtils.d.ts +38 -0
- package/dist/utils/walletUtils.js +87 -0
- package/dist/utils/walletUtils.js.map +1 -0
- package/package.json +79 -0
- package/src/__mocks__/react.ts +34 -0
- package/src/__mocks__/secureStorage.ts +87 -0
- package/src/__tests__/hooks/useBalance.test.ts +286 -0
- package/src/__tests__/hooks/useWallet.test.ts +122 -0
- package/src/__tests__/hooks/useWalletManager.test.ts +271 -0
- package/src/__tests__/hooks/useWdkApp.test.tsx +59 -0
- package/src/__tests__/hooks/useWorklet.test.ts +195 -0
- package/src/__tests__/provider/WdkAppProvider.test.tsx +67 -0
- package/src/__tests__/services/accountService.test.ts +337 -0
- package/src/__tests__/services/addressService.test.ts +312 -0
- package/src/__tests__/services/balanceService.test.ts +411 -0
- package/src/__tests__/services/walletSetupService.test.ts +463 -0
- package/src/__tests__/services/walletSwitchingService.test.ts +258 -0
- package/src/__tests__/services/workletLifecycleService.test.ts +514 -0
- package/src/__tests__/setup.ts +54 -0
- package/src/__tests__/storage/mmkvStorage.test.ts +325 -0
- package/src/__tests__/store/walletStore.test.ts +101 -0
- package/src/__tests__/store/workletStore.test.ts +329 -0
- package/src/__tests__/types/hrpc.test.ts +125 -0
- package/src/__tests__/utils/balanceUtils.test.ts +151 -0
- package/src/__tests__/utils/errorHandling.test.ts +147 -0
- package/src/__tests__/utils/errorUtils.test.ts +170 -0
- package/src/__tests__/utils/initializationState.test.ts +337 -0
- package/src/__tests__/utils/jsonUtils.test.ts +131 -0
- package/src/__tests__/utils/mmkvKeyManager.test.ts +205 -0
- package/src/__tests__/utils/mnemonicUtils.test.ts +48 -0
- package/src/__tests__/utils/raceConditions.test.ts +292 -0
- package/src/__tests__/utils/result.test.ts +73 -0
- package/src/__tests__/utils/schemas.test.ts +82 -0
- package/src/__tests__/utils/storeHelpers.test.ts +323 -0
- package/src/__tests__/utils/typeGuards.test.ts +209 -0
- package/src/__tests__/utils/validation.test.ts +152 -0
- package/src/__tests__/utils/walletUtils.test.ts +195 -0
- package/src/hooks/useBalance.ts +597 -0
- package/src/hooks/useWallet.ts +288 -0
- package/src/hooks/useWalletManager.ts +654 -0
- package/src/hooks/useWdkApp.ts +78 -0
- package/src/hooks/useWorklet.ts +109 -0
- package/src/index.ts +112 -0
- package/src/provider/WdkAppProvider.tsx +764 -0
- package/src/services/accountService.ts +134 -0
- package/src/services/addressService.ts +125 -0
- package/src/services/balanceService.ts +291 -0
- package/src/services/walletSetupService.ts +695 -0
- package/src/services/walletSwitchingService.ts +157 -0
- package/src/services/workletLifecycleService.ts +561 -0
- package/src/storage/mmkvStorage.ts +417 -0
- package/src/store/walletStore.ts +301 -0
- package/src/store/workletStore.ts +340 -0
- package/src/types/hrpc.ts +78 -0
- package/src/types.ts +188 -0
- package/src/utils/balanceUtils.ts +96 -0
- package/src/utils/constants.ts +84 -0
- package/src/utils/errorHandling.md +163 -0
- package/src/utils/errorHandling.ts +61 -0
- package/src/utils/errorUtils.ts +300 -0
- package/src/utils/initializationState.ts +242 -0
- package/src/utils/jsonUtils.ts +75 -0
- package/src/utils/logger.ts +54 -0
- package/src/utils/mmkvKeyManager.ts +256 -0
- package/src/utils/mnemonicUtils.ts +35 -0
- package/src/utils/operationMutex.ts +181 -0
- package/src/utils/result.ts +57 -0
- package/src/utils/schemas.ts +190 -0
- package/src/utils/storeHelpers.ts +236 -0
- package/src/utils/typeGuards.ts +129 -0
- package/src/utils/validation.ts +174 -0
- package/src/utils/walletStateHelpers.ts +104 -0
- package/src/utils/walletUtils.ts +107 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides safe JSON stringification and validation utilities
|
|
5
|
+
* to prevent security issues and ensure data integrity.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validate that a value has a safe JSON structure
|
|
9
|
+
* Prevents prototype pollution and circular references
|
|
10
|
+
*/
|
|
11
|
+
export function validateJSONStructure(value) {
|
|
12
|
+
try {
|
|
13
|
+
// Check for circular references
|
|
14
|
+
const seen = new WeakSet();
|
|
15
|
+
function check(value) {
|
|
16
|
+
if (value === null || typeof value !== 'object') {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (seen.has(value)) {
|
|
20
|
+
return false; // Circular reference
|
|
21
|
+
}
|
|
22
|
+
seen.add(value);
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
return value.every(check);
|
|
25
|
+
}
|
|
26
|
+
// Check for prototype pollution
|
|
27
|
+
const proto = Object.getPrototypeOf(value);
|
|
28
|
+
// Reject objects with non-standard prototypes (not null, Object.prototype, or Array.prototype)
|
|
29
|
+
// Note: Objects created with Object.create(Array.prototype) should be rejected
|
|
30
|
+
if (proto !== null && proto !== Object.prototype) {
|
|
31
|
+
// Allow Array.prototype only for actual arrays (checked above)
|
|
32
|
+
// Reject objects that inherit from Array.prototype but aren't arrays
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return Object.values(value).every(check);
|
|
36
|
+
}
|
|
37
|
+
return check(value);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Safe JSON stringify with validation
|
|
45
|
+
* Validates structure before stringifying to prevent security issues
|
|
46
|
+
*
|
|
47
|
+
* @param value - Value to stringify
|
|
48
|
+
* @param space - Optional spacing for pretty printing
|
|
49
|
+
* @returns JSON string
|
|
50
|
+
* @throws Error if value cannot be safely stringified
|
|
51
|
+
*/
|
|
52
|
+
export function safeStringify(value, space) {
|
|
53
|
+
// Validate structure first
|
|
54
|
+
if (!validateJSONStructure(value)) {
|
|
55
|
+
throw new Error('Value contains circular references or unsafe prototype properties');
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
return JSON.stringify(value, null, space);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof Error) {
|
|
62
|
+
throw new Error(`Failed to stringify value: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
throw new Error('Failed to stringify value: Unknown error');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=jsonUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonUtils.js","sourceRoot":"","sources":["../../src/utils/jsonUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,CAAC;QACH,gCAAgC;QAChC,MAAM,IAAI,GAAG,IAAI,OAAO,EAAE,CAAA;QAE1B,SAAS,KAAK,CAAC,KAAc;YAC3B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAChD,OAAO,IAAI,CAAA;YACb,CAAC;YAED,IAAI,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC,EAAE,CAAC;gBAC9B,OAAO,KAAK,CAAA,CAAC,qBAAqB;YACpC,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC,CAAA;YAEzB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAC3B,CAAC;YAED,gCAAgC;YAChC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;YAC1C,+FAA+F;YAC/F,+EAA+E;YAC/E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;gBACjD,+DAA+D;gBAC/D,qEAAqE;gBACrE,OAAO,KAAK,CAAA;YACd,CAAC;YAED,OAAO,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACrE,CAAC;QAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,KAAc;IAC1D,2BAA2B;IAC3B,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAA;IACtF,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAChE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for development and production
|
|
3
|
+
*
|
|
4
|
+
* Provides controlled logging that can be disabled in production
|
|
5
|
+
* to improve performance and prevent information leakage.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Log a message (only in development)
|
|
9
|
+
*
|
|
10
|
+
* @param message - Message to log
|
|
11
|
+
* @param args - Additional arguments to log
|
|
12
|
+
*/
|
|
13
|
+
export declare function log(...args: unknown[]): void;
|
|
14
|
+
/**
|
|
15
|
+
* Log an error (always logged, but sanitized in production)
|
|
16
|
+
*
|
|
17
|
+
* @param message - Error message
|
|
18
|
+
* @param error - Error object or additional data
|
|
19
|
+
*/
|
|
20
|
+
export declare function logError(message: string, error?: unknown): void;
|
|
21
|
+
/**
|
|
22
|
+
* Log a warning (only in development)
|
|
23
|
+
*
|
|
24
|
+
* @param message - Warning message
|
|
25
|
+
* @param args - Additional arguments to log
|
|
26
|
+
*/
|
|
27
|
+
export declare function logWarn(...args: unknown[]): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for development and production
|
|
3
|
+
*
|
|
4
|
+
* Provides controlled logging that can be disabled in production
|
|
5
|
+
* to improve performance and prevent information leakage.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Check if we're in development mode
|
|
9
|
+
* React Native sets __DEV__ to true in development builds
|
|
10
|
+
*/
|
|
11
|
+
const isDevelopment = typeof __DEV__ !== 'undefined' ? __DEV__ : process.env.NODE_ENV !== 'production';
|
|
12
|
+
/**
|
|
13
|
+
* Log a message (only in development)
|
|
14
|
+
*
|
|
15
|
+
* @param message - Message to log
|
|
16
|
+
* @param args - Additional arguments to log
|
|
17
|
+
*/
|
|
18
|
+
export function log(...args) {
|
|
19
|
+
if (isDevelopment) {
|
|
20
|
+
console.log(...args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Log an error (always logged, but sanitized in production)
|
|
25
|
+
*
|
|
26
|
+
* @param message - Error message
|
|
27
|
+
* @param error - Error object or additional data
|
|
28
|
+
*/
|
|
29
|
+
export function logError(message, error) {
|
|
30
|
+
if (isDevelopment) {
|
|
31
|
+
console.error(message, error);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// In production, log sanitized errors only
|
|
35
|
+
// This prevents information leakage while still allowing error tracking
|
|
36
|
+
console.error(message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Log a warning (only in development)
|
|
41
|
+
*
|
|
42
|
+
* @param message - Warning message
|
|
43
|
+
* @param args - Additional arguments to log
|
|
44
|
+
*/
|
|
45
|
+
export function logWarn(...args) {
|
|
46
|
+
if (isDevelopment) {
|
|
47
|
+
console.warn(...args);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,aAAa,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;AAEtG;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,GAAG,IAAe;IACpC,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACtB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,KAAe;IACvD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC/B,CAAC;SAAM,CAAC;QACN,2CAA2C;QAC3C,wEAAwE;QACxE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACxB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,GAAG,IAAe;IACxC,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MMKV Encryption Key Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages encryption keys for MMKV storage on a per-account basis.
|
|
5
|
+
* Each account (identified by email/identifier) gets its own encryption key,
|
|
6
|
+
* allowing multiple accounts on the same device with isolated encrypted storage.
|
|
7
|
+
*
|
|
8
|
+
* SECURITY NOTE: MMKV stores NON-SENSITIVE data only (addresses, balances, metadata).
|
|
9
|
+
* Since the data is non-sensitive, we use DETERMINISTIC key derivation from account identifier.
|
|
10
|
+
* This allows the same account to access the same encrypted data across devices.
|
|
11
|
+
*
|
|
12
|
+
* IMPORTANT: For sensitive data (wallet seeds, encryption keys), use SecureStorage which
|
|
13
|
+
* uses randomly generated keys stored in the device keychain.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Account identifier type (typically email or user ID)
|
|
17
|
+
*/
|
|
18
|
+
export type AccountIdentifier = string;
|
|
19
|
+
/**
|
|
20
|
+
* Clear the key derivation cache
|
|
21
|
+
*
|
|
22
|
+
* Useful when switching accounts or when you want to free memory.
|
|
23
|
+
* Note: Keys will be re-derived on next access since derivation is deterministic.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Clear cache when user logs out
|
|
28
|
+
* clearKeyCache()
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearKeyCache(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Get MMKV encryption key for an account
|
|
34
|
+
*
|
|
35
|
+
* SECURITY: Since MMKV stores non-sensitive data, we use deterministic key derivation.
|
|
36
|
+
* The key is derived from the account identifier, allowing the same account to access
|
|
37
|
+
* the same encrypted data across devices.
|
|
38
|
+
*
|
|
39
|
+
* The key is NOT stored - it's derived on-demand from the account identifier.
|
|
40
|
+
* Results are cached since derivation is deterministic.
|
|
41
|
+
*
|
|
42
|
+
* This ensures:
|
|
43
|
+
* - Account data isolation (different accounts = different keys)
|
|
44
|
+
* - Cross-device compatibility (same account = same key)
|
|
45
|
+
* - No key storage needed (deterministic derivation)
|
|
46
|
+
*
|
|
47
|
+
* @param accountIdentifier - Account identifier (email or user ID)
|
|
48
|
+
* @returns Promise that resolves to encryption key (base64 string, 32 bytes)
|
|
49
|
+
* @throws Error if account identifier is invalid or key derivation fails
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const key = await getMMKVKey('user@example.com')
|
|
54
|
+
* const mmkv = createMMKV({ encryptionKey: key })
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function getMMKVKey(accountIdentifier: AccountIdentifier): Promise<string>;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MMKV Encryption Key Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages encryption keys for MMKV storage on a per-account basis.
|
|
5
|
+
* Each account (identified by email/identifier) gets its own encryption key,
|
|
6
|
+
* allowing multiple accounts on the same device with isolated encrypted storage.
|
|
7
|
+
*
|
|
8
|
+
* SECURITY NOTE: MMKV stores NON-SENSITIVE data only (addresses, balances, metadata).
|
|
9
|
+
* Since the data is non-sensitive, we use DETERMINISTIC key derivation from account identifier.
|
|
10
|
+
* This allows the same account to access the same encrypted data across devices.
|
|
11
|
+
*
|
|
12
|
+
* IMPORTANT: For sensitive data (wallet seeds, encryption keys), use SecureStorage which
|
|
13
|
+
* uses randomly generated keys stored in the device keychain.
|
|
14
|
+
*/
|
|
15
|
+
import * as Crypto from 'expo-crypto';
|
|
16
|
+
/**
|
|
17
|
+
* Convert Uint8Array to base64 string using standard encoding
|
|
18
|
+
* This implementation follows RFC 4648 and handles all edge cases correctly
|
|
19
|
+
*
|
|
20
|
+
* @param bytes - Uint8Array to convert
|
|
21
|
+
* @returns Base64 encoded string
|
|
22
|
+
*/
|
|
23
|
+
function bytesToBase64(bytes) {
|
|
24
|
+
// Try to use Buffer if available (common in React Native with polyfills)
|
|
25
|
+
if (typeof Buffer !== 'undefined') {
|
|
26
|
+
return Buffer.from(bytes).toString('base64');
|
|
27
|
+
}
|
|
28
|
+
// Fallback to manual encoding for environments without Buffer
|
|
29
|
+
const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
30
|
+
let result = '';
|
|
31
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
32
|
+
const a = bytes[i] ?? 0;
|
|
33
|
+
const b = i + 1 < bytes.length ? (bytes[i + 1] ?? 0) : 0;
|
|
34
|
+
const c = i + 2 < bytes.length ? (bytes[i + 2] ?? 0) : 0;
|
|
35
|
+
const bitmap = (a << 16) | (b << 8) | c;
|
|
36
|
+
result += base64Chars.charAt((bitmap >> 18) & 63);
|
|
37
|
+
result += base64Chars.charAt((bitmap >> 12) & 63);
|
|
38
|
+
if (i + 1 < bytes.length) {
|
|
39
|
+
result += base64Chars.charAt((bitmap >> 6) & 63);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result += '=';
|
|
43
|
+
}
|
|
44
|
+
if (i + 2 < bytes.length) {
|
|
45
|
+
result += base64Chars.charAt(bitmap & 63);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
result += '=';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Maximum number of keys to cache before evicting least recently used
|
|
55
|
+
* This prevents unbounded memory growth while maintaining performance
|
|
56
|
+
*/
|
|
57
|
+
const MAX_CACHE_SIZE = 100;
|
|
58
|
+
/**
|
|
59
|
+
* Cache for derived keys to avoid repeated async operations
|
|
60
|
+
* Since key derivation is deterministic, we can cache the results
|
|
61
|
+
* Uses LRU (Least Recently Used) eviction policy to limit memory usage
|
|
62
|
+
*/
|
|
63
|
+
const keyCache = new Map();
|
|
64
|
+
const keyAccessOrder = new Map();
|
|
65
|
+
let accessCounter = 0;
|
|
66
|
+
/**
|
|
67
|
+
* Evict least recently used key from cache when limit is reached
|
|
68
|
+
*/
|
|
69
|
+
function evictLRUKey() {
|
|
70
|
+
if (keyCache.size < MAX_CACHE_SIZE) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Find the least recently used key
|
|
74
|
+
let oldestKey = null;
|
|
75
|
+
let oldestAccess = Infinity;
|
|
76
|
+
for (const [key, accessTime] of keyAccessOrder.entries()) {
|
|
77
|
+
if (accessTime < oldestAccess) {
|
|
78
|
+
oldestAccess = accessTime;
|
|
79
|
+
oldestKey = key;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Remove the least recently used key
|
|
83
|
+
if (oldestKey !== null) {
|
|
84
|
+
keyCache.delete(oldestKey);
|
|
85
|
+
keyAccessOrder.delete(oldestKey);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function deriveKeyFromAccount(accountIdentifier) {
|
|
89
|
+
// Check cache first
|
|
90
|
+
const cachedKey = keyCache.get(accountIdentifier);
|
|
91
|
+
if (cachedKey !== undefined) {
|
|
92
|
+
// Update access time for LRU tracking
|
|
93
|
+
accessCounter++;
|
|
94
|
+
keyAccessOrder.set(accountIdentifier, accessCounter);
|
|
95
|
+
return cachedKey;
|
|
96
|
+
}
|
|
97
|
+
// Use a constant salt for key derivation
|
|
98
|
+
// This salt is public and part of the derivation algorithm
|
|
99
|
+
const SALT = 'wdk-mmkv-encryption-salt-v1';
|
|
100
|
+
const input = `${SALT}:${accountIdentifier}`;
|
|
101
|
+
// Use expo-crypto for production-grade SHA-256 hashing
|
|
102
|
+
// This is a well-tested, battle-hardened implementation
|
|
103
|
+
const hashHex = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, input);
|
|
104
|
+
// Convert hex string to base64 using standard encoding
|
|
105
|
+
// SHA-256 produces 64 hex characters (32 bytes)
|
|
106
|
+
// Convert hex to bytes, then to base64
|
|
107
|
+
const hexBytes = hashHex.match(/.{1,2}/g);
|
|
108
|
+
if (!hexBytes || hashHex.length !== 64) {
|
|
109
|
+
throw new Error(`Invalid SHA-256 hash format: expected 64 hex characters, got ${hashHex.length}`);
|
|
110
|
+
}
|
|
111
|
+
const hashBytes = new Uint8Array(hexBytes.map((byte) => parseInt(byte, 16)));
|
|
112
|
+
// Convert bytes to base64 using standard encoding
|
|
113
|
+
// Use a well-tested base64 encoding implementation
|
|
114
|
+
const key = bytesToBase64(hashBytes);
|
|
115
|
+
// Evict LRU key if cache is full
|
|
116
|
+
evictLRUKey();
|
|
117
|
+
// Cache the result for future use
|
|
118
|
+
accessCounter++;
|
|
119
|
+
keyCache.set(accountIdentifier, key);
|
|
120
|
+
keyAccessOrder.set(accountIdentifier, accessCounter);
|
|
121
|
+
return key;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Maximum length for account identifiers to prevent DoS attacks
|
|
125
|
+
* 256 characters is reasonable for emails and user IDs
|
|
126
|
+
*/
|
|
127
|
+
const MAX_ACCOUNT_IDENTIFIER_LENGTH = 256;
|
|
128
|
+
/**
|
|
129
|
+
* Validate account identifier input
|
|
130
|
+
*
|
|
131
|
+
* @param accountIdentifier - Account identifier to validate
|
|
132
|
+
* @throws Error if validation fails
|
|
133
|
+
*/
|
|
134
|
+
function validateAccountIdentifier(accountIdentifier) {
|
|
135
|
+
if (!accountIdentifier || typeof accountIdentifier !== 'string') {
|
|
136
|
+
throw new Error('Account identifier must be a non-empty string');
|
|
137
|
+
}
|
|
138
|
+
const trimmed = accountIdentifier.trim();
|
|
139
|
+
if (trimmed === '') {
|
|
140
|
+
throw new Error('Account identifier cannot be empty or whitespace only');
|
|
141
|
+
}
|
|
142
|
+
if (trimmed.length > MAX_ACCOUNT_IDENTIFIER_LENGTH) {
|
|
143
|
+
throw new Error(`Account identifier exceeds maximum length of ${MAX_ACCOUNT_IDENTIFIER_LENGTH} characters`);
|
|
144
|
+
}
|
|
145
|
+
// Check for valid UTF-8 encoding (basic check)
|
|
146
|
+
try {
|
|
147
|
+
// Ensure the string can be properly encoded
|
|
148
|
+
encodeURIComponent(trimmed);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
throw new Error('Account identifier contains invalid characters');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Clear the key derivation cache
|
|
156
|
+
*
|
|
157
|
+
* Useful when switching accounts or when you want to free memory.
|
|
158
|
+
* Note: Keys will be re-derived on next access since derivation is deterministic.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* // Clear cache when user logs out
|
|
163
|
+
* clearKeyCache()
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
export function clearKeyCache() {
|
|
167
|
+
keyCache.clear();
|
|
168
|
+
keyAccessOrder.clear();
|
|
169
|
+
accessCounter = 0;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get MMKV encryption key for an account
|
|
173
|
+
*
|
|
174
|
+
* SECURITY: Since MMKV stores non-sensitive data, we use deterministic key derivation.
|
|
175
|
+
* The key is derived from the account identifier, allowing the same account to access
|
|
176
|
+
* the same encrypted data across devices.
|
|
177
|
+
*
|
|
178
|
+
* The key is NOT stored - it's derived on-demand from the account identifier.
|
|
179
|
+
* Results are cached since derivation is deterministic.
|
|
180
|
+
*
|
|
181
|
+
* This ensures:
|
|
182
|
+
* - Account data isolation (different accounts = different keys)
|
|
183
|
+
* - Cross-device compatibility (same account = same key)
|
|
184
|
+
* - No key storage needed (deterministic derivation)
|
|
185
|
+
*
|
|
186
|
+
* @param accountIdentifier - Account identifier (email or user ID)
|
|
187
|
+
* @returns Promise that resolves to encryption key (base64 string, 32 bytes)
|
|
188
|
+
* @throws Error if account identifier is invalid or key derivation fails
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const key = await getMMKVKey('user@example.com')
|
|
193
|
+
* const mmkv = createMMKV({ encryptionKey: key })
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export async function getMMKVKey(accountIdentifier) {
|
|
197
|
+
// Validate input before processing
|
|
198
|
+
validateAccountIdentifier(accountIdentifier);
|
|
199
|
+
// Use trimmed identifier for consistency
|
|
200
|
+
const trimmedIdentifier = accountIdentifier.trim();
|
|
201
|
+
try {
|
|
202
|
+
// Derive key deterministically from account identifier
|
|
203
|
+
// No need to store it - same account identifier always produces same key
|
|
204
|
+
return await deriveKeyFromAccount(trimmedIdentifier);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
// Provide more context in error messages
|
|
208
|
+
if (error instanceof Error) {
|
|
209
|
+
throw new Error(`Failed to derive encryption key for account: ${error.message}`);
|
|
210
|
+
}
|
|
211
|
+
throw new Error(`Failed to derive encryption key for account: ${String(error)}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=mmkvKeyManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mmkvKeyManager.js","sourceRoot":"","sources":["../../src/utils/mmkvKeyManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mnemonic utility functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Validate a mnemonic phrase
|
|
6
|
+
*
|
|
7
|
+
* @param mnemonic - The mnemonic phrase to validate
|
|
8
|
+
* @returns true if the mnemonic is valid (12 or 24 words, all non-empty)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* validateMnemonic("word1 word2 ... word12") // true
|
|
13
|
+
* validateMnemonic("word1 word2 ... word24") // true
|
|
14
|
+
* validateMnemonic("word1 word2") // false (too few words)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateMnemonic(mnemonic: string): boolean;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mnemonic utility functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Validate a mnemonic phrase
|
|
6
|
+
*
|
|
7
|
+
* @param mnemonic - The mnemonic phrase to validate
|
|
8
|
+
* @returns true if the mnemonic is valid (12 or 24 words, all non-empty)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* validateMnemonic("word1 word2 ... word12") // true
|
|
13
|
+
* validateMnemonic("word1 word2 ... word24") // true
|
|
14
|
+
* validateMnemonic("word1 word2") // false (too few words)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export function validateMnemonic(mnemonic) {
|
|
18
|
+
const trimmed = mnemonic.trim();
|
|
19
|
+
// Normalize whitespace first (multiple spaces become single spaces)
|
|
20
|
+
// This handles cases like "word1 word2" where multiple spaces should be normalized
|
|
21
|
+
const normalized = trimmed.replace(/\s+/g, ' ');
|
|
22
|
+
// Split and validate
|
|
23
|
+
const words = normalized.split(' ');
|
|
24
|
+
const validLengths = [12, 24];
|
|
25
|
+
// Check word count and that all words are non-empty
|
|
26
|
+
return validLengths.includes(words.length) && words.every(word => word.length > 0);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=mnemonicUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonicUtils.js","sourceRoot":"","sources":["../../src/utils/mnemonicUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;IAE/B,oEAAoE;IACpE,oFAAoF;IACpF,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE/C,qBAAqB;IACrB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnC,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAE7B,oDAAoD;IACpD,OAAO,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACpF,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation Mutex - Prevents concurrent wallet operations
|
|
3
|
+
*
|
|
4
|
+
* This utility provides a mutex/lock mechanism to ensure only one wallet operation
|
|
5
|
+
* can execute at a time, preventing race conditions and state corruption.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Operation mutex result
|
|
9
|
+
*/
|
|
10
|
+
export interface MutexResult {
|
|
11
|
+
/** Whether the operation was acquired */
|
|
12
|
+
acquired: boolean;
|
|
13
|
+
/** Current operation description if mutex is held */
|
|
14
|
+
currentOperation: string | null;
|
|
15
|
+
/** Release function to call when operation completes */
|
|
16
|
+
release: () => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Try to acquire operation mutex
|
|
20
|
+
*
|
|
21
|
+
* @param operationDescription - Description of the operation (for debugging)
|
|
22
|
+
* @returns MutexResult with acquired status and release function
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const mutex = acquireOperationMutex('switchWallet')
|
|
27
|
+
* if (!mutex.acquired) {
|
|
28
|
+
* throw new Error(`Operation in progress: ${mutex.currentOperation}`)
|
|
29
|
+
* }
|
|
30
|
+
* try {
|
|
31
|
+
* // Perform operation
|
|
32
|
+
* } finally {
|
|
33
|
+
* mutex.release()
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function acquireOperationMutex(operationDescription: string): MutexResult;
|
|
38
|
+
/**
|
|
39
|
+
* Execute an operation with mutex protection
|
|
40
|
+
* Automatically acquires and releases mutex
|
|
41
|
+
* Includes timeout protection to prevent stuck operations
|
|
42
|
+
*
|
|
43
|
+
* @param operationDescription - Description of the operation
|
|
44
|
+
* @param operation - Async operation to execute
|
|
45
|
+
* @param timeoutMs - Optional timeout in milliseconds (default: 30000ms / 30 seconds)
|
|
46
|
+
* @returns Promise with operation result
|
|
47
|
+
* @throws Error if mutex cannot be acquired, operation fails, or timeout is exceeded
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* await withOperationMutex('switchWallet', async () => {
|
|
52
|
+
* await WalletSwitchingService.switchToWallet(walletId)
|
|
53
|
+
* })
|
|
54
|
+
*
|
|
55
|
+
* // With custom timeout
|
|
56
|
+
* await withOperationMutex('longOperation', async () => {
|
|
57
|
+
* await longRunningOperation()
|
|
58
|
+
* }, 60000) // 60 second timeout
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function withOperationMutex<T>(operationDescription: string, operation: () => Promise<T>, timeoutMs?: number): Promise<T>;
|
|
62
|
+
/**
|
|
63
|
+
* Check if an operation is currently in progress
|
|
64
|
+
*/
|
|
65
|
+
export declare function isOperationInProgress(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get current operation description
|
|
68
|
+
*/
|
|
69
|
+
export declare function getCurrentOperation(): string | null;
|