@oxyhq/services 5.16.39 → 5.16.41

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 +41 -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 +38 -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 +13 -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 +40 -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 -704
  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 -698
  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 -773
  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,287 @@
1
+ # Identity Session Core - Integration Guide
2
+
3
+ ## Overview
4
+
5
+ The Identity Session Core provides a unified API for identity and session management across all platforms (React Native, Web, Node). All identity and session operations go through this core - never access `KeyManager`, storage, or APIs directly.
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ UI/Hooks Layer
11
+
12
+ IdentitySessionCore (unified API)
13
+
14
+ Managers (Identity, Session, Device, Refresh)
15
+
16
+ Platform Adapters (Expo 54, Node)
17
+ ```
18
+
19
+ ## Key Principles
20
+
21
+ 1. **Frontend: Use `useOxy()` hook** - This is the only API you need for React/React Native applications
22
+ 2. **Backend: Use `createIdentitySessionCore()`** - Only for Node.js/backend applications
23
+ 3. **Never access storage, APIs, or KeyManager directly** - Always go through the core or `useOxy()`
24
+ 4. **Identity operations are NATIVE ONLY** - Web cannot create/import identities
25
+ 5. **Session operations work on NATIVE + WEB** - sessions can be used on both platforms
26
+ 6. **Models are aligned with backend** - same types, same error codes
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ npm install @oxyhq/services
32
+ ```
33
+
34
+ ## Basic Usage
35
+
36
+ ### Using the React Hook (Recommended)
37
+
38
+ ```typescript
39
+ import { OxyProvider, useOxy } from '@oxyhq/services';
40
+ import { Platform } from 'react-native';
41
+
42
+ function App() {
43
+ return (
44
+ <OxyProvider baseURL="https://api.example.com">
45
+ <MyComponent />
46
+ </OxyProvider>
47
+ );
48
+ }
49
+
50
+ function MyComponent() {
51
+ const { createIdentity, signIn, hasIdentity, isLoading, error } = useOxy();
52
+
53
+ const handleCreateIdentity = async () => {
54
+ if (Platform.OS === 'web') {
55
+ alert('Identity creation is only available on native platforms');
56
+ return;
57
+ }
58
+
59
+ try {
60
+ const result = await createIdentity('myusername');
61
+ console.log('Identity created, synced:', result.synced);
62
+ } catch (err) {
63
+ console.error('Failed to create identity:', err);
64
+ }
65
+ };
66
+
67
+ const handleSignIn = async () => {
68
+ try {
69
+ const user = await signIn('My Device');
70
+ console.log('Signed in:', user);
71
+ } catch (err) {
72
+ console.error('Failed to sign in:', err);
73
+ }
74
+ };
75
+
76
+ if (error) return <Text>Error: {error}</Text>;
77
+ if (isLoading) return <Text>Loading...</Text>;
78
+
79
+ return (
80
+ <View>
81
+ <Button onPress={handleCreateIdentity} title="Create Identity" />
82
+ <Button onPress={handleSignIn} title="Sign In" />
83
+ </View>
84
+ );
85
+ }
86
+ ```
87
+
88
+ ### Direct Core Usage (Backend/Node.js Only)
89
+
90
+ **Note:** For frontend applications, always use `useOxy()` hook. Direct core usage is only for backend/Node.js applications.
91
+
92
+ ```typescript
93
+ import { createIdentitySessionCore } from '@oxyhq/services';
94
+
95
+ // Backend/Node.js only
96
+ const core = await createIdentitySessionCore('https://api.example.com');
97
+ const identity = await core.getCurrentIdentity();
98
+ const session = await core.getSession();
99
+ ```
100
+
101
+ ## API Reference
102
+
103
+ ### Using `useOxy` Hook (Recommended)
104
+
105
+ The `useOxy` hook provides all identity and session operations through a simple, reactive API:
106
+
107
+ ```typescript
108
+ const {
109
+ // Identity (Native Only)
110
+ createIdentity,
111
+ importIdentity,
112
+ deleteIdentityAndClearAccount,
113
+ hasIdentity,
114
+ getPublicKey,
115
+ isIdentitySynced,
116
+ syncIdentity,
117
+ identity,
118
+ publicKey,
119
+ identitySyncState,
120
+
121
+ // Session (Native + Web)
122
+ signIn,
123
+ logout,
124
+ logoutAll,
125
+ switchSession,
126
+ refreshSession,
127
+ session,
128
+ sessions,
129
+ activeSessionId,
130
+ isAuthenticated,
131
+
132
+ // Device (Native + Web)
133
+ getDeviceSessions,
134
+ logoutAllDeviceSessions,
135
+ updateDeviceName,
136
+ device,
137
+
138
+ // State
139
+ user,
140
+ isLoading,
141
+ isTokenReady,
142
+ isStorageReady,
143
+ error,
144
+ } = useOxy();
145
+ ```
146
+
147
+ ### Identity Operations (Native Only)
148
+
149
+ ```typescript
150
+ // Create new identity
151
+ const result = await createIdentity(username?);
152
+ // result.synced indicates if identity was synced with backend
153
+
154
+ // Import identity from backup
155
+ const result = await importIdentity(backupData, password, username?);
156
+ // result.synced indicates if identity was synced with backend
157
+
158
+ // Delete identity and clear all account data
159
+ await deleteIdentityAndClearAccount(skipBackup?, force?, userConfirmed?);
160
+
161
+ // Check if identity exists
162
+ const has = await hasIdentity();
163
+
164
+ // Get public key
165
+ const publicKey = await getPublicKey();
166
+
167
+ // Check if identity is synced
168
+ const synced = await isIdentitySynced();
169
+
170
+ // Manually sync identity
171
+ const user = await syncIdentity(username?);
172
+ ```
173
+
174
+ ### Session Operations (Native + Web)
175
+
176
+ ```typescript
177
+ // Sign in (create session)
178
+ const user = await signIn(deviceName?);
179
+
180
+ // Logout (invalidate current or specific session)
181
+ await logout(sessionId?);
182
+
183
+ // Logout all sessions
184
+ await logoutAll();
185
+
186
+ // Switch to different session
187
+ await switchSession(sessionId);
188
+
189
+ // Refresh current session
190
+ const session = await refreshSession();
191
+ ```
192
+
193
+ ### Device Operations (Native + Web)
194
+
195
+ ```typescript
196
+ // Get all device sessions
197
+ const deviceSessions = await getDeviceSessions();
198
+
199
+ // Logout all sessions for current device
200
+ await logoutAllDeviceSessions();
201
+
202
+ // Update device name
203
+ await updateDeviceName(deviceName);
204
+ ```
205
+
206
+ ### Direct Core Usage (Advanced)
207
+
208
+ For advanced use cases, you can access the core directly:
209
+
210
+ ```typescript
211
+ import { createIdentitySessionCore } from '@oxyhq/services';
212
+
213
+ const core = await createIdentitySessionCore('https://api.example.com');
214
+ const identity = await core.getCurrentIdentity();
215
+ const session = await core.getSession();
216
+
217
+ // Subscribe to events
218
+ const unsubscribe = core.subscribe((event) => {
219
+ switch (event.type) {
220
+ case 'identity:created':
221
+ console.log('Identity created:', event.identity);
222
+ break;
223
+ case 'session:created':
224
+ console.log('Session created:', event.session);
225
+ break;
226
+ case 'session:invalidated':
227
+ console.log('Session invalidated:', event.sessionId);
228
+ break;
229
+ }
230
+ });
231
+
232
+ // Cleanup
233
+ unsubscribe();
234
+ ```
235
+
236
+ ## Error Handling
237
+
238
+ All errors use unified error codes:
239
+
240
+ ```typescript
241
+ import {
242
+ IdentitySessionError,
243
+ IdentitySessionErrorCodes
244
+ } from '@oxyhq/services';
245
+
246
+ try {
247
+ await createIdentity();
248
+ } catch (error) {
249
+ if (error instanceof IdentitySessionError) {
250
+ switch (error.code) {
251
+ case IdentitySessionErrorCodes.IDENTITY_NOT_AVAILABLE_ON_WEB:
252
+ // Handle web platform error
253
+ break;
254
+ case IdentitySessionErrorCodes.IDENTITY_ALREADY_EXISTS:
255
+ // Handle already exists error
256
+ break;
257
+ default:
258
+ console.error('Error:', error.message);
259
+ }
260
+ }
261
+ }
262
+ ```
263
+
264
+ ## Type Exports
265
+
266
+ ```typescript
267
+ import type {
268
+ Identity,
269
+ Session,
270
+ Device,
271
+ DeviceInfo,
272
+ BackupData,
273
+ IdentitySessionEvent,
274
+ } from '@oxyhq/services';
275
+ ```
276
+
277
+ ## Platform Detection
278
+
279
+ The core automatically detects the platform and validates operations. Identity operations will throw `IDENTITY_NOT_AVAILABLE_ON_WEB` on web platforms.
280
+
281
+ ## Notes
282
+
283
+ - The core handles all platform-specific logic internally
284
+ - Storage, crypto, and fetch are abstracted through platform adapters
285
+ - All models are aligned with backend (IUser, ISession)
286
+ - Error codes are unified across frontend and backend
287
+ - The core is designed to be "plugged in" to any Oxy app (Mention, Homiio, Noted, etc.)
@@ -0,0 +1,395 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Identity Manager
5
+ *
6
+ * Manages cryptographic identity (OxyID) - SOLO NATIVE
7
+ * Handles key generation, storage, import, export, and signing operations.
8
+ */
9
+
10
+ import { createIdentitySessionError, IdentitySessionErrorCodes } from './errors';
11
+ import { isValidPublicKey, isValidPrivateKey, derivePublicKey, getEllipticCurve } from '../../crypto/core';
12
+ const ec = getEllipticCurve();
13
+ const STORAGE_KEYS = {
14
+ PRIVATE_KEY: 'oxy_identity_private_key',
15
+ PUBLIC_KEY: 'oxy_identity_public_key',
16
+ BACKUP_PRIVATE_KEY: 'oxy_identity_backup_private_key',
17
+ BACKUP_PUBLIC_KEY: 'oxy_identity_backup_public_key',
18
+ BACKUP_TIMESTAMP: 'oxy_identity_backup_timestamp'
19
+ };
20
+
21
+ /**
22
+ * Identity Manager Class
23
+ */
24
+ export class IdentityManager {
25
+ cachedPublicKey = null;
26
+ cachedHasIdentity = null;
27
+ constructor(adapter) {
28
+ this.adapter = adapter;
29
+ }
30
+
31
+ /**
32
+ * Invalidate cached identity state
33
+ */
34
+ invalidateCache() {
35
+ this.cachedPublicKey = null;
36
+ this.cachedHasIdentity = null;
37
+ }
38
+
39
+ /**
40
+ * Check if identity operations are available (only on native)
41
+ */
42
+ ensureNativePlatform() {
43
+ if (this.adapter.platform !== 'native') {
44
+ throw createIdentitySessionError(IdentitySessionErrorCodes.IDENTITY_NOT_AVAILABLE_ON_WEB, 'Identity operations are only available on native platforms (iOS/Android)');
45
+ }
46
+ if (!this.adapter.storage.isSecureStorageAvailable()) {
47
+ throw createIdentitySessionError(IdentitySessionErrorCodes.SECURE_STORAGE_NOT_AVAILABLE, 'Secure storage is not available on this platform');
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Convert Uint8Array to hexadecimal string
53
+ */
54
+ uint8ArrayToHex(bytes) {
55
+ return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
56
+ }
57
+
58
+ /**
59
+ * Generate a new ECDSA secp256k1 key pair
60
+ */
61
+ async generateKeyPair() {
62
+ this.ensureNativePlatform();
63
+ const randomBytes = await this.adapter.crypto.getRandomBytes(32);
64
+ const privateKeyHex = this.uint8ArrayToHex(randomBytes);
65
+ const keyPair = ec.keyFromPrivate(privateKeyHex);
66
+ return {
67
+ privateKey: keyPair.getPrivate('hex'),
68
+ publicKey: keyPair.getPublic('hex')
69
+ };
70
+ }
71
+
72
+ /**
73
+ * Create a new identity (generate and store key pair)
74
+ */
75
+ async createIdentity() {
76
+ this.ensureNativePlatform();
77
+ const {
78
+ privateKey,
79
+ publicKey
80
+ } = await this.generateKeyPair();
81
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, privateKey);
82
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, publicKey);
83
+
84
+ // Update cache
85
+ this.cachedPublicKey = publicKey;
86
+ this.cachedHasIdentity = true;
87
+ return publicKey;
88
+ }
89
+
90
+ /**
91
+ * Import an existing key pair (e.g., from backup file)
92
+ */
93
+ async importKeyPair(privateKey) {
94
+ this.ensureNativePlatform();
95
+ if (!isValidPrivateKey(privateKey)) {
96
+ throw createIdentitySessionError(IdentitySessionErrorCodes.INVALID_PRIVATE_KEY, 'Invalid private key format');
97
+ }
98
+ const keyPair = ec.keyFromPrivate(privateKey);
99
+ const publicKey = keyPair.getPublic('hex');
100
+ if (!isValidPublicKey(publicKey)) {
101
+ throw createIdentitySessionError(IdentitySessionErrorCodes.INVALID_PUBLIC_KEY, 'Failed to derive valid public key from private key');
102
+ }
103
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, privateKey);
104
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, publicKey);
105
+
106
+ // Update cache
107
+ this.cachedPublicKey = publicKey;
108
+ this.cachedHasIdentity = true;
109
+ return publicKey;
110
+ }
111
+
112
+ /**
113
+ * Get the stored private key
114
+ * WARNING: Only use this for signing operations within the app
115
+ */
116
+ async getPrivateKey() {
117
+ this.ensureNativePlatform();
118
+ try {
119
+ return await this.adapter.storage.secureGet(STORAGE_KEYS.PRIVATE_KEY);
120
+ } catch (error) {
121
+ console.warn('[IdentityManager] Failed to access secure store:', error);
122
+ return null;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Get the stored public key (cached for performance)
128
+ */
129
+ async getPublicKey() {
130
+ if (this.adapter.platform !== 'native') {
131
+ return null; // Identity only exists on native
132
+ }
133
+ if (this.cachedPublicKey !== null) {
134
+ return this.cachedPublicKey;
135
+ }
136
+ try {
137
+ const publicKey = await this.adapter.storage.secureGet(STORAGE_KEYS.PUBLIC_KEY);
138
+
139
+ // Cache result (null is a valid cache value meaning no identity)
140
+ this.cachedPublicKey = publicKey;
141
+ return publicKey;
142
+ } catch (error) {
143
+ // If secure store is not available, return null (no identity)
144
+ this.cachedPublicKey = null;
145
+ console.warn('[IdentityManager] Failed to access secure store:', error);
146
+ return null;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Check if an identity (key pair) exists on this device (cached for performance)
152
+ */
153
+ async hasIdentity() {
154
+ if (this.adapter.platform !== 'native') {
155
+ return false; // Identity only exists on native
156
+ }
157
+ if (this.cachedHasIdentity !== null) {
158
+ return this.cachedHasIdentity;
159
+ }
160
+ try {
161
+ const privateKey = await this.getPrivateKey();
162
+ const hasIdentity = privateKey !== null;
163
+
164
+ // Cache result
165
+ this.cachedHasIdentity = hasIdentity;
166
+ return hasIdentity;
167
+ } catch (error) {
168
+ // If we can't check, assume no identity (safer default)
169
+ this.cachedHasIdentity = false;
170
+ console.warn('[IdentityManager] Failed to check identity:', error);
171
+ return false;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Delete the stored identity (both keys)
177
+ */
178
+ async deleteIdentity(skipBackup = false, force = false, userConfirmed = false) {
179
+ this.ensureNativePlatform();
180
+
181
+ // CRITICAL SAFEGUARD: Require explicit user confirmation unless force is true
182
+ if (!force && !userConfirmed) {
183
+ throw createIdentitySessionError(IdentitySessionErrorCodes.IDENTITY_DELETE_FAILED, 'Identity deletion requires explicit user confirmation');
184
+ }
185
+ if (!force) {
186
+ const hasIdentity = await this.hasIdentity();
187
+ if (!hasIdentity) {
188
+ return; // Nothing to delete
189
+ }
190
+ }
191
+
192
+ // ALWAYS create backup before deletion unless explicitly skipped
193
+ if (!skipBackup) {
194
+ try {
195
+ const backupSuccess = await this.backupIdentity();
196
+ if (!backupSuccess) {
197
+ console.warn('[IdentityManager] Failed to backup identity before deletion - proceeding anyway');
198
+ }
199
+ } catch (backupError) {
200
+ console.warn('[IdentityManager] Failed to backup identity before deletion:', backupError);
201
+ }
202
+ }
203
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.PRIVATE_KEY);
204
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.PUBLIC_KEY);
205
+
206
+ // Invalidate cache
207
+ this.invalidateCache();
208
+
209
+ // Also clear backup if force deletion
210
+ if (force) {
211
+ try {
212
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.BACKUP_PRIVATE_KEY);
213
+ await this.adapter.storage.secureDelete(STORAGE_KEYS.BACKUP_PUBLIC_KEY);
214
+ await this.adapter.storage.remove(STORAGE_KEYS.BACKUP_TIMESTAMP);
215
+ } catch (error) {
216
+ // Ignore backup deletion errors
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Backup identity to SecureStore (separate backup storage)
223
+ */
224
+ async backupIdentity() {
225
+ this.ensureNativePlatform();
226
+ try {
227
+ const privateKey = await this.getPrivateKey();
228
+ const publicKey = await this.getPublicKey();
229
+ if (!privateKey || !publicKey) {
230
+ return false; // Nothing to backup
231
+ }
232
+
233
+ // Store backup in SecureStore (still secure, but separate from primary storage)
234
+ await this.adapter.storage.secureSet(STORAGE_KEYS.BACKUP_PRIVATE_KEY, privateKey);
235
+ await this.adapter.storage.secureSet(STORAGE_KEYS.BACKUP_PUBLIC_KEY, publicKey);
236
+ await this.adapter.storage.set(STORAGE_KEYS.BACKUP_TIMESTAMP, Date.now().toString());
237
+ return true;
238
+ } catch (error) {
239
+ console.error('[IdentityManager] Failed to backup identity:', error);
240
+ return false;
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Restore identity from backup if primary storage is corrupted
246
+ */
247
+ async restoreIdentityFromBackup() {
248
+ this.ensureNativePlatform();
249
+ try {
250
+ // Invalidate cache before restoring to ensure fresh state
251
+ this.invalidateCache();
252
+
253
+ // Check if backup exists
254
+ const backupPrivateKey = await this.adapter.storage.secureGet(STORAGE_KEYS.BACKUP_PRIVATE_KEY);
255
+ const backupPublicKey = await this.adapter.storage.secureGet(STORAGE_KEYS.BACKUP_PUBLIC_KEY);
256
+ if (!backupPrivateKey || !backupPublicKey) {
257
+ return false; // No backup available
258
+ }
259
+
260
+ // Verify backup integrity
261
+ if (!isValidPrivateKey(backupPrivateKey)) {
262
+ return false;
263
+ }
264
+ if (!isValidPublicKey(backupPublicKey)) {
265
+ return false;
266
+ }
267
+
268
+ // Verify keys match
269
+ const derivedPublicKey = derivePublicKey(backupPrivateKey);
270
+ if (derivedPublicKey !== backupPublicKey) {
271
+ return false; // Backup keys don't match
272
+ }
273
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PRIVATE_KEY, backupPrivateKey);
274
+ await this.adapter.storage.secureSet(STORAGE_KEYS.PUBLIC_KEY, backupPublicKey);
275
+ const restored = await this.verifyIdentityIntegrity();
276
+ if (restored) {
277
+ // Update cache
278
+ this.cachedPublicKey = backupPublicKey;
279
+ this.cachedHasIdentity = true;
280
+ await this.adapter.storage.set(STORAGE_KEYS.BACKUP_TIMESTAMP, Date.now().toString());
281
+ return true;
282
+ }
283
+ return false;
284
+ } catch (error) {
285
+ console.error('[IdentityManager] Failed to restore identity from backup:', error);
286
+ return false;
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Verify identity integrity - checks if keys are valid and accessible
292
+ */
293
+ async verifyIdentityIntegrity() {
294
+ this.ensureNativePlatform();
295
+ try {
296
+ const privateKey = await this.getPrivateKey();
297
+ const publicKey = await this.getPublicKey();
298
+ if (!privateKey || !publicKey) {
299
+ return false;
300
+ }
301
+
302
+ // Validate private key format
303
+ if (!isValidPrivateKey(privateKey)) {
304
+ return false;
305
+ }
306
+
307
+ // Validate public key format
308
+ if (!isValidPublicKey(publicKey)) {
309
+ return false;
310
+ }
311
+
312
+ // Verify public key can be derived from private key
313
+ const derivedPublicKey = derivePublicKey(privateKey);
314
+ if (derivedPublicKey !== publicKey) {
315
+ return false; // Keys don't match
316
+ }
317
+
318
+ // Verify we can create a key pair object (tests elliptic curve operations)
319
+ const keyPair = await this.getKeyPairObject();
320
+ if (!keyPair) {
321
+ return false;
322
+ }
323
+ return true;
324
+ } catch (error) {
325
+ console.error('[IdentityManager] Identity integrity check failed:', error);
326
+ return false;
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Get the elliptic curve key object from the stored private key
332
+ * Used internally for signing operations
333
+ */
334
+ async getKeyPairObject() {
335
+ this.ensureNativePlatform();
336
+ const privateKey = await this.getPrivateKey();
337
+ if (!privateKey) return null;
338
+ return ec.keyFromPrivate(privateKey);
339
+ }
340
+
341
+ /**
342
+ * Decrypt backup data and import identity
343
+ */
344
+ async decryptAndImportBackup(backupData, password) {
345
+ this.ensureNativePlatform();
346
+ try {
347
+ // Convert hex strings to Uint8Array
348
+ const saltBytes = new Uint8Array(backupData.salt.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
349
+ const ivBytes = new Uint8Array(backupData.iv.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || []);
350
+
351
+ // Derive key from password (same algorithm as EncryptedBackupGenerator)
352
+ const saltHex = Array.from(saltBytes).map(b => b.toString(16).padStart(2, '0')).join('');
353
+ let key = password + saltHex;
354
+ for (let i = 0; i < 10000; i++) {
355
+ key = await this.adapter.crypto.digestStringAsync('SHA256', key);
356
+ }
357
+ const keyBytes = new Uint8Array(32);
358
+ for (let i = 0; i < 64 && i < key.length; i += 2) {
359
+ keyBytes[i / 2] = parseInt(key.substring(i, i + 2), 16);
360
+ }
361
+
362
+ // Decrypt private key (XOR decryption - same as encryption)
363
+ const encryptedBytes = Buffer.from(backupData.encrypted, 'base64');
364
+ const decryptedBytes = new Uint8Array(encryptedBytes.length);
365
+ for (let i = 0; i < encryptedBytes.length; i++) {
366
+ decryptedBytes[i] = encryptedBytes[i] ^ keyBytes[i % keyBytes.length] ^ ivBytes[i % ivBytes.length];
367
+ }
368
+ const privateKey = new TextDecoder().decode(decryptedBytes);
369
+
370
+ // Import the key pair
371
+ return await this.importKeyPair(privateKey);
372
+ } catch (error) {
373
+ throw createIdentitySessionError(IdentitySessionErrorCodes.BACKUP_DECRYPTION_FAILED, `Failed to decrypt backup: ${error instanceof Error ? error.message : String(error)}`);
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Sign a challenge using the stored private key
379
+ */
380
+ async signChallenge(challenge) {
381
+ this.ensureNativePlatform();
382
+ const keyPair = await this.getKeyPairObject();
383
+ if (!keyPair) {
384
+ throw createIdentitySessionError(IdentitySessionErrorCodes.IDENTITY_NOT_FOUND, 'No identity found. Please create or import an identity first.');
385
+ }
386
+
387
+ // Hash the challenge
388
+ const messageHash = await this.adapter.crypto.digestStringAsync('SHA256', challenge);
389
+
390
+ // Sign the hash
391
+ const signature = keyPair.sign(messageHash);
392
+ return signature.toDER('hex');
393
+ }
394
+ }
395
+ //# sourceMappingURL=IdentityManager.js.map