@oxyhq/services 27.1.3 → 29.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/LICENSE +202 -661
  2. package/NOTICE +16 -0
  3. package/README.md +67 -2
  4. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt +178 -0
  5. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionProvider.kt +99 -0
  6. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionStore.kt +115 -0
  7. package/expo-module.config.json +1 -0
  8. package/lib/commonjs/index.js +78 -16
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/ui/boot/runProviderColdBoot.js +7 -0
  11. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  12. package/lib/commonjs/ui/client.js +12 -7
  13. package/lib/commonjs/ui/client.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +10 -27
  15. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  16. package/lib/commonjs/ui/components/OxyAuthChooser.js +132 -44
  17. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  18. package/lib/commonjs/ui/components/OxyProvider.js +4 -2
  19. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  20. package/lib/commonjs/ui/components/SurfaceScreen.js +31 -3
  21. package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
  22. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +209 -84
  23. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  24. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +25 -7
  25. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -1
  26. package/lib/commonjs/ui/components/authChooser/primitives.js +35 -22
  27. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
  28. package/lib/commonjs/ui/components/authChooser/signInProgress.js +5 -0
  29. package/lib/commonjs/ui/components/authChooser/signInProgress.js.map +1 -1
  30. package/lib/commonjs/ui/components/authChooser/types.js +11 -0
  31. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
  32. package/lib/commonjs/ui/context/OxyContext.js +257 -306
  33. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  34. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +27 -37
  35. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  36. package/lib/commonjs/ui/context/oxyContextHelpers.js +0 -29
  37. package/lib/commonjs/ui/context/oxyContextHelpers.js.map +1 -1
  38. package/lib/commonjs/ui/context/useOxyAccountGraph.js +6 -17
  39. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  40. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +42 -0
  41. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -0
  42. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +0 -19
  43. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  44. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +57 -0
  45. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -0
  46. package/lib/commonjs/ui/hooks/useI18n.js +22 -3
  47. package/lib/commonjs/ui/hooks/useI18n.js.map +1 -1
  48. package/lib/commonjs/ui/hooks/useSessionManagement.js +46 -153
  49. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  50. package/lib/commonjs/ui/index.js +12 -7
  51. package/lib/commonjs/ui/index.js.map +1 -1
  52. package/lib/commonjs/ui/navigation/routes.js +85 -73
  53. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  54. package/lib/commonjs/ui/navigation/surfaces.js +8 -7
  55. package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
  56. package/lib/commonjs/ui/runtime/createOxyRuntime.js +433 -0
  57. package/lib/commonjs/ui/runtime/createOxyRuntime.js.map +1 -0
  58. package/lib/commonjs/ui/runtime/index.js +63 -0
  59. package/lib/commonjs/ui/runtime/index.js.map +1 -0
  60. package/lib/commonjs/ui/runtime/runtimeContext.js +83 -0
  61. package/lib/commonjs/ui/runtime/runtimeContext.js.map +1 -0
  62. package/lib/commonjs/ui/runtime/types.js +6 -0
  63. package/lib/commonjs/ui/runtime/types.js.map +1 -0
  64. package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js +57 -0
  65. package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js.map +1 -0
  66. package/lib/commonjs/ui/screens/AccountMembersScreen.js +3 -4
  67. package/lib/commonjs/ui/screens/AccountMembersScreen.js.map +1 -1
  68. package/lib/commonjs/ui/screens/CreateAccountScreen.js +3 -12
  69. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  70. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +6 -5
  71. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  72. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +4 -4
  73. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  74. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
  75. package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js +4 -2
  76. package/lib/commonjs/ui/screens/trust/TrustRulesScreen.js.map +1 -1
  77. package/lib/commonjs/ui/server.js +1 -2
  78. package/lib/commonjs/ui/server.js.map +1 -1
  79. package/lib/commonjs/ui/session/authStore.js +45 -9
  80. package/lib/commonjs/ui/session/authStore.js.map +1 -1
  81. package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js +306 -0
  82. package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js.map +1 -0
  83. package/lib/commonjs/ui/stores/authStore.js +154 -55
  84. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  85. package/lib/commonjs/ui/stores/followTargetStore.js +27 -0
  86. package/lib/commonjs/ui/stores/followTargetStore.js.map +1 -1
  87. package/lib/commonjs/ui/utils/avatarUtils.js +2 -36
  88. package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
  89. package/lib/module/index.js +20 -9
  90. package/lib/module/index.js.map +1 -1
  91. package/lib/module/ui/boot/runProviderColdBoot.js +7 -0
  92. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  93. package/lib/module/ui/client.js +1 -2
  94. package/lib/module/ui/client.js.map +1 -1
  95. package/lib/module/ui/components/OxyAccountDialogScreen.js +10 -27
  96. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  97. package/lib/module/ui/components/OxyAuthChooser.js +134 -44
  98. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  99. package/lib/module/ui/components/OxyProvider.js +5 -3
  100. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  101. package/lib/module/ui/components/SurfaceScreen.js +33 -5
  102. package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
  103. package/lib/module/ui/components/authChooser/AccountsMenuView.js +210 -85
  104. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  105. package/lib/module/ui/components/authChooser/SignInEntryView.js +25 -7
  106. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -1
  107. package/lib/module/ui/components/authChooser/primitives.js +35 -22
  108. package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
  109. package/lib/module/ui/components/authChooser/signInProgress.js +5 -0
  110. package/lib/module/ui/components/authChooser/signInProgress.js.map +1 -1
  111. package/lib/module/ui/components/authChooser/types.js +11 -0
  112. package/lib/module/ui/components/authChooser/types.js.map +1 -1
  113. package/lib/module/ui/context/OxyContext.js +251 -303
  114. package/lib/module/ui/context/OxyContext.js.map +1 -1
  115. package/lib/module/ui/context/hooks/useAuthOperations.js +27 -37
  116. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  117. package/lib/module/ui/context/oxyContextHelpers.js +0 -28
  118. package/lib/module/ui/context/oxyContextHelpers.js.map +1 -1
  119. package/lib/module/ui/context/useOxyAccountGraph.js +6 -17
  120. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  121. package/lib/module/ui/hooks/accountDialogSnapshot.js +38 -0
  122. package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -0
  123. package/lib/module/ui/hooks/mutations/useAccountMutations.js +0 -19
  124. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  125. package/lib/module/ui/hooks/useDeviceSwitcher.js +53 -0
  126. package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -0
  127. package/lib/module/ui/hooks/useI18n.js +24 -4
  128. package/lib/module/ui/hooks/useI18n.js.map +1 -1
  129. package/lib/module/ui/hooks/useSessionManagement.js +47 -155
  130. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  131. package/lib/module/ui/index.js +1 -2
  132. package/lib/module/ui/index.js.map +1 -1
  133. package/lib/module/ui/navigation/routes.js +84 -72
  134. package/lib/module/ui/navigation/routes.js.map +1 -1
  135. package/lib/module/ui/navigation/surfaces.js +6 -6
  136. package/lib/module/ui/navigation/surfaces.js.map +1 -1
  137. package/lib/module/ui/runtime/createOxyRuntime.js +430 -0
  138. package/lib/module/ui/runtime/createOxyRuntime.js.map +1 -0
  139. package/lib/module/ui/runtime/index.js +15 -0
  140. package/lib/module/ui/runtime/index.js.map +1 -0
  141. package/lib/module/ui/runtime/runtimeContext.js +75 -0
  142. package/lib/module/ui/runtime/runtimeContext.js.map +1 -0
  143. package/lib/module/ui/runtime/types.js +4 -0
  144. package/lib/module/ui/runtime/types.js.map +1 -0
  145. package/lib/module/ui/runtime/useRuntimeSnapshot.js +52 -0
  146. package/lib/module/ui/runtime/useRuntimeSnapshot.js.map +1 -0
  147. package/lib/module/ui/screens/AccountMembersScreen.js +4 -5
  148. package/lib/module/ui/screens/AccountMembersScreen.js.map +1 -1
  149. package/lib/module/ui/screens/CreateAccountScreen.js +4 -13
  150. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  151. package/lib/module/ui/screens/trust/TrustCenterScreen.js +6 -5
  152. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  153. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +5 -5
  154. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  155. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
  156. package/lib/module/ui/screens/trust/TrustRulesScreen.js +4 -2
  157. package/lib/module/ui/screens/trust/TrustRulesScreen.js.map +1 -1
  158. package/lib/module/ui/server.js +0 -1
  159. package/lib/module/ui/server.js.map +1 -1
  160. package/lib/module/ui/session/authStore.js +46 -11
  161. package/lib/module/ui/session/authStore.js.map +1 -1
  162. package/lib/module/ui/session/sharedDeviceCredentialStore.js +302 -0
  163. package/lib/module/ui/session/sharedDeviceCredentialStore.js.map +1 -0
  164. package/lib/module/ui/stores/authStore.js +154 -55
  165. package/lib/module/ui/stores/authStore.js.map +1 -1
  166. package/lib/module/ui/stores/followTargetStore.js +25 -0
  167. package/lib/module/ui/stores/followTargetStore.js.map +1 -1
  168. package/lib/module/ui/utils/avatarUtils.js +2 -35
  169. package/lib/module/ui/utils/avatarUtils.js.map +1 -1
  170. package/lib/typescript/commonjs/index.d.ts +6 -4
  171. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  172. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ui/client.d.ts +1 -2
  174. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  175. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  176. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  178. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
  179. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
  180. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +3 -1
  182. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +18 -6
  184. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
  185. package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts.map +1 -1
  186. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +33 -1
  187. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
  188. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +35 -4
  189. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  190. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +8 -12
  191. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  192. package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts +0 -2
  193. package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +9 -1
  195. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  196. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -3
  197. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  198. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +15 -0
  199. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
  200. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  201. package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts +49 -0
  202. package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts +13 -0
  204. package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts.map +1 -1
  205. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +23 -18
  206. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  207. package/lib/typescript/commonjs/ui/index.d.ts +1 -2
  208. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  209. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +15 -1
  210. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
  212. package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts +144 -0
  213. package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/ui/runtime/index.d.ts +16 -0
  215. package/lib/typescript/commonjs/ui/runtime/index.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts +43 -0
  217. package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/ui/runtime/types.d.ts +89 -0
  219. package/lib/typescript/commonjs/ui/runtime/types.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
  221. package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
  222. package/lib/typescript/commonjs/ui/screens/AccountMembersScreen.d.ts.map +1 -1
  223. package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  224. package/lib/typescript/commonjs/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  225. package/lib/typescript/commonjs/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
  226. package/lib/typescript/commonjs/ui/server.d.ts +0 -1
  227. package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
  228. package/lib/typescript/commonjs/ui/session/authStore.d.ts +60 -9
  229. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
  230. package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
  231. package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/ui/stores/authStore.d.ts +49 -5
  233. package/lib/typescript/commonjs/ui/stores/authStore.d.ts.map +1 -1
  234. package/lib/typescript/commonjs/ui/stores/followTargetStore.d.ts +8 -1
  235. package/lib/typescript/commonjs/ui/stores/followTargetStore.d.ts.map +1 -1
  236. package/lib/typescript/commonjs/ui/types/navigation.d.ts +26 -0
  237. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  238. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts +2 -10
  239. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
  240. package/lib/typescript/module/index.d.ts +6 -4
  241. package/lib/typescript/module/index.d.ts.map +1 -1
  242. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  243. package/lib/typescript/module/ui/client.d.ts +1 -2
  244. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  245. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  246. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  247. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  248. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
  249. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
  250. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  251. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +3 -1
  252. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  253. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +18 -6
  254. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
  255. package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts.map +1 -1
  256. package/lib/typescript/module/ui/components/authChooser/types.d.ts +33 -1
  257. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
  258. package/lib/typescript/module/ui/context/OxyContext.d.ts +35 -4
  259. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  260. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +8 -12
  261. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  262. package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts +0 -2
  263. package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts.map +1 -1
  264. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +9 -1
  265. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  266. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -3
  267. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  268. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +15 -0
  269. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
  270. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  271. package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts +49 -0
  272. package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
  273. package/lib/typescript/module/ui/hooks/useI18n.d.ts +13 -0
  274. package/lib/typescript/module/ui/hooks/useI18n.d.ts.map +1 -1
  275. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +23 -18
  276. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  277. package/lib/typescript/module/ui/index.d.ts +1 -2
  278. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  279. package/lib/typescript/module/ui/navigation/routes.d.ts +15 -1
  280. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  281. package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
  282. package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts +144 -0
  283. package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts.map +1 -0
  284. package/lib/typescript/module/ui/runtime/index.d.ts +16 -0
  285. package/lib/typescript/module/ui/runtime/index.d.ts.map +1 -0
  286. package/lib/typescript/module/ui/runtime/runtimeContext.d.ts +43 -0
  287. package/lib/typescript/module/ui/runtime/runtimeContext.d.ts.map +1 -0
  288. package/lib/typescript/module/ui/runtime/types.d.ts +89 -0
  289. package/lib/typescript/module/ui/runtime/types.d.ts.map +1 -0
  290. package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
  291. package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
  292. package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts.map +1 -1
  293. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  294. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  295. package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
  296. package/lib/typescript/module/ui/server.d.ts +0 -1
  297. package/lib/typescript/module/ui/server.d.ts.map +1 -1
  298. package/lib/typescript/module/ui/session/authStore.d.ts +60 -9
  299. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
  300. package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
  301. package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
  302. package/lib/typescript/module/ui/stores/authStore.d.ts +49 -5
  303. package/lib/typescript/module/ui/stores/authStore.d.ts.map +1 -1
  304. package/lib/typescript/module/ui/stores/followTargetStore.d.ts +8 -1
  305. package/lib/typescript/module/ui/stores/followTargetStore.d.ts.map +1 -1
  306. package/lib/typescript/module/ui/types/navigation.d.ts +26 -0
  307. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  308. package/lib/typescript/module/ui/utils/avatarUtils.d.ts +2 -10
  309. package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
  310. package/package.json +8 -8
  311. package/plugins/withSharedDeviceSessionProvider.js +102 -0
  312. package/plugins/withSharedDeviceSessionReader.js +57 -0
  313. package/src/__tests__/esmSourcePurity.test.ts +61 -0
  314. package/src/index.ts +36 -9
  315. package/src/ui/boot/runProviderColdBoot.ts +7 -0
  316. package/src/ui/client.ts +1 -2
  317. package/src/ui/components/OxyAccountDialogScreen.tsx +10 -29
  318. package/src/ui/components/OxyAuthChooser.tsx +149 -50
  319. package/src/ui/components/OxyProvider.tsx +7 -5
  320. package/src/ui/components/SurfaceScreen.tsx +28 -4
  321. package/src/ui/components/__tests__/followTargetButton.test.ts +39 -0
  322. package/src/ui/components/authChooser/AccountsMenuView.tsx +246 -96
  323. package/src/ui/components/authChooser/SignInEntryView.tsx +31 -8
  324. package/src/ui/components/authChooser/primitives.tsx +37 -23
  325. package/src/ui/components/authChooser/signInProgress.ts +4 -0
  326. package/src/ui/components/authChooser/types.ts +34 -1
  327. package/src/ui/context/OxyContext.tsx +269 -324
  328. package/src/ui/context/hooks/useAuthOperations.ts +32 -35
  329. package/src/ui/context/oxyContextHelpers.ts +0 -30
  330. package/src/ui/context/oxyContextTypes.ts +9 -1
  331. package/src/ui/context/useOxyAccountGraph.ts +5 -19
  332. package/src/ui/hooks/accountDialogSnapshot.ts +37 -0
  333. package/src/ui/hooks/mutations/useAccountMutations.ts +0 -19
  334. package/src/ui/hooks/queries/__tests__/userCache.test.ts +12 -1
  335. package/src/ui/hooks/useDeviceSwitcher.ts +110 -0
  336. package/src/ui/hooks/useI18n.ts +23 -3
  337. package/src/ui/hooks/useSessionManagement.ts +62 -211
  338. package/src/ui/index.ts +1 -2
  339. package/src/ui/navigation/routes.ts +85 -75
  340. package/src/ui/navigation/surfaces.ts +6 -9
  341. package/src/ui/runtime/createOxyRuntime.ts +623 -0
  342. package/src/ui/runtime/index.ts +34 -0
  343. package/src/ui/runtime/runtimeContext.tsx +111 -0
  344. package/src/ui/runtime/types.ts +110 -0
  345. package/src/ui/runtime/useRuntimeSnapshot.ts +52 -0
  346. package/src/ui/screens/AccountMembersScreen.tsx +6 -5
  347. package/src/ui/screens/CreateAccountScreen.tsx +3 -16
  348. package/src/ui/screens/trust/TrustCenterScreen.tsx +7 -7
  349. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +4 -5
  350. package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
  351. package/src/ui/screens/trust/TrustRulesScreen.tsx +3 -2
  352. package/src/ui/server.ts +0 -1
  353. package/src/ui/session/__tests__/authStore.test.ts +90 -0
  354. package/src/ui/session/__tests__/sharedDeviceCredentialStore.test.ts +289 -0
  355. package/src/ui/session/authStore.ts +78 -9
  356. package/src/ui/session/sharedDeviceCredentialStore.ts +318 -0
  357. package/src/ui/stores/authStore.ts +171 -43
  358. package/src/ui/stores/followTargetStore.ts +24 -1
  359. package/src/ui/types/navigation.ts +26 -0
  360. package/src/ui/utils/avatarUtils.ts +2 -37
  361. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +0 -64
  362. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +0 -1
  363. package/lib/commonjs/ui/screens/trust/trustTier.js +0 -23
  364. package/lib/commonjs/ui/screens/trust/trustTier.js.map +0 -1
  365. package/lib/commonjs/ui/stores/accountStore.js +0 -221
  366. package/lib/commonjs/ui/stores/accountStore.js.map +0 -1
  367. package/lib/module/ui/hooks/useSwitchableAccounts.js +0 -60
  368. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +0 -1
  369. package/lib/module/ui/screens/trust/trustTier.js +0 -19
  370. package/lib/module/ui/screens/trust/trustTier.js.map +0 -1
  371. package/lib/module/ui/stores/accountStore.js +0 -213
  372. package/lib/module/ui/stores/accountStore.js.map +0 -1
  373. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +0 -23
  374. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
  375. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +0 -9
  376. package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +0 -1
  377. package/lib/typescript/commonjs/ui/stores/accountStore.d.ts +0 -27
  378. package/lib/typescript/commonjs/ui/stores/accountStore.d.ts.map +0 -1
  379. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +0 -23
  380. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
  381. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +0 -9
  382. package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +0 -1
  383. package/lib/typescript/module/ui/stores/accountStore.d.ts +0 -27
  384. package/lib/typescript/module/ui/stores/accountStore.d.ts.map +0 -1
  385. package/src/ui/hooks/useSwitchableAccounts.ts +0 -75
  386. package/src/ui/screens/trust/trustTier.ts +0 -20
  387. package/src/ui/stores/accountStore.ts +0 -264
@@ -123,5 +123,31 @@ export interface OxyProviderProps {
123
123
  * @default false
124
124
  */
125
125
  backgroundSession?: boolean;
126
+ /**
127
+ * Whether this origin/app may persist the durable device credential
128
+ * (`deviceId` + `deviceSecret`) at all.
129
+ *
130
+ * `'persistent'` (the default, and every app's behaviour) stores it — web
131
+ * localStorage per origin, SecureStore per app on native — so the SDK can
132
+ * re-mint an access token on the next cold boot.
133
+ *
134
+ * `'ephemeral'` stores NOTHING durable: the session lives in memory for the
135
+ * lifetime of the page and is gone on reload. It exists for ONE caller,
136
+ * `auth.oxy.so` with the browser hub enabled (issue #937 Phase 5, ADR 0003),
137
+ * where the durable credential for the browser profile is the server-side
138
+ * DeviceSession behind the `__Host-oxy-device` handle. Two durable
139
+ * credentials for one origin is the dual authority that phase exists to
140
+ * remove — revoking the hub while a localStorage secret still mints would
141
+ * make a sign-out look like it worked — so the way to let the hub be
142
+ * authoritative is to stop persisting the other one, not to consult it
143
+ * second.
144
+ *
145
+ * Do NOT reach for this to make an app "more private". A relying-party
146
+ * origin set to `'ephemeral'` simply signs the user out on every reload,
147
+ * because nothing else on that origin remembers the device.
148
+ *
149
+ * @default 'persistent'
150
+ */
151
+ deviceCredentialStorage?: 'persistent' | 'ephemeral';
126
152
  }
127
153
  //# sourceMappingURL=navigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../../src/ui/types/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAiB,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAgB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAE5B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,eAAe,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGrC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAGlC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,YAAY,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAGjE,aAAa,CAAC,EAAE,SAAS,CAAC;IAG1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAGnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IAMtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACtC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,uBAAuB,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;CACxD"}
@@ -2,16 +2,8 @@ import type { OxyServices, User } from '@oxyhq/core';
2
2
  import type { UserProfileUpdate } from '@oxyhq/contracts';
3
3
  import type { QueryClient } from '@tanstack/react-query';
4
4
  /**
5
- * Refreshes avatar in accountStore with cache-busted URL to force image reload.
6
- *
7
- * @param sessionId - The session ID for the account to update
8
- * @param avatarFileId - The new avatar file ID
9
- * @param oxyServices - OxyServices instance to generate download URL
10
- */
11
- export declare function refreshAvatarInStore(sessionId: string, avatarFileId: string, oxyServices: OxyServices): void;
12
- /**
13
- * Updates user profile with avatar and handles all side effects (query invalidation, accountStore update).
14
- * This function can be used from within OxyContext provider without requiring useOxy hook.
5
+ * Updates user profile with avatar and handles all side effects (cache writes,
6
+ * query invalidation). Usable from inside the provider without `useOxy`.
15
7
  *
16
8
  * @param updates - Profile updates including avatar
17
9
  * @param oxyServices - OxyServices instance
@@ -1 +1 @@
1
- {"version":3,"file":"avatarUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/avatarUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,GACvB,IAAI,CAON;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAyCf"}
1
+ {"version":3,"file":"avatarUtils.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/avatarUtils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAOzD;;;;;;;;;;GAUG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,EAC1B,WAAW,EAAE,WAAW,EACxB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@oxyhq/services",
3
- "version": "27.1.3",
3
+ "version": "29.0.0",
4
4
  "description": "OxyHQ Expo/React Native SDK — UI components, screens, and native features",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
7
7
  "types": "lib/typescript/commonjs/index.d.ts",
8
8
  "react-native": "src/index.ts",
9
9
  "source": "src/index.ts",
10
- "sideEffects": false,
11
10
  "publishConfig": {
12
11
  "access": "public"
13
12
  },
@@ -77,6 +76,7 @@
77
76
  "./package.json": "./package.json"
78
77
  },
79
78
  "files": [
79
+ "NOTICE",
80
80
  "src",
81
81
  "lib",
82
82
  "assets",
@@ -103,7 +103,7 @@
103
103
  "directory": "packages/services"
104
104
  },
105
105
  "author": "OxyHQ",
106
- "license": "AGPL-3.0-only",
106
+ "license": "Apache-2.0",
107
107
  "engines": {
108
108
  "node": ">=18.0.0"
109
109
  },
@@ -138,7 +138,7 @@
138
138
  }
139
139
  },
140
140
  "dependencies": {
141
- "@oxyhq/contracts": "0.24.0",
141
+ "@oxyhq/contracts": "0.26.0",
142
142
  "@simplewebauthn/browser": "^13.3.0",
143
143
  "color": "^4.2.3"
144
144
  },
@@ -147,10 +147,10 @@
147
147
  "@commitlint/cli": "^21.2.1",
148
148
  "@commitlint/config-conventional": "^21.2.0",
149
149
  "@expo/vector-icons": "^15.0.3",
150
- "@oxyhq/core": "19.1.2",
150
+ "@oxyhq/core": "21.0.0",
151
151
  "@react-native-async-storage/async-storage": "^2.0.0",
152
152
  "@react-native-community/netinfo": "^11.4.1",
153
- "@react-native/babel-preset": "^0.86.0",
153
+ "@react-native/babel-preset": "^0.86.2",
154
154
  "@release-it/conventional-changelog": "^10.0.6",
155
155
  "@tanstack/query-async-storage-persister": "^5.101",
156
156
  "@tanstack/query-sync-storage-persister": "^5.101",
@@ -183,14 +183,14 @@
183
183
  "react-native-svg": "15.15.5",
184
184
  "release-it": "^19.0.6",
185
185
  "socket.io-client": "^4.8.1",
186
- "ts-jest": "^29.4.0",
186
+ "ts-jest": "^29.4.12",
187
187
  "typescript": "^5.9.2",
188
188
  "zustand": "^5.0.14"
189
189
  },
190
190
  "peerDependencies": {
191
191
  "@expo/vector-icons": "^15.0.3",
192
192
  "@oxyhq/bloom": ">=0.59.0",
193
- "@oxyhq/core": "^19.0.0",
193
+ "@oxyhq/core": "^21.0.0",
194
194
  "@react-native-async-storage/async-storage": "^2.0.0",
195
195
  "@react-native-community/netinfo": ">=11.4.1",
196
196
  "@tanstack/query-async-storage-persister": "^5.101",
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Config plugin: withSharedDeviceSessionProvider (UID-member hub apps).
3
+ *
4
+ * The shared DeviceSession credential is how several official Oxy apps end up on
5
+ * ONE `DeviceSession` — and therefore one globally active account context —
6
+ * WITHOUT any of them reading Commons's private identity key. This plugin wires
7
+ * the Android side of `@oxyhq/services`:
8
+ *
9
+ * - Defines a `signature`-level permission
10
+ * `so.oxy.shared.permission.READ_DEVICE_SESSION`. `signature` means only apps
11
+ * signed with the SAME certificate (the shared Oxy release keystore) can hold
12
+ * it — the trust boundary is the signing key, not the deprecated `sharedUserId`.
13
+ * - Requests that same permission so this app can also read cross-authority.
14
+ * - Declares `OxyDeviceSessionProvider` at authority
15
+ * `${applicationId}.devicesession` (AGP substitutes `${applicationId}` at
16
+ * build), guarded by that permission. The provider is READ-only across the
17
+ * process boundary: a sibling may join the device session, never overwrite it.
18
+ * - Adds `<queries>` entries so Android 11+ package-visibility filtering never
19
+ * hides the sibling providers from the resolver.
20
+ *
21
+ * WHICH APPS USE THIS PLUGIN: exactly the apps listed in `PROVIDER_AUTHORITIES`
22
+ * below, which must be apps inside the `so.oxy.shared` UID. UID members share one
23
+ * data directory, so they all serve the SAME file and the sweep in
24
+ * `OxyDeviceSessionModule` is deterministic whichever one answers. An app that is
25
+ * same-signature but outside that UID must use `withSharedDeviceSessionReader`
26
+ * instead — hosting from there would publish a second, independent copy of "the
27
+ * shared credential" and make the winner depend on list order.
28
+ *
29
+ * Keep this list identical to `PROVIDER_AUTHORITIES` in
30
+ * `android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt`.
31
+ *
32
+ * This is deliberately a SEPARATE permission and a SEPARATE provider from
33
+ * `withSharedIdentityProvider`. Two secrets with different blast radii: the
34
+ * identity key is self-custody and irreplaceable, the device credential is
35
+ * server-revocable and re-publishable. An app that only needs a session gets only
36
+ * the second one.
37
+ */
38
+ const { withAndroidManifest } = require('@expo/config-plugins');
39
+
40
+ const READ_DEVICE_SESSION_PERMISSION = 'so.oxy.shared.permission.READ_DEVICE_SESSION';
41
+ const PROVIDER_CLASS = 'so.oxy.devicesession.OxyDeviceSessionProvider';
42
+ const PROVIDER_AUTHORITIES = [
43
+ 'so.oxy.accounts.devicesession',
44
+ 'so.oxy.accounts.dev.devicesession',
45
+ 'so.oxy.commons.devicesession',
46
+ 'so.oxy.commons.dev.devicesession',
47
+ ];
48
+
49
+ module.exports = function withSharedDeviceSessionProvider(config) {
50
+ return withAndroidManifest(config, (modConfig) => {
51
+ const manifest = modConfig.modResults.manifest;
52
+
53
+ // 1. Define the signature-level permission.
54
+ manifest['permission'] = manifest['permission'] ?? [];
55
+ if (!manifest['permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
56
+ manifest['permission'].push({
57
+ $: {
58
+ 'android:name': READ_DEVICE_SESSION_PERMISSION,
59
+ 'android:protectionLevel': 'signature',
60
+ },
61
+ });
62
+ }
63
+
64
+ // 2. Request it (a hub app reads its siblings too — prod ⇆ dev variant).
65
+ manifest['uses-permission'] = manifest['uses-permission'] ?? [];
66
+ if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
67
+ manifest['uses-permission'].push({ $: { 'android:name': READ_DEVICE_SESSION_PERMISSION } });
68
+ }
69
+
70
+ // 3. Make the sibling provider authorities visible under package filtering.
71
+ manifest['queries'] = manifest['queries'] ?? [];
72
+ if (manifest['queries'].length === 0) {
73
+ manifest['queries'].push({});
74
+ }
75
+ const queries = manifest['queries'][0];
76
+ queries.provider = queries.provider ?? [];
77
+ for (const authority of PROVIDER_AUTHORITIES) {
78
+ if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
79
+ queries.provider.push({ $: { 'android:authorities': authority } });
80
+ }
81
+ }
82
+
83
+ // 4. Host the provider.
84
+ const app = manifest.application?.[0];
85
+ if (!app) {
86
+ throw new Error('withSharedDeviceSessionProvider: AndroidManifest has no <application>');
87
+ }
88
+ app.provider = app.provider ?? [];
89
+ if (!app.provider.some((p) => p.$['android:name'] === PROVIDER_CLASS)) {
90
+ app.provider.push({
91
+ $: {
92
+ 'android:name': PROVIDER_CLASS,
93
+ 'android:authorities': '${applicationId}.devicesession',
94
+ 'android:exported': 'true',
95
+ 'android:permission': READ_DEVICE_SESSION_PERMISSION,
96
+ },
97
+ });
98
+ }
99
+
100
+ return modConfig;
101
+ });
102
+ };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Config plugin: withSharedDeviceSessionReader (every other official Oxy app).
3
+ *
4
+ * A reader app JOINS the device's existing session — it adopts the shared
5
+ * `deviceId` + `deviceSecret` a hub app published, so it lands signed in with no
6
+ * QR and, crucially, without ever asking for Commons's private identity key.
7
+ * This plugin wires the minimal Android side of `@oxyhq/services`:
8
+ *
9
+ * - Requests the `signature`-level permission
10
+ * `so.oxy.shared.permission.READ_DEVICE_SESSION` (defined by the hub apps).
11
+ * Because it is `signature`, it is granted only when this app is signed with
12
+ * the SAME certificate as the hub — that is the entire trust boundary, and it
13
+ * is what makes an incorrectly-signed app unable to read the slot.
14
+ * - Adds `<queries>` entries for the hub authorities so package-visibility
15
+ * filtering (Android 11+) never hides them from `ContentResolver.call`.
16
+ *
17
+ * The provider itself is declared only by the hub apps
18
+ * (`withSharedDeviceSessionProvider`) — see the note there about why hosting is
19
+ * restricted to apps inside the `so.oxy.shared` UID.
20
+ *
21
+ * Keep this list identical to `PROVIDER_AUTHORITIES` in
22
+ * `android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt`.
23
+ */
24
+ const { withAndroidManifest } = require('@expo/config-plugins');
25
+
26
+ const READ_DEVICE_SESSION_PERMISSION = 'so.oxy.shared.permission.READ_DEVICE_SESSION';
27
+ const PROVIDER_AUTHORITIES = [
28
+ 'so.oxy.accounts.devicesession',
29
+ 'so.oxy.accounts.dev.devicesession',
30
+ 'so.oxy.commons.devicesession',
31
+ 'so.oxy.commons.dev.devicesession',
32
+ ];
33
+
34
+ module.exports = function withSharedDeviceSessionReader(config) {
35
+ return withAndroidManifest(config, (modConfig) => {
36
+ const manifest = modConfig.modResults.manifest;
37
+
38
+ manifest['uses-permission'] = manifest['uses-permission'] ?? [];
39
+ if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_DEVICE_SESSION_PERMISSION)) {
40
+ manifest['uses-permission'].push({ $: { 'android:name': READ_DEVICE_SESSION_PERMISSION } });
41
+ }
42
+
43
+ manifest['queries'] = manifest['queries'] ?? [];
44
+ if (manifest['queries'].length === 0) {
45
+ manifest['queries'].push({});
46
+ }
47
+ const queries = manifest['queries'][0];
48
+ queries.provider = queries.provider ?? [];
49
+ for (const authority of PROVIDER_AUTHORITIES) {
50
+ if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
51
+ queries.provider.push({ $: { 'android:authorities': authority } });
52
+ }
53
+ }
54
+
55
+ return modConfig;
56
+ });
57
+ };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * `@oxyhq/services` ships an ESM build, and ESM has no `require`.
3
+ *
4
+ * This is not a style rule: a surviving `require()` puts web bundlers into
5
+ * CommonJS interop, which hands consumers `undefined` bindings with no build
6
+ * error and no warning. It blanked auth.oxy.so/authorize once — see the note on
7
+ * `screenComponents` in `../ui/navigation/routes` for the mechanism, and
8
+ * `README.md` for the incident.
9
+ *
10
+ * Deferring is still legitimate: a thunk over a static import defers a READ,
11
+ * `import()` defers a LOAD. Neither needs `require()`.
12
+ */
13
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
14
+ import { join, relative } from 'node:path';
15
+
16
+ const SRC_ROOT = join(__dirname, '..');
17
+
18
+ /** Source extensions that end up in the published ESM build. */
19
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx'];
20
+
21
+ /** Tests are compiled to CommonJS by ts-jest and never ship, so they are exempt. */
22
+ const EXEMPT_SEGMENTS = ['__tests__'];
23
+
24
+ function collectSourceFiles(dir: string): string[] {
25
+ const found: string[] = [];
26
+ for (const entry of readdirSync(dir)) {
27
+ const path = join(dir, entry);
28
+ if (statSync(path).isDirectory()) {
29
+ if (EXEMPT_SEGMENTS.includes(entry)) continue;
30
+ found.push(...collectSourceFiles(path));
31
+ continue;
32
+ }
33
+ if (SOURCE_EXTENSIONS.some((ext) => path.endsWith(ext)) && !path.endsWith('.d.ts')) {
34
+ found.push(path);
35
+ }
36
+ }
37
+ return found;
38
+ }
39
+
40
+ /**
41
+ * Drop comments and string/template literals so prose about `require()` — such
42
+ * as the notes explaining this very rule — is not mistaken for a call.
43
+ */
44
+ function stripCommentsAndStrings(code: string): string {
45
+ return code
46
+ .replace(/\/\*[\s\S]*?\*\//g, '')
47
+ .replace(/(^|[^:])\/\/.*$/gm, '$1')
48
+ .replace(/'(?:[^'\\\n]|\\.)*'/g, "''")
49
+ .replace(/"(?:[^"\\\n]|\\.)*"/g, '""')
50
+ .replace(/`(?:[^`\\]|\\.)*`/g, '``');
51
+ }
52
+
53
+ describe('ESM source purity', () => {
54
+ it('never calls require() anywhere in the shipped source', () => {
55
+ const offenders = collectSourceFiles(SRC_ROOT)
56
+ .filter((file) => /\brequire\s*\(/.test(stripCommentsAndStrings(readFileSync(file, 'utf8'))))
57
+ .map((file) => relative(SRC_ROOT, file));
58
+
59
+ expect(offenders).toEqual([]);
60
+ });
61
+ });
package/src/index.ts CHANGED
@@ -33,6 +33,29 @@ setPlatformOS(Platform.OS as PlatformOS);
33
33
  // ---------------------------------------------------------------------------
34
34
  export { default as OxyProvider } from './ui/components/OxyProvider';
35
35
  export { useOxy } from './ui/context/OxyContext';
36
+ // `useOxy()` THROWS when no provider is mounted. `useOptionalOxy()` returns
37
+ // `null` instead, for the rare component that renders on both sides of the
38
+ // provider boundary; there is no fabricated forever-loading runtime.
39
+ export { useOptionalOxy, OxyProviderMissingError } from './ui/context/OxyContext';
40
+
41
+ // The runtime surface (ADR 0004). These subscribe to the ONE runtime with a
42
+ // selector, so — unlike `useOxy()`, whose value is rebuilt by any of its fifty
43
+ // members moving — a locale change or a dialog opening does not re-render them.
44
+ export {
45
+ useOxyRuntime,
46
+ useOxySnapshot,
47
+ useActiveAccount,
48
+ useDeviceDirectory,
49
+ OxyRuntimeMissingError,
50
+ } from './ui/runtime';
51
+ export type {
52
+ ActiveAccount,
53
+ OxyRuntime,
54
+ OxyRuntimeError,
55
+ OxyRuntimeSnapshot,
56
+ OxyRuntimeStatus,
57
+ OxyTokenStatus,
58
+ } from './ui/runtime';
36
59
  export type { OxyContextState } from './ui/context/OxyContext';
37
60
  export { useAuth } from './ui/hooks/useAuth';
38
61
  export type { AuthState, AuthActions, UseAuthReturn } from './ui/hooks/useAuth';
@@ -45,7 +68,6 @@ export { IdentityBoundSessionError } from './ui/session/identityBinding';
45
68
  // Zustand stores
46
69
  // ---------------------------------------------------------------------------
47
70
  export { useAuthStore } from './ui/stores/authStore';
48
- export { useAccountStore } from './ui/stores/accountStore';
49
71
  export {
50
72
  useAssetStore,
51
73
  useAssets as useAssetsStore,
@@ -306,6 +328,11 @@ export {
306
328
  // guide most likely to be reached for did not resolve.
307
329
  isFollowedGlobally,
308
330
  withApplicationMode,
331
+ // Whether a cached status is safe to act on without a round trip — list rows
332
+ // often carry globalState without relationshipId.
333
+ isCompleteFollowStatus,
334
+ followRecordToStatus,
335
+ followRecordsToStatusMap,
309
336
  } from './ui/stores/followTargetStore';
310
337
  export { default as OxyPayButton } from './ui/components/OxyPayButton';
311
338
  export { LogoIcon } from './ui/components/logo/LogoIcon';
@@ -338,14 +365,14 @@ export { OxySignInRequestSurface } from './ui/components/OxySignInRequestSurface
338
365
  export type { OxySignInRequestSurfaceProps } from './ui/components/OxySignInRequestSurface';
339
366
  export type { OxySignInSurfaceAction } from './ui/components/authChooser/types';
340
367
 
341
- // Unified switchable-accounts hook — the single source of everything the user
342
- // can switch into: device sign-ins AND linked graph accounts (owned orgs +
343
- // shared-with-you), deduped by account id and hydrated with real
344
- // name/email/avatar/color. Backed by the shared `AccountDialogController` in
345
- // `@oxyhq/core`. Every switch routes through `useOxy().switchToAccount`.
346
- // The `SwitchableAccount` type lives in `@oxyhq/core` — import it from there.
347
- export { useSwitchableAccounts } from './ui/hooks/useSwitchableAccounts';
348
- export type { UseSwitchableAccountsResult } from './ui/hooks/useSwitchableAccounts';
368
+ // The device switcher — the server's own directory (ADR 0002) of who is signed
369
+ // in here and what each of them may act as, grouped by PERSON, with the two
370
+ // removals an account id cannot name. Backed by the shared
371
+ // `AccountDialogController` in `@oxyhq/core`; selecting a row activates a
372
+ // `contextId`. `DevicePrincipalGroup` and `DeviceContext` live in `@oxyhq/core`
373
+ // — import them from there.
374
+ export { useDeviceSwitcher } from './ui/hooks/useDeviceSwitcher';
375
+ export type { UseDeviceSwitcherResult } from './ui/hooks/useDeviceSwitcher';
349
376
 
350
377
  // Unified "Manage your Oxy Account" screen (the caller's own personal account)
351
378
  export { default as ProfileScreen } from './ui/screens/ProfileScreen';
@@ -8,6 +8,7 @@ import {
8
8
  } from '@oxyhq/core';
9
9
  import type { SessionClient } from '@oxyhq/core';
10
10
  import { loadPersistedDeviceCredential } from '../utils/deviceCredential';
11
+ import { createPlatformSharedDeviceCredentialStore } from '../session/sharedDeviceCredentialStore';
11
12
  import { tryCompleteOAuthReturn } from '../utils/oauthReturn';
12
13
  import { isWebBrowser } from '../utils/isWebBrowser';
13
14
  import { isNetConnectivityExplicitlyOffline } from '../utils/netConnectivity';
@@ -161,6 +162,12 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
161
162
  platform: { isWeb: isWebBrowser(), isNative: !isWebBrowser() },
162
163
  sessionMode,
163
164
  identity,
165
+ // The device-wide shared credential slot, enabling the `shared-device-adopt`
166
+ // lane: a newly installed official app joins this device's existing session
167
+ // instead of falling back to signing a challenge with the Commons identity
168
+ // key. `null` on web, where each origin is its own device by design; the
169
+ // core lane is also skipped outright in `sessionMode: 'identity'`.
170
+ sharedDeviceCredential: createPlatformSharedDeviceCredentialStore() ?? undefined,
164
171
  overallDeadlineMs: COLD_BOOT_OVERALL_DEADLINE_MS,
165
172
  isOffline: () => offline,
166
173
  onStepDeadline: (stepId) => {
package/src/ui/client.ts CHANGED
@@ -19,7 +19,7 @@ export { default as FollowButton } from './components/FollowButton';
19
19
  export { default as OxyPayButton } from './components/OxyPayButton';
20
20
 
21
21
  // Context
22
- export { useOxy } from './context/OxyContext';
22
+ export { useOxy, useOptionalOxy, OxyProviderMissingError } from './context/OxyContext';
23
23
 
24
24
  // Hooks
25
25
  export { useAuth } from './hooks/useAuth';
@@ -34,7 +34,6 @@ export { default as ManageAccountScreen } from './screens/ManageAccountScreen';
34
34
 
35
35
  // Stores
36
36
  export { useAuthStore } from './stores/authStore';
37
- export { useAccountStore } from './stores/accountStore';
38
37
 
39
38
  // Error handler utilities
40
39
  export {
@@ -31,6 +31,7 @@ import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
31
31
  import type { BaseScreenProps } from '../types/navigation';
32
32
  import LogoText from './logo/LogoText';
33
33
  import OxyAuthChooser from './OxyAuthChooser';
34
+ import { EMPTY_ACCOUNT_DIALOG_SNAPSHOT } from '../hooks/accountDialogSnapshot';
34
35
 
35
36
  type Translate = ReturnType<typeof useI18n>['t'];
36
37
 
@@ -61,20 +62,22 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
61
62
 
62
63
  // A lightweight, header-only binding to the same controller `OxyAuthChooser`
63
64
  // binds independently — cheap, and the established pattern here (
64
- // `useSwitchableAccounts` also binds to this controller on its own).
65
+ // `useDeviceSwitcher` also binds to this controller on its own).
65
66
  const subscribe = useCallback(
66
67
  (listener: () => void) => (controller ? controller.subscribe(listener) : () => undefined),
67
68
  [controller],
68
69
  );
69
70
  const getSnapshot = useCallback(
70
- () => (controller ? controller.getSnapshot() : EMPTY_SNAPSHOT),
71
+ () => (controller ? controller.getSnapshot() : EMPTY_ACCOUNT_DIALOG_SNAPSHOT),
71
72
  [controller],
72
73
  );
73
74
  const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
74
75
 
75
76
  const { view } = snapshot;
76
- const showBack =
77
- view === 'qr' || view === 'signup' || (view === 'add' && snapshot.accounts.length > 0);
77
+ // "Add another account" only makes sense as a back destination when there IS
78
+ // another i.e. somebody is already signed in on this device.
79
+ const hasSignedInAccounts = (snapshot.directory?.principals.length ?? 0) > 0;
80
+ const showBack = view === 'qr' || view === 'signup' || (view === 'add' && hasSignedInAccounts);
78
81
  const goToAccounts = useCallback(() => {
79
82
  if (!controller) return;
80
83
  const { view: currentView, signIn } = controller.getSnapshot();
@@ -100,7 +103,7 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
100
103
  // by the bar. Every OTHER view keeps the SHARED Dialog nav header the rest of
101
104
  // the SDK uses — a large in-content title/subtitle that collapses into the bar
102
105
  // on scroll — because their copy is informative.
103
- const copy = view === 'accounts' ? null : headerCopy(view, snapshot.accounts.length, t);
106
+ const copy = view === 'accounts' ? null : headerCopy(view, hasSignedInAccounts, t);
104
107
 
105
108
  useSurfaceHeader({
106
109
  titleContent: copy ? undefined : NAV_LOGO,
@@ -126,7 +129,7 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
126
129
 
127
130
  function headerCopy(
128
131
  view: Exclude<AccountDialogSnapshot['view'], 'accounts'>,
129
- accountCount: number,
132
+ hasSignedInAccounts: boolean,
130
133
  t: Translate,
131
134
  ): { title: string; subtitle: string | null } {
132
135
  switch (view) {
@@ -147,7 +150,7 @@ function headerCopy(
147
150
  subtitle: t('signup.subtitle') || 'One identity for the whole ecosystem.',
148
151
  };
149
152
  default:
150
- return accountCount > 0
153
+ return hasSignedInAccounts
151
154
  ? {
152
155
  title: t('signin.addAccountTitle') || 'Add another account',
153
156
  subtitle: t('signin.addAccountSubtitle') || 'Sign in with another account.',
@@ -159,28 +162,6 @@ function headerCopy(
159
162
  }
160
163
  }
161
164
 
162
- const EMPTY_SNAPSHOT: AccountDialogSnapshot = {
163
- view: 'accounts',
164
- accounts: [],
165
- activeAccountId: null,
166
- loading: false,
167
- error: null,
168
- switchingAccountId: null,
169
- signIn: {
170
- phase: 'idle',
171
- authorizeCode: null,
172
- qrPayload: null,
173
- expiresAt: null,
174
- error: null,
175
- route: null,
176
- routeFailed: false,
177
- pushSentAt: null,
178
- openedAt: null,
179
- progress: 'idle',
180
- },
181
- commonsAvailability: 'unknown',
182
- };
183
-
184
165
  /**
185
166
  * The screen gutter. In the Dialog's nav-header mode the surface adds NO content
186
167
  * padding of its own — the large title and each screen own theirs — so this must