@oxyhq/services 5.16.40 → 5.16.42

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 (267) hide show
  1. package/lib/commonjs/adapters/expo/crypto.js +56 -0
  2. package/lib/commonjs/adapters/expo/crypto.js.map +1 -0
  3. package/lib/commonjs/adapters/expo/fetch.js +30 -0
  4. package/lib/commonjs/adapters/expo/fetch.js.map +1 -0
  5. package/lib/commonjs/adapters/expo/index.js +48 -0
  6. package/lib/commonjs/adapters/expo/index.js.map +1 -0
  7. package/lib/commonjs/adapters/expo/storage.js +201 -0
  8. package/lib/commonjs/adapters/expo/storage.js.map +1 -0
  9. package/lib/commonjs/adapters/index.js +50 -0
  10. package/lib/commonjs/adapters/index.js.map +1 -0
  11. package/lib/commonjs/adapters/node/crypto.js +40 -0
  12. package/lib/commonjs/adapters/node/crypto.js.map +1 -0
  13. package/lib/commonjs/adapters/node/fetch.js +62 -0
  14. package/lib/commonjs/adapters/node/fetch.js.map +1 -0
  15. package/lib/commonjs/adapters/node/index.js +34 -0
  16. package/lib/commonjs/adapters/node/index.js.map +1 -0
  17. package/lib/commonjs/adapters/node/storage.js +163 -0
  18. package/lib/commonjs/adapters/node/storage.js.map +1 -0
  19. package/lib/commonjs/core/identity-session/DeviceManager.js +237 -0
  20. package/lib/commonjs/core/identity-session/DeviceManager.js.map +1 -0
  21. package/lib/commonjs/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  22. package/lib/commonjs/core/identity-session/IdentityManager.js +400 -0
  23. package/lib/commonjs/core/identity-session/IdentityManager.js.map +1 -0
  24. package/lib/commonjs/core/identity-session/IdentitySessionCore.js +394 -0
  25. package/lib/commonjs/core/identity-session/IdentitySessionCore.js.map +1 -0
  26. package/lib/commonjs/core/identity-session/RefreshManager.js +137 -0
  27. package/lib/commonjs/core/identity-session/RefreshManager.js.map +1 -0
  28. package/lib/commonjs/core/identity-session/SessionManager.js +427 -0
  29. package/lib/commonjs/core/identity-session/SessionManager.js.map +1 -0
  30. package/lib/commonjs/core/identity-session/createIdentitySessionCore.js +24 -0
  31. package/lib/commonjs/core/identity-session/createIdentitySessionCore.js.map +1 -0
  32. package/lib/commonjs/core/identity-session/errors.js +176 -0
  33. package/lib/commonjs/core/identity-session/errors.js.map +1 -0
  34. package/lib/commonjs/core/identity-session/index.js +80 -0
  35. package/lib/commonjs/core/identity-session/index.js.map +1 -0
  36. package/lib/commonjs/core/identity-session/types.js +2 -0
  37. package/lib/commonjs/core/identity-session/types.js.map +1 -0
  38. package/lib/commonjs/core/index.js +2 -21
  39. package/lib/commonjs/core/index.js.map +1 -1
  40. package/lib/commonjs/index.js +58 -8
  41. package/lib/commonjs/index.js.map +1 -1
  42. package/lib/commonjs/models/interfaces.js +7 -0
  43. package/lib/commonjs/models/interfaces.js.map +1 -1
  44. package/lib/commonjs/ui/context/OxyContext.js +434 -820
  45. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  46. package/lib/commonjs/ui/hooks/useAvatarPicker.js +52 -0
  47. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -0
  48. package/lib/commonjs/ui/hooks/useIdentityTransfer.js +125 -0
  49. package/lib/commonjs/ui/hooks/useIdentityTransfer.js.map +1 -0
  50. package/lib/commonjs/ui/hooks/useTransferCodesPersistence.js +81 -0
  51. package/lib/commonjs/ui/hooks/useTransferCodesPersistence.js.map +1 -0
  52. package/lib/commonjs/ui/screens/AccountCenterScreen.js +7 -2
  53. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +12 -5
  55. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  56. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +2 -2
  57. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  58. package/lib/commonjs/ui/screens/ProfileScreen.js +6 -6
  59. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  60. package/lib/commonjs/ui/utils/sessionHelpers.js +7 -1
  61. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  62. package/lib/commonjs/utils/index.js +0 -7
  63. package/lib/commonjs/utils/index.js.map +1 -1
  64. package/lib/commonjs/utils/sessionUtils.js +8 -1
  65. package/lib/commonjs/utils/sessionUtils.js.map +1 -1
  66. package/lib/module/adapters/expo/crypto.js +51 -0
  67. package/lib/module/adapters/expo/crypto.js.map +1 -0
  68. package/lib/module/adapters/expo/fetch.js +26 -0
  69. package/lib/module/adapters/expo/fetch.js.map +1 -0
  70. package/lib/module/adapters/expo/index.js +45 -0
  71. package/lib/module/adapters/expo/index.js.map +1 -0
  72. package/lib/module/adapters/expo/storage.js +198 -0
  73. package/lib/module/adapters/expo/storage.js.map +1 -0
  74. package/lib/module/adapters/index.js +47 -0
  75. package/lib/module/adapters/index.js.map +1 -0
  76. package/lib/module/adapters/node/crypto.js +36 -0
  77. package/lib/module/adapters/node/crypto.js.map +1 -0
  78. package/lib/module/adapters/node/fetch.js +57 -0
  79. package/lib/module/adapters/node/fetch.js.map +1 -0
  80. package/lib/module/adapters/node/index.js +31 -0
  81. package/lib/module/adapters/node/index.js.map +1 -0
  82. package/lib/module/adapters/node/storage.js +159 -0
  83. package/lib/module/adapters/node/storage.js.map +1 -0
  84. package/lib/module/core/identity-session/DeviceManager.js +232 -0
  85. package/lib/module/core/identity-session/DeviceManager.js.map +1 -0
  86. package/lib/module/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  87. package/lib/module/core/identity-session/IdentityManager.js +395 -0
  88. package/lib/module/core/identity-session/IdentityManager.js.map +1 -0
  89. package/lib/module/core/identity-session/IdentitySessionCore.js +390 -0
  90. package/lib/module/core/identity-session/IdentitySessionCore.js.map +1 -0
  91. package/lib/module/core/identity-session/RefreshManager.js +132 -0
  92. package/lib/module/core/identity-session/RefreshManager.js.map +1 -0
  93. package/lib/module/core/identity-session/SessionManager.js +422 -0
  94. package/lib/module/core/identity-session/SessionManager.js.map +1 -0
  95. package/lib/module/core/identity-session/createIdentitySessionCore.js +21 -0
  96. package/lib/module/core/identity-session/createIdentitySessionCore.js.map +1 -0
  97. package/lib/module/core/identity-session/errors.js +170 -0
  98. package/lib/module/core/identity-session/errors.js.map +1 -0
  99. package/lib/module/core/identity-session/index.js +17 -0
  100. package/lib/module/core/identity-session/index.js.map +1 -0
  101. package/lib/module/core/identity-session/types.js +2 -0
  102. package/lib/module/core/identity-session/types.js.map +1 -0
  103. package/lib/module/core/index.js +2 -3
  104. package/lib/module/core/index.js.map +1 -1
  105. package/lib/module/index.js +12 -2
  106. package/lib/module/index.js.map +1 -1
  107. package/lib/module/models/interfaces.js +7 -0
  108. package/lib/module/models/interfaces.js.map +1 -1
  109. package/lib/module/ui/context/OxyContext.js +436 -822
  110. package/lib/module/ui/context/OxyContext.js.map +1 -1
  111. package/lib/module/ui/hooks/useAvatarPicker.js +48 -0
  112. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -0
  113. package/lib/module/ui/hooks/useIdentityTransfer.js +121 -0
  114. package/lib/module/ui/hooks/useIdentityTransfer.js.map +1 -0
  115. package/lib/module/ui/hooks/useTransferCodesPersistence.js +77 -0
  116. package/lib/module/ui/hooks/useTransferCodesPersistence.js.map +1 -0
  117. package/lib/module/ui/screens/AccountCenterScreen.js +7 -2
  118. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  119. package/lib/module/ui/screens/AccountSettingsScreen.js +12 -5
  120. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  121. package/lib/module/ui/screens/AccountSwitcherScreen.js +2 -2
  122. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  123. package/lib/module/ui/screens/ProfileScreen.js +6 -6
  124. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  125. package/lib/module/ui/utils/sessionHelpers.js +7 -1
  126. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  127. package/lib/module/utils/index.js +2 -1
  128. package/lib/module/utils/index.js.map +1 -1
  129. package/lib/module/utils/sessionUtils.js +8 -1
  130. package/lib/module/utils/sessionUtils.js.map +1 -1
  131. package/lib/typescript/adapters/expo/crypto.d.ts +17 -0
  132. package/lib/typescript/adapters/expo/crypto.d.ts.map +1 -0
  133. package/lib/typescript/adapters/expo/fetch.d.ts +16 -0
  134. package/lib/typescript/adapters/expo/fetch.d.ts.map +1 -0
  135. package/lib/typescript/adapters/expo/index.d.ts +23 -0
  136. package/lib/typescript/adapters/expo/index.d.ts.map +1 -0
  137. package/lib/typescript/adapters/expo/storage.d.ts +23 -0
  138. package/lib/typescript/adapters/expo/storage.d.ts.map +1 -0
  139. package/lib/typescript/adapters/index.d.ts +19 -0
  140. package/lib/typescript/adapters/index.d.ts.map +1 -0
  141. package/lib/typescript/adapters/node/crypto.d.ts +17 -0
  142. package/lib/typescript/adapters/node/crypto.d.ts.map +1 -0
  143. package/lib/typescript/adapters/node/fetch.d.ts +16 -0
  144. package/lib/typescript/adapters/node/fetch.d.ts.map +1 -0
  145. package/lib/typescript/adapters/node/index.d.ts +23 -0
  146. package/lib/typescript/adapters/node/index.d.ts.map +1 -0
  147. package/lib/typescript/adapters/node/storage.d.ts +23 -0
  148. package/lib/typescript/adapters/node/storage.d.ts.map +1 -0
  149. package/lib/typescript/core/identity-session/DeviceManager.d.ts +64 -0
  150. package/lib/typescript/core/identity-session/DeviceManager.d.ts.map +1 -0
  151. package/lib/typescript/core/identity-session/IdentityManager.d.ts +88 -0
  152. package/lib/typescript/core/identity-session/IdentityManager.d.ts.map +1 -0
  153. package/lib/typescript/core/identity-session/IdentitySessionCore.d.ts +141 -0
  154. package/lib/typescript/core/identity-session/IdentitySessionCore.d.ts.map +1 -0
  155. package/lib/typescript/core/identity-session/RefreshManager.d.ts +36 -0
  156. package/lib/typescript/core/identity-session/RefreshManager.d.ts.map +1 -0
  157. package/lib/typescript/core/identity-session/SessionManager.d.ts +104 -0
  158. package/lib/typescript/core/identity-session/SessionManager.d.ts.map +1 -0
  159. package/lib/typescript/core/identity-session/createIdentitySessionCore.d.ts +11 -0
  160. package/lib/typescript/core/identity-session/createIdentitySessionCore.d.ts.map +1 -0
  161. package/lib/typescript/core/identity-session/errors.d.ts +63 -0
  162. package/lib/typescript/core/identity-session/errors.d.ts.map +1 -0
  163. package/lib/typescript/core/identity-session/index.d.ts +14 -0
  164. package/lib/typescript/core/identity-session/index.d.ts.map +1 -0
  165. package/lib/typescript/core/identity-session/types.d.ts +196 -0
  166. package/lib/typescript/core/identity-session/types.d.ts.map +1 -0
  167. package/lib/typescript/core/index.d.ts +1 -3
  168. package/lib/typescript/core/index.d.ts.map +1 -1
  169. package/lib/typescript/core/mixins/index.d.ts +2 -2
  170. package/lib/typescript/index.d.ts +3 -2
  171. package/lib/typescript/index.d.ts.map +1 -1
  172. package/lib/typescript/models/interfaces.d.ts +5 -36
  173. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  174. package/lib/typescript/models/session.d.ts +3 -16
  175. package/lib/typescript/models/session.d.ts.map +1 -1
  176. package/lib/typescript/ui/context/OxyContext.d.ts +2 -25
  177. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  178. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts +7 -8
  179. package/lib/typescript/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  180. package/lib/typescript/ui/hooks/mutations/useServicesMutations.d.ts +1 -1
  181. package/lib/typescript/ui/hooks/mutations/useServicesMutations.d.ts.map +1 -1
  182. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts +5 -5
  183. package/lib/typescript/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  184. package/lib/typescript/ui/hooks/useAvatarPicker.d.ts +18 -0
  185. package/lib/typescript/ui/hooks/useAvatarPicker.d.ts.map +1 -0
  186. package/lib/typescript/ui/hooks/useIdentityTransfer.d.ts +24 -0
  187. package/lib/typescript/ui/hooks/useIdentityTransfer.d.ts.map +1 -0
  188. package/lib/typescript/ui/hooks/useTransferCodesPersistence.d.ts +6 -0
  189. package/lib/typescript/ui/hooks/useTransferCodesPersistence.d.ts.map +1 -0
  190. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  191. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  192. package/lib/typescript/ui/utils/sessionHelpers.d.ts +1 -0
  193. package/lib/typescript/ui/utils/sessionHelpers.d.ts.map +1 -1
  194. package/lib/typescript/utils/index.d.ts +0 -2
  195. package/lib/typescript/utils/index.d.ts.map +1 -1
  196. package/lib/typescript/utils/sessionUtils.d.ts.map +1 -1
  197. package/package.json +1 -1
  198. package/src/adapters/expo/crypto.ts +55 -0
  199. package/src/adapters/expo/fetch.ts +28 -0
  200. package/src/adapters/expo/index.ts +51 -0
  201. package/src/adapters/expo/storage.ts +228 -0
  202. package/src/adapters/index.ts +47 -0
  203. package/src/adapters/node/crypto.ts +39 -0
  204. package/src/adapters/node/fetch.ts +59 -0
  205. package/src/adapters/node/index.ts +37 -0
  206. package/src/adapters/node/storage.ts +170 -0
  207. package/src/core/identity-session/DeviceManager.ts +273 -0
  208. package/src/core/identity-session/INTEGRATION_GUIDE.md +287 -0
  209. package/src/core/identity-session/IdentityManager.ts +474 -0
  210. package/src/core/identity-session/IdentitySessionCore.ts +464 -0
  211. package/src/core/identity-session/RefreshManager.ts +189 -0
  212. package/src/core/identity-session/SessionManager.ts +500 -0
  213. package/src/core/identity-session/createIdentitySessionCore.ts +19 -0
  214. package/src/core/identity-session/errors.ts +197 -0
  215. package/src/core/identity-session/index.ts +15 -0
  216. package/src/core/identity-session/types.ts +188 -0
  217. package/src/core/index.ts +3 -4
  218. package/src/index.ts +28 -3
  219. package/src/models/interfaces.ts +12 -39
  220. package/src/models/session.ts +6 -16
  221. package/src/ui/context/OxyContext.tsx +442 -871
  222. package/src/ui/hooks/auth/index.ts +1 -0
  223. package/src/ui/hooks/useAvatarPicker.ts +62 -0
  224. package/src/ui/hooks/useIdentityTransfer.ts +135 -0
  225. package/src/ui/hooks/useTransferCodesPersistence.ts +80 -0
  226. package/src/ui/screens/AccountCenterScreen.tsx +7 -2
  227. package/src/ui/screens/AccountSettingsScreen.tsx +15 -8
  228. package/src/ui/screens/AccountSwitcherScreen.tsx +2 -2
  229. package/src/ui/screens/ProfileScreen.tsx +10 -10
  230. package/src/ui/utils/sessionHelpers.ts +7 -0
  231. package/src/utils/index.ts +1 -2
  232. package/src/utils/sessionUtils.ts +8 -0
  233. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +0 -732
  234. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +0 -1
  235. package/lib/commonjs/ui/context/hooks/useDeviceManagement.js +0 -73
  236. package/lib/commonjs/ui/context/hooks/useDeviceManagement.js.map +0 -1
  237. package/lib/commonjs/ui/hooks/useDeviceManagement.js +0 -73
  238. package/lib/commonjs/ui/hooks/useDeviceManagement.js.map +0 -1
  239. package/lib/commonjs/ui/hooks/useSessionManagement.js +0 -281
  240. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +0 -1
  241. package/lib/commonjs/utils/deviceManager.js +0 -177
  242. package/lib/commonjs/utils/deviceManager.js.map +0 -1
  243. package/lib/module/ui/context/hooks/useAuthOperations.js +0 -726
  244. package/lib/module/ui/context/hooks/useAuthOperations.js.map +0 -1
  245. package/lib/module/ui/context/hooks/useDeviceManagement.js +0 -68
  246. package/lib/module/ui/context/hooks/useDeviceManagement.js.map +0 -1
  247. package/lib/module/ui/hooks/useDeviceManagement.js +0 -68
  248. package/lib/module/ui/hooks/useDeviceManagement.js.map +0 -1
  249. package/lib/module/ui/hooks/useSessionManagement.js +0 -276
  250. package/lib/module/ui/hooks/useSessionManagement.js.map +0 -1
  251. package/lib/module/utils/deviceManager.js +0 -171
  252. package/lib/module/utils/deviceManager.js.map +0 -1
  253. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +0 -59
  254. package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +0 -1
  255. package/lib/typescript/ui/context/hooks/useDeviceManagement.d.ts +0 -27
  256. package/lib/typescript/ui/context/hooks/useDeviceManagement.d.ts.map +0 -1
  257. package/lib/typescript/ui/hooks/useDeviceManagement.d.ts +0 -27
  258. package/lib/typescript/ui/hooks/useDeviceManagement.d.ts.map +0 -1
  259. package/lib/typescript/ui/hooks/useSessionManagement.d.ts +0 -41
  260. package/lib/typescript/ui/hooks/useSessionManagement.d.ts.map +0 -1
  261. package/lib/typescript/utils/deviceManager.d.ts +0 -66
  262. package/lib/typescript/utils/deviceManager.d.ts.map +0 -1
  263. package/src/ui/context/hooks/useAuthOperations.ts +0 -801
  264. package/src/ui/context/hooks/useDeviceManagement.ts +0 -108
  265. package/src/ui/hooks/useDeviceManagement.ts +0 -108
  266. package/src/ui/hooks/useSessionManagement.ts +0 -401
  267. package/src/utils/deviceManager.ts +0 -198
@@ -0,0 +1,474 @@
1
+ /**
2
+ * Identity Manager
3
+ *
4
+ * Manages cryptographic identity (OxyID) - SOLO NATIVE
5
+ * Handles key generation, storage, import, export, and signing operations.
6
+ */
7
+
8
+ import { ec as EC } from 'elliptic';
9
+ import type { ECKeyPair } from 'elliptic';
10
+ import type { PlatformAdapter } from '../../adapters';
11
+ import type { Identity, BackupData } from './types';
12
+ import {
13
+ createIdentitySessionError,
14
+ IdentitySessionErrorCodes,
15
+ } from './errors';
16
+ import {
17
+ isValidPublicKey,
18
+ isValidPrivateKey,
19
+ derivePublicKey,
20
+ getEllipticCurve,
21
+ } from '../../crypto/core';
22
+
23
+ const ec = getEllipticCurve();
24
+
25
+ const STORAGE_KEYS = {
26
+ PRIVATE_KEY: 'oxy_identity_private_key',
27
+ PUBLIC_KEY: 'oxy_identity_public_key',
28
+ BACKUP_PRIVATE_KEY: 'oxy_identity_backup_private_key',
29
+ BACKUP_PUBLIC_KEY: 'oxy_identity_backup_public_key',
30
+ BACKUP_TIMESTAMP: 'oxy_identity_backup_timestamp',
31
+ } as const;
32
+
33
+ /**
34
+ * Identity Manager Class
35
+ */
36
+ export class IdentityManager {
37
+ private adapter: PlatformAdapter;
38
+ private cachedPublicKey: string | null = null;
39
+ private cachedHasIdentity: boolean | null = null;
40
+
41
+ constructor(adapter: PlatformAdapter) {
42
+ this.adapter = adapter;
43
+ }
44
+
45
+ /**
46
+ * Invalidate cached identity state
47
+ */
48
+ invalidateCache(): void {
49
+ this.cachedPublicKey = null;
50
+ this.cachedHasIdentity = null;
51
+ }
52
+
53
+ /**
54
+ * Check if identity operations are available (only on native)
55
+ */
56
+ private ensureNativePlatform(): void {
57
+ if (this.adapter.platform !== 'native') {
58
+ throw createIdentitySessionError(
59
+ IdentitySessionErrorCodes.IDENTITY_NOT_AVAILABLE_ON_WEB,
60
+ 'Identity operations are only available on native platforms (iOS/Android)'
61
+ );
62
+ }
63
+
64
+ if (!this.adapter.storage.isSecureStorageAvailable()) {
65
+ throw createIdentitySessionError(
66
+ IdentitySessionErrorCodes.SECURE_STORAGE_NOT_AVAILABLE,
67
+ 'Secure storage is not available on this platform'
68
+ );
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Convert Uint8Array to hexadecimal string
74
+ */
75
+ private uint8ArrayToHex(bytes: Uint8Array): string {
76
+ return Array.from(bytes)
77
+ .map(b => b.toString(16).padStart(2, '0'))
78
+ .join('');
79
+ }
80
+
81
+ /**
82
+ * Generate a new ECDSA secp256k1 key pair
83
+ */
84
+ async generateKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
85
+ this.ensureNativePlatform();
86
+
87
+ const randomBytes = await this.adapter.crypto.getRandomBytes(32);
88
+ const privateKeyHex = this.uint8ArrayToHex(randomBytes);
89
+ const keyPair = ec.keyFromPrivate(privateKeyHex);
90
+
91
+ return {
92
+ privateKey: keyPair.getPrivate('hex'),
93
+ publicKey: keyPair.getPublic('hex'),
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Create a new identity (generate and store key pair)
99
+ */
100
+ async createIdentity(): Promise<string> {
101
+ this.ensureNativePlatform();
102
+
103
+ const { privateKey, publicKey } = await this.generateKeyPair();
104
+
105
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, privateKey);
106
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, publicKey);
107
+
108
+ // Update cache
109
+ this.cachedPublicKey = publicKey;
110
+ this.cachedHasIdentity = true;
111
+
112
+ return publicKey;
113
+ }
114
+
115
+ /**
116
+ * Import an existing key pair (e.g., from backup file)
117
+ */
118
+ async importKeyPair(privateKey: string): Promise<string> {
119
+ this.ensureNativePlatform();
120
+
121
+ if (!isValidPrivateKey(privateKey)) {
122
+ throw createIdentitySessionError(
123
+ IdentitySessionErrorCodes.INVALID_PRIVATE_KEY,
124
+ 'Invalid private key format'
125
+ );
126
+ }
127
+
128
+ const keyPair = ec.keyFromPrivate(privateKey);
129
+ const publicKey = keyPair.getPublic('hex');
130
+
131
+ if (!isValidPublicKey(publicKey)) {
132
+ throw createIdentitySessionError(
133
+ IdentitySessionErrorCodes.INVALID_PUBLIC_KEY,
134
+ 'Failed to derive valid public key from private key'
135
+ );
136
+ }
137
+
138
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, privateKey);
139
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, publicKey);
140
+
141
+ // Update cache
142
+ this.cachedPublicKey = publicKey;
143
+ this.cachedHasIdentity = true;
144
+
145
+ return publicKey;
146
+ }
147
+
148
+ /**
149
+ * Get the stored private key
150
+ * WARNING: Only use this for signing operations within the app
151
+ */
152
+ async getPrivateKey(): Promise<string | null> {
153
+ this.ensureNativePlatform();
154
+
155
+ try {
156
+ return await this.adapter.storage.secureGet(STORAGE_KEYS.PRIVATE_KEY);
157
+ } catch (error) {
158
+ console.warn('[IdentityManager] Failed to access secure store:', error);
159
+ return null;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Get the stored public key (cached for performance)
165
+ */
166
+ async getPublicKey(): Promise<string | null> {
167
+ if (this.adapter.platform !== 'native') {
168
+ return null; // Identity only exists on native
169
+ }
170
+
171
+ if (this.cachedPublicKey !== null) {
172
+ return this.cachedPublicKey;
173
+ }
174
+
175
+ try {
176
+ const publicKey = await this.adapter.storage.secureGet(STORAGE_KEYS.PUBLIC_KEY);
177
+
178
+ // Cache result (null is a valid cache value meaning no identity)
179
+ this.cachedPublicKey = publicKey;
180
+
181
+ return publicKey;
182
+ } catch (error) {
183
+ // If secure store is not available, return null (no identity)
184
+ this.cachedPublicKey = null;
185
+ console.warn('[IdentityManager] Failed to access secure store:', error);
186
+ return null;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Check if an identity (key pair) exists on this device (cached for performance)
192
+ */
193
+ async hasIdentity(): Promise<boolean> {
194
+ if (this.adapter.platform !== 'native') {
195
+ return false; // Identity only exists on native
196
+ }
197
+
198
+ if (this.cachedHasIdentity !== null) {
199
+ return this.cachedHasIdentity;
200
+ }
201
+
202
+ try {
203
+ const privateKey = await this.getPrivateKey();
204
+ const hasIdentity = privateKey !== null;
205
+
206
+ // Cache result
207
+ this.cachedHasIdentity = hasIdentity;
208
+
209
+ return hasIdentity;
210
+ } catch (error) {
211
+ // If we can't check, assume no identity (safer default)
212
+ this.cachedHasIdentity = false;
213
+ console.warn('[IdentityManager] Failed to check identity:', error);
214
+ return false;
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Delete the stored identity (both keys)
220
+ */
221
+ async deleteIdentity(
222
+ skipBackup: boolean = false,
223
+ force: boolean = false,
224
+ userConfirmed: boolean = false
225
+ ): Promise<void> {
226
+ this.ensureNativePlatform();
227
+
228
+ // CRITICAL SAFEGUARD: Require explicit user confirmation unless force is true
229
+ if (!force && !userConfirmed) {
230
+ throw createIdentitySessionError(
231
+ IdentitySessionErrorCodes.IDENTITY_DELETE_FAILED,
232
+ 'Identity deletion requires explicit user confirmation'
233
+ );
234
+ }
235
+
236
+ if (!force) {
237
+ const hasIdentity = await this.hasIdentity();
238
+ if (!hasIdentity) {
239
+ return; // Nothing to delete
240
+ }
241
+ }
242
+
243
+ // ALWAYS create backup before deletion unless explicitly skipped
244
+ if (!skipBackup) {
245
+ try {
246
+ const backupSuccess = await this.backupIdentity();
247
+ if (!backupSuccess) {
248
+ console.warn('[IdentityManager] Failed to backup identity before deletion - proceeding anyway');
249
+ }
250
+ } catch (backupError) {
251
+ console.warn('[IdentityManager] Failed to backup identity before deletion:', backupError);
252
+ }
253
+ }
254
+
255
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.PRIVATE_KEY);
256
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.PUBLIC_KEY);
257
+
258
+ // Invalidate cache
259
+ this.invalidateCache();
260
+
261
+ // Also clear backup if force deletion
262
+ if (force) {
263
+ try {
264
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.BACKUP_PRIVATE_KEY);
265
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.BACKUP_PUBLIC_KEY);
266
+ await this.adapter.storage.remove(STORAGE_KEYS.BACKUP_TIMESTAMP);
267
+ } catch (error) {
268
+ // Ignore backup deletion errors
269
+ }
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Backup identity to SecureStore (separate backup storage)
275
+ */
276
+ async backupIdentity(): Promise<boolean> {
277
+ this.ensureNativePlatform();
278
+
279
+ try {
280
+ const privateKey = await this.getPrivateKey();
281
+ const publicKey = await this.getPublicKey();
282
+
283
+ if (!privateKey || !publicKey) {
284
+ return false; // Nothing to backup
285
+ }
286
+
287
+ // Store backup in SecureStore (still secure, but separate from primary storage)
288
+ await this.adapter.storage.secureSet(STORAGE_KEYS.BACKUP_PRIVATE_KEY, privateKey);
289
+ await this.adapter.storage.secureSet(STORAGE_KEYS.BACKUP_PUBLIC_KEY, publicKey);
290
+ await this.adapter.storage.set(STORAGE_KEYS.BACKUP_TIMESTAMP, Date.now().toString());
291
+
292
+ return true;
293
+ } catch (error) {
294
+ console.error('[IdentityManager] Failed to backup identity:', error);
295
+ return false;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Restore identity from backup if primary storage is corrupted
301
+ */
302
+ async restoreIdentityFromBackup(): Promise<boolean> {
303
+ this.ensureNativePlatform();
304
+
305
+ try {
306
+ // Invalidate cache before restoring to ensure fresh state
307
+ this.invalidateCache();
308
+
309
+ // Check if backup exists
310
+ const backupPrivateKey = await this.adapter.storage.secureGet(STORAGE_KEYS.BACKUP_PRIVATE_KEY);
311
+ const backupPublicKey = await this.adapter.storage.secureGet(STORAGE_KEYS.BACKUP_PUBLIC_KEY);
312
+
313
+ if (!backupPrivateKey || !backupPublicKey) {
314
+ return false; // No backup available
315
+ }
316
+
317
+ // Verify backup integrity
318
+ if (!isValidPrivateKey(backupPrivateKey)) {
319
+ return false;
320
+ }
321
+
322
+ if (!isValidPublicKey(backupPublicKey)) {
323
+ return false;
324
+ }
325
+
326
+ // Verify keys match
327
+ const derivedPublicKey = derivePublicKey(backupPrivateKey);
328
+ if (derivedPublicKey !== backupPublicKey) {
329
+ return false; // Backup keys don't match
330
+ }
331
+
332
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, backupPrivateKey);
333
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, backupPublicKey);
334
+
335
+ const restored = await this.verifyIdentityIntegrity();
336
+ if (restored) {
337
+ // Update cache
338
+ this.cachedPublicKey = backupPublicKey;
339
+ this.cachedHasIdentity = true;
340
+
341
+ await this.adapter.storage.set(STORAGE_KEYS.BACKUP_TIMESTAMP, Date.now().toString());
342
+ return true;
343
+ }
344
+
345
+ return false;
346
+ } catch (error) {
347
+ console.error('[IdentityManager] Failed to restore identity from backup:', error);
348
+ return false;
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Verify identity integrity - checks if keys are valid and accessible
354
+ */
355
+ async verifyIdentityIntegrity(): Promise<boolean> {
356
+ this.ensureNativePlatform();
357
+
358
+ try {
359
+ const privateKey = await this.getPrivateKey();
360
+ const publicKey = await this.getPublicKey();
361
+
362
+ if (!privateKey || !publicKey) {
363
+ return false;
364
+ }
365
+
366
+ // Validate private key format
367
+ if (!isValidPrivateKey(privateKey)) {
368
+ return false;
369
+ }
370
+
371
+ // Validate public key format
372
+ if (!isValidPublicKey(publicKey)) {
373
+ return false;
374
+ }
375
+
376
+ // Verify public key can be derived from private key
377
+ const derivedPublicKey = derivePublicKey(privateKey);
378
+ if (derivedPublicKey !== publicKey) {
379
+ return false; // Keys don't match
380
+ }
381
+
382
+ // Verify we can create a key pair object (tests elliptic curve operations)
383
+ const keyPair = await this.getKeyPairObject();
384
+ if (!keyPair) {
385
+ return false;
386
+ }
387
+
388
+ return true;
389
+ } catch (error) {
390
+ console.error('[IdentityManager] Identity integrity check failed:', error);
391
+ return false;
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Get the elliptic curve key object from the stored private key
397
+ * Used internally for signing operations
398
+ */
399
+ async getKeyPairObject(): Promise<ECKeyPair | null> {
400
+ this.ensureNativePlatform();
401
+
402
+ const privateKey = await this.getPrivateKey();
403
+ if (!privateKey) return null;
404
+
405
+ return ec.keyFromPrivate(privateKey);
406
+ }
407
+
408
+ /**
409
+ * Decrypt backup data and import identity
410
+ */
411
+ async decryptAndImportBackup(backupData: BackupData, password: string): Promise<string> {
412
+ this.ensureNativePlatform();
413
+
414
+ try {
415
+ // Convert hex strings to Uint8Array
416
+ const saltBytes = new Uint8Array(
417
+ backupData.salt.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []
418
+ );
419
+ const ivBytes = new Uint8Array(
420
+ backupData.iv.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []
421
+ );
422
+
423
+ // Derive key from password (same algorithm as EncryptedBackupGenerator)
424
+ const saltHex = Array.from(saltBytes).map(b => b.toString(16).padStart(2, '0')).join('');
425
+ let key = password + saltHex;
426
+ for (let i = 0; i < 10000; i++) {
427
+ key = await this.adapter.crypto.digestStringAsync('SHA256', key);
428
+ }
429
+ const keyBytes = new Uint8Array(32);
430
+ for (let i = 0; i < 64 && i < key.length; i += 2) {
431
+ keyBytes[i / 2] = parseInt(key.substring(i, i + 2), 16);
432
+ }
433
+
434
+ // Decrypt private key (XOR decryption - same as encryption)
435
+ const encryptedBytes = Buffer.from(backupData.encrypted, 'base64');
436
+ const decryptedBytes = new Uint8Array(encryptedBytes.length);
437
+ for (let i = 0; i < encryptedBytes.length; i++) {
438
+ decryptedBytes[i] = encryptedBytes[i] ^ keyBytes[i % keyBytes.length] ^ ivBytes[i % ivBytes.length];
439
+ }
440
+ const privateKey = new TextDecoder().decode(decryptedBytes);
441
+
442
+ // Import the key pair
443
+ return await this.importKeyPair(privateKey);
444
+ } catch (error) {
445
+ throw createIdentitySessionError(
446
+ IdentitySessionErrorCodes.BACKUP_DECRYPTION_FAILED,
447
+ `Failed to decrypt backup: ${error instanceof Error ? error.message : String(error)}`
448
+ );
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Sign a challenge using the stored private key
454
+ */
455
+ async signChallenge(challenge: string): Promise<string> {
456
+ this.ensureNativePlatform();
457
+
458
+ const keyPair = await this.getKeyPairObject();
459
+ if (!keyPair) {
460
+ throw createIdentitySessionError(
461
+ IdentitySessionErrorCodes.IDENTITY_NOT_FOUND,
462
+ 'No identity found. Please create or import an identity first.'
463
+ );
464
+ }
465
+
466
+ // Hash the challenge
467
+ const messageHash = await this.adapter.crypto.digestStringAsync('SHA256', challenge);
468
+
469
+ // Sign the hash
470
+ const signature = keyPair.sign(messageHash);
471
+ return signature.toDER('hex');
472
+ }
473
+ }
474
+