@oxy.so/core 1.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 (673) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +16 -0
  3. package/README.md +221 -0
  4. package/dist/cjs/.tsbuildinfo +1 -0
  5. package/dist/cjs/HttpService.js +1270 -0
  6. package/dist/cjs/OxyServices.base.js +390 -0
  7. package/dist/cjs/OxyServices.errors.js +95 -0
  8. package/dist/cjs/OxyServices.js +72 -0
  9. package/dist/cjs/boot/sessionColdBoot.js +395 -0
  10. package/dist/cjs/constants/version.js +16 -0
  11. package/dist/cjs/crypto/aead.js +79 -0
  12. package/dist/cjs/crypto/ecdh.js +35 -0
  13. package/dist/cjs/crypto/identityMarker.js +255 -0
  14. package/dist/cjs/crypto/kdf.js +39 -0
  15. package/dist/cjs/crypto/keyManager.js +2234 -0
  16. package/dist/cjs/crypto/polyfill.js +131 -0
  17. package/dist/cjs/crypto/recoveryPhrase.js +242 -0
  18. package/dist/cjs/crypto/signatureService.js +273 -0
  19. package/dist/cjs/i18n/accountCategoryLabels.js +44 -0
  20. package/dist/cjs/i18n/accountRoleLabels.js +27 -0
  21. package/dist/cjs/i18n/index.js +90 -0
  22. package/dist/cjs/i18n/locales/ar-SA.json +282 -0
  23. package/dist/cjs/i18n/locales/ca-ES.json +282 -0
  24. package/dist/cjs/i18n/locales/de-DE.json +282 -0
  25. package/dist/cjs/i18n/locales/en-US.json +2161 -0
  26. package/dist/cjs/i18n/locales/es-ES.json +2161 -0
  27. package/dist/cjs/i18n/locales/fr-FR.json +282 -0
  28. package/dist/cjs/i18n/locales/it-IT.json +282 -0
  29. package/dist/cjs/i18n/locales/ja-JP.json +282 -0
  30. package/dist/cjs/i18n/locales/ko-KR.json +282 -0
  31. package/dist/cjs/i18n/locales/locales/ar-SA.json +282 -0
  32. package/dist/cjs/i18n/locales/locales/ca-ES.json +282 -0
  33. package/dist/cjs/i18n/locales/locales/de-DE.json +282 -0
  34. package/dist/cjs/i18n/locales/locales/en-US.json +2161 -0
  35. package/dist/cjs/i18n/locales/locales/es-ES.json +2161 -0
  36. package/dist/cjs/i18n/locales/locales/fr-FR.json +282 -0
  37. package/dist/cjs/i18n/locales/locales/it-IT.json +282 -0
  38. package/dist/cjs/i18n/locales/locales/ja-JP.json +282 -0
  39. package/dist/cjs/i18n/locales/locales/ko-KR.json +282 -0
  40. package/dist/cjs/i18n/locales/locales/pt-PT.json +282 -0
  41. package/dist/cjs/i18n/locales/locales/zh-CN.json +282 -0
  42. package/dist/cjs/i18n/locales/pt-PT.json +282 -0
  43. package/dist/cjs/i18n/locales/zh-CN.json +282 -0
  44. package/dist/cjs/i18n/reputationCategoryLabels.js +20 -0
  45. package/dist/cjs/i18n/trustTierLabels.js +19 -0
  46. package/dist/cjs/index.js +498 -0
  47. package/dist/cjs/inference/OxyInferenceClient.js +544 -0
  48. package/dist/cjs/logger/index.js +149 -0
  49. package/dist/cjs/mixins/OxyServices.accounts.js +555 -0
  50. package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
  51. package/dist/cjs/mixins/OxyServices.appData.js +108 -0
  52. package/dist/cjs/mixins/OxyServices.assets.js +764 -0
  53. package/dist/cjs/mixins/OxyServices.auth.js +1254 -0
  54. package/dist/cjs/mixins/OxyServices.chains.js +73 -0
  55. package/dist/cjs/mixins/OxyServices.civic.js +611 -0
  56. package/dist/cjs/mixins/OxyServices.connectedApps.js +78 -0
  57. package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
  58. package/dist/cjs/mixins/OxyServices.deviceBoot.js +191 -0
  59. package/dist/cjs/mixins/OxyServices.deviceTransfer.js +314 -0
  60. package/dist/cjs/mixins/OxyServices.devices.js +116 -0
  61. package/dist/cjs/mixins/OxyServices.features.js +335 -0
  62. package/dist/cjs/mixins/OxyServices.followGraph.js +221 -0
  63. package/dist/cjs/mixins/OxyServices.identity.js +461 -0
  64. package/dist/cjs/mixins/OxyServices.identityBackup.js +172 -0
  65. package/dist/cjs/mixins/OxyServices.inference.js +59 -0
  66. package/dist/cjs/mixins/OxyServices.language.js +125 -0
  67. package/dist/cjs/mixins/OxyServices.links.js +72 -0
  68. package/dist/cjs/mixins/OxyServices.location.js +43 -0
  69. package/dist/cjs/mixins/OxyServices.nodes.js +175 -0
  70. package/dist/cjs/mixins/OxyServices.notifications.js +63 -0
  71. package/dist/cjs/mixins/OxyServices.payment.js +158 -0
  72. package/dist/cjs/mixins/OxyServices.privacy.js +199 -0
  73. package/dist/cjs/mixins/OxyServices.reputation.js +289 -0
  74. package/dist/cjs/mixins/OxyServices.security.js +89 -0
  75. package/dist/cjs/mixins/OxyServices.store.js +266 -0
  76. package/dist/cjs/mixins/OxyServices.topics.js +137 -0
  77. package/dist/cjs/mixins/OxyServices.user.js +902 -0
  78. package/dist/cjs/mixins/OxyServices.utility.js +1098 -0
  79. package/dist/cjs/mixins/index.js +135 -0
  80. package/dist/cjs/mixins/mixinHelpers.js +53 -0
  81. package/dist/cjs/models/Topic.js +16 -0
  82. package/dist/cjs/models/interfaces.js +20 -0
  83. package/dist/cjs/models/session.js +2 -0
  84. package/dist/cjs/server/auth.js +167 -0
  85. package/dist/cjs/server/capabilityTicket.js +192 -0
  86. package/dist/cjs/server/cors.js +225 -0
  87. package/dist/cjs/server/index.js +97 -0
  88. package/dist/cjs/server/rateLimit.js +207 -0
  89. package/dist/cjs/server/safeFetch.js +458 -0
  90. package/dist/cjs/server/securityHeaders.js +377 -0
  91. package/dist/cjs/server/userInvalidation.js +156 -0
  92. package/dist/cjs/server/verifySecret.js +50 -0
  93. package/dist/cjs/session/SessionClient.js +865 -0
  94. package/dist/cjs/session/accountDelegationAccess.js +48 -0
  95. package/dist/cjs/session/accountDialogController.js +1131 -0
  96. package/dist/cjs/session/accountSwitchTargets.js +81 -0
  97. package/dist/cjs/session/authStateStore.js +404 -0
  98. package/dist/cjs/session/createSessionClient.js +32 -0
  99. package/dist/cjs/session/deviceDirectory.js +143 -0
  100. package/dist/cjs/session/deviceSwitcherRows.js +76 -0
  101. package/dist/cjs/session/identityPin.js +256 -0
  102. package/dist/cjs/session/identitySession.js +135 -0
  103. package/dist/cjs/session/projectSessionState.js +121 -0
  104. package/dist/cjs/session/refresh.js +398 -0
  105. package/dist/cjs/session/sessionClientHost.js +34 -0
  106. package/dist/cjs/session/sharedDeviceCredential.js +247 -0
  107. package/dist/cjs/session/socketLoader.js +55 -0
  108. package/dist/cjs/shared/utils/colorUtils.js +153 -0
  109. package/dist/cjs/shared/utils/errorUtils.js +183 -0
  110. package/dist/cjs/shared/utils/index.js +49 -0
  111. package/dist/cjs/shared/utils/networkUtils.js +183 -0
  112. package/dist/cjs/shared/utils/themeUtils.js +106 -0
  113. package/dist/cjs/utils/accountCacheSweep.js +80 -0
  114. package/dist/cjs/utils/accountUtils.js +140 -0
  115. package/dist/cjs/utils/activityId.js +6 -0
  116. package/dist/cjs/utils/apiUtils.js +91 -0
  117. package/dist/cjs/utils/asyncUtils.js +222 -0
  118. package/dist/cjs/utils/authHelpers.js +120 -0
  119. package/dist/cjs/utils/authWebUrl.js +19 -0
  120. package/dist/cjs/utils/avatarUtils.js +29 -0
  121. package/dist/cjs/utils/cache.js +235 -0
  122. package/dist/cjs/utils/cacheKey.js +85 -0
  123. package/dist/cjs/utils/coldBoot.js +122 -0
  124. package/dist/cjs/utils/commonsApproval.js +31 -0
  125. package/dist/cjs/utils/commonsDelivery.js +59 -0
  126. package/dist/cjs/utils/deviceManager.js +174 -0
  127. package/dist/cjs/utils/displayNamePolicyRanges.generated.js +60 -0
  128. package/dist/cjs/utils/edgeRegion.js +6 -0
  129. package/dist/cjs/utils/errorUtils.js +243 -0
  130. package/dist/cjs/utils/identityCacheSweep.js +97 -0
  131. package/dist/cjs/utils/languageUtils.js +224 -0
  132. package/dist/cjs/utils/oauthPkce.js +311 -0
  133. package/dist/cjs/utils/officialOrigins.js +64 -0
  134. package/dist/cjs/utils/oxyServiceEnvironment.js +19 -0
  135. package/dist/cjs/utils/platform.js +119 -0
  136. package/dist/cjs/utils/profileLinks.js +63 -0
  137. package/dist/cjs/utils/redactUrl.js +29 -0
  138. package/dist/cjs/utils/registrableApex.js +45 -0
  139. package/dist/cjs/utils/requestUtils.js +209 -0
  140. package/dist/cjs/utils/sessionUtils.js +181 -0
  141. package/dist/cjs/utils/textNormalization.js +158 -0
  142. package/dist/cjs/utils/userHandle.js +37 -0
  143. package/dist/cjs/utils/userIdentity.js +50 -0
  144. package/dist/cjs/utils/validationUtils.js +370 -0
  145. package/dist/cjs/utils/webauthnOrigin.js +51 -0
  146. package/dist/esm/.tsbuildinfo +1 -0
  147. package/dist/esm/HttpService.js +1266 -0
  148. package/dist/esm/OxyServices.base.js +386 -0
  149. package/dist/esm/OxyServices.errors.js +88 -0
  150. package/dist/esm/OxyServices.js +66 -0
  151. package/dist/esm/boot/sessionColdBoot.js +392 -0
  152. package/dist/esm/constants/version.js +13 -0
  153. package/dist/esm/crypto/aead.js +74 -0
  154. package/dist/esm/crypto/ecdh.js +32 -0
  155. package/dist/esm/crypto/identityMarker.js +248 -0
  156. package/dist/esm/crypto/kdf.js +36 -0
  157. package/dist/esm/crypto/keyManager.js +2227 -0
  158. package/dist/esm/crypto/polyfill.js +129 -0
  159. package/dist/esm/crypto/recoveryPhrase.js +238 -0
  160. package/dist/esm/crypto/signatureService.js +269 -0
  161. package/dist/esm/i18n/accountCategoryLabels.js +37 -0
  162. package/dist/esm/i18n/accountRoleLabels.js +20 -0
  163. package/dist/esm/i18n/index.js +83 -0
  164. package/dist/esm/i18n/locales/ar-SA.json +282 -0
  165. package/dist/esm/i18n/locales/ca-ES.json +282 -0
  166. package/dist/esm/i18n/locales/de-DE.json +282 -0
  167. package/dist/esm/i18n/locales/en-US.json +2161 -0
  168. package/dist/esm/i18n/locales/es-ES.json +2161 -0
  169. package/dist/esm/i18n/locales/fr-FR.json +282 -0
  170. package/dist/esm/i18n/locales/it-IT.json +282 -0
  171. package/dist/esm/i18n/locales/ja-JP.json +282 -0
  172. package/dist/esm/i18n/locales/ko-KR.json +282 -0
  173. package/dist/esm/i18n/locales/locales/ar-SA.json +282 -0
  174. package/dist/esm/i18n/locales/locales/ca-ES.json +282 -0
  175. package/dist/esm/i18n/locales/locales/de-DE.json +282 -0
  176. package/dist/esm/i18n/locales/locales/en-US.json +2161 -0
  177. package/dist/esm/i18n/locales/locales/es-ES.json +2161 -0
  178. package/dist/esm/i18n/locales/locales/fr-FR.json +282 -0
  179. package/dist/esm/i18n/locales/locales/it-IT.json +282 -0
  180. package/dist/esm/i18n/locales/locales/ja-JP.json +282 -0
  181. package/dist/esm/i18n/locales/locales/ko-KR.json +282 -0
  182. package/dist/esm/i18n/locales/locales/pt-PT.json +282 -0
  183. package/dist/esm/i18n/locales/locales/zh-CN.json +282 -0
  184. package/dist/esm/i18n/locales/pt-PT.json +282 -0
  185. package/dist/esm/i18n/locales/zh-CN.json +282 -0
  186. package/dist/esm/i18n/reputationCategoryLabels.js +13 -0
  187. package/dist/esm/i18n/trustTierLabels.js +12 -0
  188. package/dist/esm/index.js +254 -0
  189. package/dist/esm/inference/OxyInferenceClient.js +538 -0
  190. package/dist/esm/logger/index.js +140 -0
  191. package/dist/esm/mixins/OxyServices.accounts.js +543 -0
  192. package/dist/esm/mixins/OxyServices.analytics.js +46 -0
  193. package/dist/esm/mixins/OxyServices.appData.js +103 -0
  194. package/dist/esm/mixins/OxyServices.assets.js +761 -0
  195. package/dist/esm/mixins/OxyServices.auth.js +1247 -0
  196. package/dist/esm/mixins/OxyServices.chains.js +70 -0
  197. package/dist/esm/mixins/OxyServices.civic.js +605 -0
  198. package/dist/esm/mixins/OxyServices.connectedApps.js +75 -0
  199. package/dist/esm/mixins/OxyServices.contacts.js +47 -0
  200. package/dist/esm/mixins/OxyServices.deviceBoot.js +186 -0
  201. package/dist/esm/mixins/OxyServices.deviceTransfer.js +311 -0
  202. package/dist/esm/mixins/OxyServices.devices.js +113 -0
  203. package/dist/esm/mixins/OxyServices.features.js +332 -0
  204. package/dist/esm/mixins/OxyServices.followGraph.js +218 -0
  205. package/dist/esm/mixins/OxyServices.identity.js +457 -0
  206. package/dist/esm/mixins/OxyServices.identityBackup.js +169 -0
  207. package/dist/esm/mixins/OxyServices.inference.js +56 -0
  208. package/dist/esm/mixins/OxyServices.language.js +122 -0
  209. package/dist/esm/mixins/OxyServices.links.js +69 -0
  210. package/dist/esm/mixins/OxyServices.location.js +40 -0
  211. package/dist/esm/mixins/OxyServices.nodes.js +172 -0
  212. package/dist/esm/mixins/OxyServices.notifications.js +60 -0
  213. package/dist/esm/mixins/OxyServices.payment.js +155 -0
  214. package/dist/esm/mixins/OxyServices.privacy.js +196 -0
  215. package/dist/esm/mixins/OxyServices.reputation.js +286 -0
  216. package/dist/esm/mixins/OxyServices.security.js +86 -0
  217. package/dist/esm/mixins/OxyServices.store.js +263 -0
  218. package/dist/esm/mixins/OxyServices.topics.js +134 -0
  219. package/dist/esm/mixins/OxyServices.user.js +899 -0
  220. package/dist/esm/mixins/OxyServices.utility.js +1095 -0
  221. package/dist/esm/mixins/index.js +132 -0
  222. package/dist/esm/mixins/mixinHelpers.js +48 -0
  223. package/dist/esm/models/Topic.js +13 -0
  224. package/dist/esm/models/interfaces.js +17 -0
  225. package/dist/esm/models/session.js +1 -0
  226. package/dist/esm/server/auth.js +154 -0
  227. package/dist/esm/server/capabilityTicket.js +183 -0
  228. package/dist/esm/server/cors.js +220 -0
  229. package/dist/esm/server/index.js +47 -0
  230. package/dist/esm/server/rateLimit.js +201 -0
  231. package/dist/esm/server/safeFetch.js +447 -0
  232. package/dist/esm/server/securityHeaders.js +364 -0
  233. package/dist/esm/server/userInvalidation.js +152 -0
  234. package/dist/esm/server/verifySecret.js +47 -0
  235. package/dist/esm/session/SessionClient.js +861 -0
  236. package/dist/esm/session/accountDelegationAccess.js +45 -0
  237. package/dist/esm/session/accountDialogController.js +1126 -0
  238. package/dist/esm/session/accountSwitchTargets.js +77 -0
  239. package/dist/esm/session/authStateStore.js +398 -0
  240. package/dist/esm/session/createSessionClient.js +29 -0
  241. package/dist/esm/session/deviceDirectory.js +135 -0
  242. package/dist/esm/session/deviceSwitcherRows.js +72 -0
  243. package/dist/esm/session/identityPin.js +249 -0
  244. package/dist/esm/session/identitySession.js +131 -0
  245. package/dist/esm/session/projectSessionState.js +114 -0
  246. package/dist/esm/session/refresh.js +390 -0
  247. package/dist/esm/session/sessionClientHost.js +31 -0
  248. package/dist/esm/session/sharedDeviceCredential.js +239 -0
  249. package/dist/esm/session/socketLoader.js +19 -0
  250. package/dist/esm/shared/utils/colorUtils.js +143 -0
  251. package/dist/esm/shared/utils/errorUtils.js +170 -0
  252. package/dist/esm/shared/utils/index.js +15 -0
  253. package/dist/esm/shared/utils/networkUtils.js +173 -0
  254. package/dist/esm/shared/utils/themeUtils.js +98 -0
  255. package/dist/esm/utils/accountCacheSweep.js +75 -0
  256. package/dist/esm/utils/accountUtils.js +131 -0
  257. package/dist/esm/utils/activityId.js +2 -0
  258. package/dist/esm/utils/apiUtils.js +84 -0
  259. package/dist/esm/utils/asyncUtils.js +207 -0
  260. package/dist/esm/utils/authHelpers.js +111 -0
  261. package/dist/esm/utils/authWebUrl.js +16 -0
  262. package/dist/esm/utils/avatarUtils.js +26 -0
  263. package/dist/esm/utils/cache.js +227 -0
  264. package/dist/esm/utils/cacheKey.js +80 -0
  265. package/dist/esm/utils/coldBoot.js +119 -0
  266. package/dist/esm/utils/commonsApproval.js +27 -0
  267. package/dist/esm/utils/commonsDelivery.js +54 -0
  268. package/dist/esm/utils/deviceManager.js +170 -0
  269. package/dist/esm/utils/displayNamePolicyRanges.generated.js +57 -0
  270. package/dist/esm/utils/edgeRegion.js +2 -0
  271. package/dist/esm/utils/errorUtils.js +232 -0
  272. package/dist/esm/utils/identityCacheSweep.js +92 -0
  273. package/dist/esm/utils/languageUtils.js +212 -0
  274. package/dist/esm/utils/oauthPkce.js +297 -0
  275. package/dist/esm/utils/officialOrigins.js +59 -0
  276. package/dist/esm/utils/oxyServiceEnvironment.js +16 -0
  277. package/dist/esm/utils/platform.js +110 -0
  278. package/dist/esm/utils/profileLinks.js +60 -0
  279. package/dist/esm/utils/redactUrl.js +26 -0
  280. package/dist/esm/utils/registrableApex.js +42 -0
  281. package/dist/esm/utils/requestUtils.js +203 -0
  282. package/dist/esm/utils/sessionUtils.js +171 -0
  283. package/dist/esm/utils/textNormalization.js +154 -0
  284. package/dist/esm/utils/userHandle.js +33 -0
  285. package/dist/esm/utils/userIdentity.js +45 -0
  286. package/dist/esm/utils/validationUtils.js +350 -0
  287. package/dist/esm/utils/webauthnOrigin.js +48 -0
  288. package/dist/types/.tsbuildinfo +1 -0
  289. package/dist/types/HttpService.d.ts +413 -0
  290. package/dist/types/OxyServices.base.d.ts +187 -0
  291. package/dist/types/OxyServices.d.ts +139 -0
  292. package/dist/types/OxyServices.errors.d.ts +84 -0
  293. package/dist/types/boot/sessionColdBoot.d.ts +140 -0
  294. package/dist/types/constants/version.d.ts +13 -0
  295. package/dist/types/crypto/aead.d.ts +56 -0
  296. package/dist/types/crypto/ecdh.d.ts +29 -0
  297. package/dist/types/crypto/identityMarker.d.ts +94 -0
  298. package/dist/types/crypto/kdf.d.ts +25 -0
  299. package/dist/types/crypto/keyManager.d.ts +582 -0
  300. package/dist/types/crypto/polyfill.d.ts +25 -0
  301. package/dist/types/crypto/recoveryPhrase.d.ts +173 -0
  302. package/dist/types/crypto/signatureService.d.ts +136 -0
  303. package/dist/types/i18n/accountCategoryLabels.d.ts +34 -0
  304. package/dist/types/i18n/accountRoleLabels.d.ts +10 -0
  305. package/dist/types/i18n/index.d.ts +3 -0
  306. package/dist/types/i18n/reputationCategoryLabels.d.ts +10 -0
  307. package/dist/types/i18n/trustTierLabels.d.ts +9 -0
  308. package/dist/types/index.d.ts +145 -0
  309. package/dist/types/inference/OxyInferenceClient.d.ts +342 -0
  310. package/dist/types/logger/index.d.ts +104 -0
  311. package/dist/types/mixins/OxyServices.accounts.d.ts +868 -0
  312. package/dist/types/mixins/OxyServices.analytics.d.ts +72 -0
  313. package/dist/types/mixins/OxyServices.appData.d.ts +108 -0
  314. package/dist/types/mixins/OxyServices.assets.d.ts +329 -0
  315. package/dist/types/mixins/OxyServices.auth.d.ts +908 -0
  316. package/dist/types/mixins/OxyServices.chains.d.ts +156 -0
  317. package/dist/types/mixins/OxyServices.civic.d.ts +510 -0
  318. package/dist/types/mixins/OxyServices.connectedApps.d.ts +169 -0
  319. package/dist/types/mixins/OxyServices.contacts.d.ts +100 -0
  320. package/dist/types/mixins/OxyServices.deviceBoot.d.ts +185 -0
  321. package/dist/types/mixins/OxyServices.deviceTransfer.d.ts +149 -0
  322. package/dist/types/mixins/OxyServices.devices.d.ts +103 -0
  323. package/dist/types/mixins/OxyServices.features.d.ts +250 -0
  324. package/dist/types/mixins/OxyServices.followGraph.d.ts +223 -0
  325. package/dist/types/mixins/OxyServices.identity.d.ts +351 -0
  326. package/dist/types/mixins/OxyServices.identityBackup.d.ts +129 -0
  327. package/dist/types/mixins/OxyServices.inference.d.ts +95 -0
  328. package/dist/types/mixins/OxyServices.language.d.ts +87 -0
  329. package/dist/types/mixins/OxyServices.links.d.ts +104 -0
  330. package/dist/types/mixins/OxyServices.location.d.ts +70 -0
  331. package/dist/types/mixins/OxyServices.nodes.d.ts +198 -0
  332. package/dist/types/mixins/OxyServices.notifications.d.ts +143 -0
  333. package/dist/types/mixins/OxyServices.payment.d.ts +117 -0
  334. package/dist/types/mixins/OxyServices.privacy.d.ts +146 -0
  335. package/dist/types/mixins/OxyServices.reputation.d.ts +202 -0
  336. package/dist/types/mixins/OxyServices.security.d.ts +84 -0
  337. package/dist/types/mixins/OxyServices.store.d.ts +334 -0
  338. package/dist/types/mixins/OxyServices.topics.d.ts +110 -0
  339. package/dist/types/mixins/OxyServices.user.d.ts +558 -0
  340. package/dist/types/mixins/OxyServices.utility.d.ts +393 -0
  341. package/dist/types/mixins/index.d.ts +87 -0
  342. package/dist/types/mixins/mixinHelpers.d.ts +31 -0
  343. package/dist/types/models/Topic.d.ts +42 -0
  344. package/dist/types/models/interfaces.d.ts +675 -0
  345. package/dist/types/models/session.d.ts +51 -0
  346. package/dist/types/server/auth.d.ts +130 -0
  347. package/dist/types/server/capabilityTicket.d.ts +41 -0
  348. package/dist/types/server/cors.d.ts +98 -0
  349. package/dist/types/server/index.d.ts +35 -0
  350. package/dist/types/server/rateLimit.d.ts +40 -0
  351. package/dist/types/server/safeFetch.d.ts +137 -0
  352. package/dist/types/server/securityHeaders.d.ts +221 -0
  353. package/dist/types/server/userInvalidation.d.ts +114 -0
  354. package/dist/types/server/verifySecret.d.ts +29 -0
  355. package/dist/types/session/SessionClient.d.ts +418 -0
  356. package/dist/types/session/accountDelegationAccess.d.ts +40 -0
  357. package/dist/types/session/accountDialogController.d.ts +648 -0
  358. package/dist/types/session/accountSwitchTargets.d.ts +70 -0
  359. package/dist/types/session/authStateStore.d.ts +153 -0
  360. package/dist/types/session/createSessionClient.d.ts +30 -0
  361. package/dist/types/session/deviceDirectory.d.ts +182 -0
  362. package/dist/types/session/deviceSwitcherRows.d.ts +92 -0
  363. package/dist/types/session/identityPin.d.ts +87 -0
  364. package/dist/types/session/identitySession.d.ts +105 -0
  365. package/dist/types/session/projectSessionState.d.ts +74 -0
  366. package/dist/types/session/refresh.d.ts +179 -0
  367. package/dist/types/session/sessionClientHost.d.ts +18 -0
  368. package/dist/types/session/sharedDeviceCredential.d.ts +202 -0
  369. package/dist/types/session/socketLoader.d.ts +11 -0
  370. package/dist/types/shared/utils/colorUtils.d.ts +104 -0
  371. package/dist/types/shared/utils/errorUtils.d.ts +97 -0
  372. package/dist/types/shared/utils/index.d.ts +13 -0
  373. package/dist/types/shared/utils/networkUtils.d.ts +139 -0
  374. package/dist/types/shared/utils/themeUtils.d.ts +90 -0
  375. package/dist/types/utils/accountCacheSweep.d.ts +75 -0
  376. package/dist/types/utils/accountUtils.d.ts +100 -0
  377. package/dist/types/utils/activityId.d.ts +2 -0
  378. package/dist/types/utils/apiUtils.d.ts +95 -0
  379. package/dist/types/utils/asyncUtils.d.ts +62 -0
  380. package/dist/types/utils/authHelpers.d.ts +58 -0
  381. package/dist/types/utils/authWebUrl.d.ts +16 -0
  382. package/dist/types/utils/avatarUtils.d.ts +16 -0
  383. package/dist/types/utils/cache.d.ts +130 -0
  384. package/dist/types/utils/cacheKey.d.ts +66 -0
  385. package/dist/types/utils/coldBoot.d.ts +131 -0
  386. package/dist/types/utils/commonsApproval.d.ts +13 -0
  387. package/dist/types/utils/commonsDelivery.d.ts +105 -0
  388. package/dist/types/utils/deviceManager.d.ts +65 -0
  389. package/dist/types/utils/displayNamePolicyRanges.generated.d.ts +57 -0
  390. package/dist/types/utils/edgeRegion.d.ts +2 -0
  391. package/dist/types/utils/errorUtils.d.ts +125 -0
  392. package/dist/types/utils/identityCacheSweep.d.ts +80 -0
  393. package/dist/types/utils/languageUtils.d.ts +100 -0
  394. package/dist/types/utils/oauthPkce.d.ts +157 -0
  395. package/dist/types/utils/officialOrigins.d.ts +13 -0
  396. package/dist/types/utils/oxyServiceEnvironment.d.ts +17 -0
  397. package/dist/types/utils/platform.d.ts +49 -0
  398. package/dist/types/utils/profileLinks.d.ts +44 -0
  399. package/dist/types/utils/redactUrl.d.ts +17 -0
  400. package/dist/types/utils/registrableApex.d.ts +27 -0
  401. package/dist/types/utils/requestUtils.d.ts +123 -0
  402. package/dist/types/utils/sessionUtils.d.ts +54 -0
  403. package/dist/types/utils/textNormalization.d.ts +103 -0
  404. package/dist/types/utils/userHandle.d.ts +26 -0
  405. package/dist/types/utils/userIdentity.d.ts +21 -0
  406. package/dist/types/utils/validationUtils.d.ts +268 -0
  407. package/dist/types/utils/webauthnOrigin.d.ts +32 -0
  408. package/package.json +168 -0
  409. package/src/HttpService.ts +1553 -0
  410. package/src/OxyServices.base.ts +478 -0
  411. package/src/OxyServices.errors.ts +122 -0
  412. package/src/OxyServices.ts +172 -0
  413. package/src/__tests__/authSocket.test.ts +96 -0
  414. package/src/__tests__/httpServiceActivityId.test.ts +49 -0
  415. package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
  416. package/src/__tests__/httpServiceCache.test.ts +318 -0
  417. package/src/__tests__/httpServiceCsrf.test.ts +235 -0
  418. package/src/__tests__/httpServiceFormEncoded.test.ts +142 -0
  419. package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
  420. package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +115 -0
  421. package/src/__tests__/inSessionRefresh.test.ts +260 -0
  422. package/src/__tests__/linkedClient.test.ts +370 -0
  423. package/src/__tests__/parseHttpErrorBody.test.ts +116 -0
  424. package/src/__tests__/serverValueImportsDeclared.test.ts +120 -0
  425. package/src/__tests__/userIdentity.test.ts +143 -0
  426. package/src/boot/__tests__/sessionColdBoot.identity.test.ts +393 -0
  427. package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +325 -0
  428. package/src/boot/__tests__/sessionColdBoot.test.ts +570 -0
  429. package/src/boot/sessionColdBoot.ts +529 -0
  430. package/src/constants/version.ts +15 -0
  431. package/src/crypto/__tests__/backupMaterial.test.ts +86 -0
  432. package/src/crypto/__tests__/cryptoPrimitives.test.ts +226 -0
  433. package/src/crypto/__tests__/identityMocks.ts +125 -0
  434. package/src/crypto/__tests__/keyManager.atomicity.test.ts +272 -0
  435. package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +175 -0
  436. package/src/crypto/__tests__/keyManager.identityStatus.test.ts +217 -0
  437. package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +179 -0
  438. package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +138 -0
  439. package/src/crypto/__tests__/keyManager.storageMigration.test.ts +227 -0
  440. package/src/crypto/__tests__/keyManager.test.ts +329 -0
  441. package/src/crypto/__tests__/polyfill.test.ts +109 -0
  442. package/src/crypto/__tests__/recoveryPhrase.test.ts +61 -0
  443. package/src/crypto/__tests__/scopedSeed.test.ts +126 -0
  444. package/src/crypto/__tests__/signChallengeShared.test.ts +63 -0
  445. package/src/crypto/__tests__/signedRecord.test.ts +230 -0
  446. package/src/crypto/aead.ts +97 -0
  447. package/src/crypto/ecdh.ts +37 -0
  448. package/src/crypto/identityMarker.ts +291 -0
  449. package/src/crypto/kdf.ts +43 -0
  450. package/src/crypto/keyManager.ts +2607 -0
  451. package/src/crypto/polyfill.ts +143 -0
  452. package/src/crypto/recoveryPhrase.ts +337 -0
  453. package/src/crypto/signatureService.ts +350 -0
  454. package/src/i18n/__tests__/accountCategoryLabels.test.ts +62 -0
  455. package/src/i18n/__tests__/accountRoleLabels.test.ts +54 -0
  456. package/src/i18n/__tests__/reputationCategoryLabels.test.ts +56 -0
  457. package/src/i18n/__tests__/trustTierLabels.test.ts +47 -0
  458. package/src/i18n/accountCategoryLabels.ts +44 -0
  459. package/src/i18n/accountRoleLabels.ts +26 -0
  460. package/src/i18n/index.ts +88 -0
  461. package/src/i18n/locales/ar-SA.json +282 -0
  462. package/src/i18n/locales/ca-ES.json +282 -0
  463. package/src/i18n/locales/de-DE.json +282 -0
  464. package/src/i18n/locales/en-US.json +2161 -0
  465. package/src/i18n/locales/es-ES.json +2161 -0
  466. package/src/i18n/locales/fr-FR.json +282 -0
  467. package/src/i18n/locales/it-IT.json +282 -0
  468. package/src/i18n/locales/ja-JP.json +282 -0
  469. package/src/i18n/locales/ko-KR.json +282 -0
  470. package/src/i18n/locales/pt-PT.json +282 -0
  471. package/src/i18n/locales/zh-CN.json +282 -0
  472. package/src/i18n/reputationCategoryLabels.ts +20 -0
  473. package/src/i18n/trustTierLabels.ts +18 -0
  474. package/src/index.ts +881 -0
  475. package/src/inference/OxyInferenceClient.ts +888 -0
  476. package/src/inference/__tests__/OxyInferenceClient.test.ts +834 -0
  477. package/src/logger/__tests__/logger.test.ts +207 -0
  478. package/src/logger/index.ts +217 -0
  479. package/src/mixins/OxyServices.accounts.ts +1330 -0
  480. package/src/mixins/OxyServices.analytics.ts +53 -0
  481. package/src/mixins/OxyServices.appData.ts +158 -0
  482. package/src/mixins/OxyServices.assets.ts +861 -0
  483. package/src/mixins/OxyServices.auth.ts +1858 -0
  484. package/src/mixins/OxyServices.chains.ts +134 -0
  485. package/src/mixins/OxyServices.civic.ts +945 -0
  486. package/src/mixins/OxyServices.connectedApps.ts +174 -0
  487. package/src/mixins/OxyServices.contacts.ts +73 -0
  488. package/src/mixins/OxyServices.deviceBoot.ts +210 -0
  489. package/src/mixins/OxyServices.deviceTransfer.ts +393 -0
  490. package/src/mixins/OxyServices.devices.ts +120 -0
  491. package/src/mixins/OxyServices.features.ts +454 -0
  492. package/src/mixins/OxyServices.followGraph.ts +293 -0
  493. package/src/mixins/OxyServices.identity.ts +705 -0
  494. package/src/mixins/OxyServices.identityBackup.ts +250 -0
  495. package/src/mixins/OxyServices.inference.ts +57 -0
  496. package/src/mixins/OxyServices.language.ts +144 -0
  497. package/src/mixins/OxyServices.links.ts +107 -0
  498. package/src/mixins/OxyServices.location.ts +46 -0
  499. package/src/mixins/OxyServices.nodes.ts +337 -0
  500. package/src/mixins/OxyServices.notifications.ts +142 -0
  501. package/src/mixins/OxyServices.payment.ts +163 -0
  502. package/src/mixins/OxyServices.privacy.ts +219 -0
  503. package/src/mixins/OxyServices.reputation.ts +436 -0
  504. package/src/mixins/OxyServices.security.ts +110 -0
  505. package/src/mixins/OxyServices.store.ts +585 -0
  506. package/src/mixins/OxyServices.topics.ts +169 -0
  507. package/src/mixins/OxyServices.user.ts +1137 -0
  508. package/src/mixins/OxyServices.utility.ts +1370 -0
  509. package/src/mixins/__tests__/OxyServices.civic.test.ts +1095 -0
  510. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +124 -0
  511. package/src/mixins/__tests__/OxyServices.deviceTransfer.test.ts +271 -0
  512. package/src/mixins/__tests__/OxyServices.identity.test.ts +376 -0
  513. package/src/mixins/__tests__/OxyServices.links.test.ts +154 -0
  514. package/src/mixins/__tests__/OxyServices.nodes.test.ts +341 -0
  515. package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +276 -0
  516. package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +192 -0
  517. package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +135 -0
  518. package/src/mixins/__tests__/accounts.test.ts +727 -0
  519. package/src/mixins/__tests__/appData.test.ts +203 -0
  520. package/src/mixins/__tests__/assetCredentials.test.ts +47 -0
  521. package/src/mixins/__tests__/assetUpload.test.ts +191 -0
  522. package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +135 -0
  523. package/src/mixins/__tests__/chains.test.ts +113 -0
  524. package/src/mixins/__tests__/commonsSignIn.test.ts +1144 -0
  525. package/src/mixins/__tests__/connectedApps.test.ts +123 -0
  526. package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +113 -0
  527. package/src/mixins/__tests__/discoveryErrorHandling.test.ts +266 -0
  528. package/src/mixins/__tests__/followCacheInvalidation.test.ts +173 -0
  529. package/src/mixins/__tests__/followGraph.test.ts +147 -0
  530. package/src/mixins/__tests__/followGraphPagination.test.ts +271 -0
  531. package/src/mixins/__tests__/getFileDownloadUrl.test.ts +346 -0
  532. package/src/mixins/__tests__/getFollowStatuses.test.ts +95 -0
  533. package/src/mixins/__tests__/getUsersByIds.test.ts +149 -0
  534. package/src/mixins/__tests__/identityBackup.test.ts +315 -0
  535. package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +407 -0
  536. package/src/mixins/__tests__/inferenceFactory.test.ts +58 -0
  537. package/src/mixins/__tests__/onTokensChanged.test.ts +129 -0
  538. package/src/mixins/__tests__/preSessionSkipAuth.test.ts +284 -0
  539. package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +155 -0
  540. package/src/mixins/__tests__/reputation.test.ts +522 -0
  541. package/src/mixins/__tests__/serviceAuth.test.ts +832 -0
  542. package/src/mixins/__tests__/serviceTokenJwks.test.ts +208 -0
  543. package/src/mixins/__tests__/store.test.ts +304 -0
  544. package/src/mixins/__tests__/topics.test.ts +156 -0
  545. package/src/mixins/__tests__/userReadCacheBypass.test.ts +129 -0
  546. package/src/mixins/__tests__/userTokenAuth.test.ts +746 -0
  547. package/src/mixins/__tests__/verifyChallenge.test.ts +130 -0
  548. package/src/mixins/__tests__/verifyServiceActingAs.test.ts +167 -0
  549. package/src/mixins/__tests__/webauthnAuth.test.ts +205 -0
  550. package/src/mixins/index.ts +201 -0
  551. package/src/mixins/mixinHelpers.ts +69 -0
  552. package/src/models/Topic.ts +46 -0
  553. package/src/models/interfaces.ts +786 -0
  554. package/src/models/session.ts +55 -0
  555. package/src/server/__tests__/auth.test.ts +78 -0
  556. package/src/server/__tests__/capabilityTicket.test.ts +111 -0
  557. package/src/server/__tests__/cors.socket.test.ts +225 -0
  558. package/src/server/__tests__/cors.test.ts +158 -0
  559. package/src/server/__tests__/rateLimit.test.ts +257 -0
  560. package/src/server/__tests__/safeFetch.test.ts +232 -0
  561. package/src/server/__tests__/securityHeaders.test.ts +348 -0
  562. package/src/server/__tests__/serviceTokenAttribution.test.ts +396 -0
  563. package/src/server/__tests__/userInvalidation.test.ts +203 -0
  564. package/src/server/__tests__/verifySecret.test.ts +40 -0
  565. package/src/server/auth.ts +271 -0
  566. package/src/server/capabilityTicket.ts +258 -0
  567. package/src/server/cors.ts +277 -0
  568. package/src/server/index.ts +136 -0
  569. package/src/server/rateLimit.ts +313 -0
  570. package/src/server/safeFetch.ts +586 -0
  571. package/src/server/securityHeaders.ts +467 -0
  572. package/src/server/userInvalidation.ts +199 -0
  573. package/src/server/verifySecret.ts +52 -0
  574. package/src/session/SessionClient.ts +1001 -0
  575. package/src/session/__tests__/SessionClient.additive.test.ts +153 -0
  576. package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +114 -0
  577. package/src/session/__tests__/SessionClient.diagnostics.test.ts +91 -0
  578. package/src/session/__tests__/SessionClient.directory.test.ts +688 -0
  579. package/src/session/__tests__/SessionClient.httpIntegration.test.ts +65 -0
  580. package/src/session/__tests__/SessionClient.identityPin.test.ts +175 -0
  581. package/src/session/__tests__/SessionClient.rest.test.ts +119 -0
  582. package/src/session/__tests__/SessionClient.serverEvents.test.ts +72 -0
  583. package/src/session/__tests__/SessionClient.socket.test.ts +202 -0
  584. package/src/session/__tests__/SessionClient.socketFactory.test.ts +81 -0
  585. package/src/session/__tests__/SessionClient.state.test.ts +78 -0
  586. package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +170 -0
  587. package/src/session/__tests__/accountDelegationAccess.test.ts +104 -0
  588. package/src/session/__tests__/accountDialogController.test.ts +1969 -0
  589. package/src/session/__tests__/accountDialogShape.test.ts +118 -0
  590. package/src/session/__tests__/accountSwitchTargets.test.ts +137 -0
  591. package/src/session/__tests__/authStateStore.test.ts +451 -0
  592. package/src/session/__tests__/deviceDirectory.test.ts +422 -0
  593. package/src/session/__tests__/deviceSwitcherRows.test.ts +223 -0
  594. package/src/session/__tests__/identityPin.test.ts +131 -0
  595. package/src/session/__tests__/identitySession.test.ts +194 -0
  596. package/src/session/__tests__/projectSessionState.test.ts +105 -0
  597. package/src/session/__tests__/refresh.identityPin.test.ts +307 -0
  598. package/src/session/__tests__/refresh.test.ts +443 -0
  599. package/src/session/__tests__/sessionIntegration.test.ts +209 -0
  600. package/src/session/__tests__/sharedDeviceCredential.test.ts +300 -0
  601. package/src/session/accountDelegationAccess.ts +72 -0
  602. package/src/session/accountDialogController.ts +1494 -0
  603. package/src/session/accountSwitchTargets.ts +93 -0
  604. package/src/session/authStateStore.ts +502 -0
  605. package/src/session/createSessionClient.ts +39 -0
  606. package/src/session/deviceDirectory.ts +269 -0
  607. package/src/session/deviceSwitcherRows.ts +145 -0
  608. package/src/session/identityPin.ts +310 -0
  609. package/src/session/identitySession.ts +206 -0
  610. package/src/session/projectSessionState.ts +137 -0
  611. package/src/session/refresh.ts +517 -0
  612. package/src/session/sessionClientHost.ts +39 -0
  613. package/src/session/sharedDeviceCredential.ts +349 -0
  614. package/src/session/socketLoader.ts +30 -0
  615. package/src/shared/utils/colorUtils.ts +155 -0
  616. package/src/shared/utils/errorUtils.ts +181 -0
  617. package/src/shared/utils/index.ts +59 -0
  618. package/src/shared/utils/networkUtils.ts +248 -0
  619. package/src/shared/utils/themeUtils.ts +115 -0
  620. package/src/types/buffer.d.ts +97 -0
  621. package/src/types/expo-crypto.d.ts +16 -0
  622. package/src/types/expo-secure-store.d.ts +17 -0
  623. package/src/utils/__tests__/accountUtils.test.ts +151 -0
  624. package/src/utils/__tests__/activityId.test.ts +45 -0
  625. package/src/utils/__tests__/asyncUtils.test.ts +187 -0
  626. package/src/utils/__tests__/authWebUrl.test.ts +15 -0
  627. package/src/utils/__tests__/cacheKey.test.ts +0 -0
  628. package/src/utils/__tests__/coldBoot.test.ts +496 -0
  629. package/src/utils/__tests__/commonsApproval.test.ts +60 -0
  630. package/src/utils/__tests__/identityCacheSweep.test.ts +151 -0
  631. package/src/utils/__tests__/languageUtils.test.ts +219 -0
  632. package/src/utils/__tests__/oauthPkce.test.ts +272 -0
  633. package/src/utils/__tests__/officialOrigins.test.ts +31 -0
  634. package/src/utils/__tests__/oxyServiceEnvironment.test.ts +7 -0
  635. package/src/utils/__tests__/profileLinks.test.ts +180 -0
  636. package/src/utils/__tests__/redactUrl.test.ts +33 -0
  637. package/src/utils/__tests__/registrableApex.test.ts +62 -0
  638. package/src/utils/__tests__/textNormalization.test.ts +205 -0
  639. package/src/utils/__tests__/validationUtils.test.ts +703 -0
  640. package/src/utils/__tests__/webauthnOrigin.test.ts +83 -0
  641. package/src/utils/accountCacheSweep.ts +93 -0
  642. package/src/utils/accountUtils.ts +194 -0
  643. package/src/utils/activityId.ts +2 -0
  644. package/src/utils/apiUtils.ts +137 -0
  645. package/src/utils/asyncUtils.ts +280 -0
  646. package/src/utils/authHelpers.ts +148 -0
  647. package/src/utils/authWebUrl.ts +17 -0
  648. package/src/utils/avatarUtils.ts +39 -0
  649. package/src/utils/cache.ts +273 -0
  650. package/src/utils/cacheKey.ts +93 -0
  651. package/src/utils/coldBoot.ts +218 -0
  652. package/src/utils/commonsApproval.ts +39 -0
  653. package/src/utils/commonsDelivery.ts +132 -0
  654. package/src/utils/deviceManager.ts +203 -0
  655. package/src/utils/displayNamePolicyRanges.generated.ts +69 -0
  656. package/src/utils/edgeRegion.ts +2 -0
  657. package/src/utils/errorUtils.ts +352 -0
  658. package/src/utils/identityCacheSweep.ts +104 -0
  659. package/src/utils/languageUtils.ts +256 -0
  660. package/src/utils/oauthPkce.ts +392 -0
  661. package/src/utils/officialOrigins.ts +62 -0
  662. package/src/utils/oxyServiceEnvironment.ts +17 -0
  663. package/src/utils/platform.ts +139 -0
  664. package/src/utils/profileLinks.ts +91 -0
  665. package/src/utils/redactUrl.ts +28 -0
  666. package/src/utils/registrableApex.ts +41 -0
  667. package/src/utils/requestUtils.ts +237 -0
  668. package/src/utils/sessionUtils.ts +206 -0
  669. package/src/utils/textNormalization.ts +162 -0
  670. package/src/utils/userHandle.ts +49 -0
  671. package/src/utils/userIdentity.ts +60 -0
  672. package/src/utils/validationUtils.ts +390 -0
  673. package/src/utils/webauthnOrigin.ts +52 -0
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Crypto Polyfills
3
+ *
4
+ * Ensures Buffer and crypto.getRandomValues are available
5
+ * across all platforms (Node.js, Browser, React Native).
6
+ *
7
+ * Guard order when installing a `getRandomValues` shim (see bottom of file and
8
+ * {@link cryptoPolyfill}):
9
+ *
10
+ * 1. A REAL `globalThis.crypto.getRandomValues` — used as-is (browser, Node
11
+ * >= 20, modern Hermes). The shim below is only installed when the host is
12
+ * missing it, so this branch is the install-time gate.
13
+ * 2. Node — backed by the built-in `node:crypto` module (`webcrypto`, else
14
+ * `randomFillSync`). This is what a Node runtime WITHOUT a global WebCrypto
15
+ * (Node 18 script entrypoints, some embedded hosts) falls back to.
16
+ * 3. React Native — `expo-crypto.getRandomBytes` (statically imported via the
17
+ * per-platform `platform/crypto` module in `@oxy.so/protocol`).
18
+ *
19
+ * Historically step (2) delegated to `@oxy.so/protocol`'s RN-only
20
+ * `getRandomBytesRN`, which THROWS on Node — so any Node host lacking a global
21
+ * WebCrypto crashed here instead of getting randomness. It is now a proper
22
+ * Node-backed implementation.
23
+ */
24
+ import _cjs_buffer from 'buffer';
25
+ const { Buffer } = _cjs_buffer;
26
+ import { getRandomBytesRN, isNodeJS } from '@oxy.so/protocol';
27
+ const getGlobalObject = () => {
28
+ if (typeof globalThis !== 'undefined')
29
+ return globalThis;
30
+ if (typeof global !== 'undefined')
31
+ return global;
32
+ if (typeof window !== 'undefined')
33
+ return window;
34
+ if (typeof self !== 'undefined')
35
+ return self;
36
+ return {};
37
+ };
38
+ const globalObject = getGlobalObject();
39
+ // Make Buffer available globally for libraries that depend on it
40
+ if (!globalObject.Buffer) {
41
+ globalObject.Buffer = Buffer;
42
+ }
43
+ /**
44
+ * Lazily-resolved `node:crypto` module, cached after the first attempt.
45
+ * `undefined` = not tried yet; `null` = tried and unavailable (non-Node host).
46
+ */
47
+ let cachedNodeCrypto;
48
+ /**
49
+ * Synchronously load `node:crypto` on a Node runtime, or `null` elsewhere.
50
+ *
51
+ * Uses a guarded, Node-only `require`. Every runtime that actually reaches this
52
+ * branch has a working CommonJS `require`: `@oxy.so/core` publishes no
53
+ * `"type": "module"`, so Node loads it as CommonJS and the `require` free
54
+ * variable is present. Browsers never reach here (they own `globalThis.crypto`,
55
+ * so this polyfill is never installed) and React Native takes the
56
+ * `getRandomBytesRN` branch — so the `node:crypto` reference is dead code in
57
+ * those bundles, and Expo's Metro resolver shims `node:*` builtins, keeping
58
+ * web/native bundles green.
59
+ */
60
+ function loadNodeCryptoSync() {
61
+ if (cachedNodeCrypto !== undefined) {
62
+ return cachedNodeCrypto;
63
+ }
64
+ if (typeof require !== 'function') {
65
+ cachedNodeCrypto = null;
66
+ return cachedNodeCrypto;
67
+ }
68
+ try {
69
+ cachedNodeCrypto = require('node:crypto');
70
+ }
71
+ catch {
72
+ // No Node crypto (unexpected on a real Node host) — degrade to the next
73
+ // mechanism rather than crash.
74
+ cachedNodeCrypto = null;
75
+ }
76
+ return cachedNodeCrypto;
77
+ }
78
+ /**
79
+ * Fill `array` with cryptographically-secure random bytes from `node:crypto`.
80
+ * Prefers `webcrypto.getRandomValues`; falls back to `randomFillSync`. Returns
81
+ * `false` when Node crypto is unavailable so the caller can try the next
82
+ * mechanism.
83
+ */
84
+ function fillFromNodeCrypto(array) {
85
+ const nodeCrypto = loadNodeCryptoSync();
86
+ if (!nodeCrypto) {
87
+ return false;
88
+ }
89
+ const webcrypto = nodeCrypto.webcrypto;
90
+ if (webcrypto && typeof webcrypto.getRandomValues === 'function') {
91
+ try {
92
+ webcrypto.getRandomValues(array);
93
+ return true;
94
+ }
95
+ catch {
96
+ // `webcrypto.getRandomValues` rejects non-integer views (Float*Array,
97
+ // DataView); fall through to `randomFillSync`, which accepts any view.
98
+ }
99
+ }
100
+ if (typeof nodeCrypto.randomFillSync === 'function') {
101
+ nodeCrypto.randomFillSync(array);
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+ const cryptoPolyfill = {
107
+ getRandomValues(array) {
108
+ // Node: back the CSPRNG with `node:crypto`. This is the path that matters on
109
+ // Node runtimes shipping WITHOUT a global WebCrypto — where delegating to
110
+ // the RN-only expo-crypto stub would throw.
111
+ if (isNodeJS() && fillFromNodeCrypto(array)) {
112
+ return array;
113
+ }
114
+ // React Native (and any non-Node host without WebCrypto): synchronous
115
+ // expo-crypto via @oxy.so/protocol's RN `platform/crypto` variant.
116
+ const bytes = getRandomBytesRN(array.byteLength);
117
+ const uint8View = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
118
+ uint8View.set(bytes);
119
+ return array;
120
+ },
121
+ };
122
+ // Only polyfill if crypto or crypto.getRandomValues is not available
123
+ if (typeof globalObject.crypto === 'undefined') {
124
+ globalObject.crypto = cryptoPolyfill;
125
+ }
126
+ else if (typeof globalObject.crypto.getRandomValues !== 'function') {
127
+ globalObject.crypto.getRandomValues = cryptoPolyfill.getRandomValues;
128
+ }
129
+ export { Buffer };
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Recovery Phrase Service - BIP39 Mnemonic Generation
3
+ *
4
+ * Handles generation and restoration of recovery phrases (mnemonic seeds)
5
+ * for backing up and restoring user identities.
6
+ *
7
+ * Note: This module requires the polyfill to be loaded first (done via crypto/index.ts)
8
+ *
9
+ * Oxy recovery phrases are English-only, so the English wordlist is imported by
10
+ * its own subpath. Never reach for a package that exposes its wordlists through
11
+ * a barrel: `bip39`'s `_wordlists` hard-requires all ten languages, which put
12
+ * ~265 KB of unreachable wordlists into the initial chunk of every consuming
13
+ * app. Adding another language means one more subpath import, ideally lazy.
14
+ */
15
+ import { generateMnemonic, mnemonicToSeed, validateMnemonic } from '@scure/bip39';
16
+ import { wordlist } from '@scure/bip39/wordlists/english';
17
+ import { KeyManager } from './keyManager.js';
18
+ import { hkdfSha256 } from './kdf.js';
19
+ /**
20
+ * Convert Uint8Array or array-like to hexadecimal string
21
+ * Works in both Node.js and React Native without depending on Buffer
22
+ */
23
+ function toHex(data) {
24
+ // Convert to array of numbers if needed
25
+ const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
26
+ return Array.from(bytes)
27
+ .map(b => b.toString(16).padStart(2, '0'))
28
+ .join('');
29
+ }
30
+ /** UTF-8 encode an ASCII label to bytes (for HKDF salt/info). */
31
+ function utf8(label) {
32
+ return new TextEncoder().encode(label);
33
+ }
34
+ /**
35
+ * HKDF context tag for the encrypted-backup key schedule (b3 Feature 1). Used as
36
+ * the HKDF `salt`; distinct from any other Oxy key-derivation salt so the backup
37
+ * key schedule is independent. Versioned so a future scheme change is a new tag.
38
+ */
39
+ export const BACKUP_KDF_SALT = 'oxy-identity-backup-v1';
40
+ /** HKDF `info` label that derives the symmetric AEAD key from the seed. */
41
+ export const BACKUP_KDF_ENCRYPTION_INFO = 'oxy-backup-encryption-key';
42
+ /** HKDF `info` label that derives the (server-hashed) backup locator from the seed. */
43
+ export const BACKUP_KDF_LOOKUP_INFO = 'oxy-backup-lookup-id';
44
+ /** Byte length of both the derived backup key and the derived lookup id (256-bit). */
45
+ export const BACKUP_MATERIAL_LENGTH = 32;
46
+ export class RecoveryPhraseService {
47
+ /**
48
+ * Generate a new identity with a recovery phrase.
49
+ * The mnemonic phrase MUST be shown to the user exactly once after this
50
+ * call resolves — if it is lost, the account becomes unrecoverable.
51
+ *
52
+ * Refuses to overwrite an existing identity unless `options.overwrite === true`.
53
+ *
54
+ * @throws IdentityAlreadyExistsError if an identity already exists and overwrite is not set
55
+ */
56
+ static async generateIdentityWithRecovery(options) {
57
+ // Generate 128-bit entropy for 12-word mnemonic
58
+ const mnemonic = generateMnemonic(wordlist, 128);
59
+ // Derive private key from mnemonic
60
+ // Using the seed directly as the private key (simplified approach)
61
+ const seed = await mnemonicToSeed(mnemonic);
62
+ // Use first 32 bytes of seed as private key
63
+ const privateKeyHex = toHex(seed.subarray(0, 32));
64
+ // Import the derived key pair. KeyManager.importKeyPair will refuse to
65
+ // clobber an existing identity unless overwrite is explicitly requested.
66
+ const publicKey = await KeyManager.importKeyPair(privateKeyHex, {
67
+ overwrite: options?.overwrite === true,
68
+ });
69
+ return {
70
+ phrase: mnemonic,
71
+ words: mnemonic.split(' '),
72
+ publicKey,
73
+ };
74
+ }
75
+ /**
76
+ * Generate a 24-word recovery phrase for higher security.
77
+ *
78
+ * Same overwrite-protection semantics as `generateIdentityWithRecovery`.
79
+ */
80
+ static async generateIdentityWithRecovery24(options) {
81
+ // Generate 256-bit entropy for 24-word mnemonic
82
+ const mnemonic = generateMnemonic(wordlist, 256);
83
+ const seed = await mnemonicToSeed(mnemonic);
84
+ const privateKeyHex = toHex(seed.subarray(0, 32));
85
+ const publicKey = await KeyManager.importKeyPair(privateKeyHex, {
86
+ overwrite: options?.overwrite === true,
87
+ });
88
+ return {
89
+ phrase: mnemonic,
90
+ words: mnemonic.split(' '),
91
+ publicKey,
92
+ };
93
+ }
94
+ /**
95
+ * Derive a brand-new identity + recovery phrase WITHOUT persisting anything.
96
+ *
97
+ * Pure: same derivation as {@link generateIdentityWithRecovery} (128-bit
98
+ * mnemonic → seed → first 32 bytes as the secp256k1 private key) but it stops
99
+ * BEFORE `KeyManager.importKeyPair`, so no on-device identity is touched. The
100
+ * caller decides if/when to commit the material (e.g. only after a server
101
+ * confirms a key rotation). Works on web too — it never reads or writes secure
102
+ * storage.
103
+ *
104
+ * The 12-word `phrase` MUST be shown to the user before the identity is
105
+ * committed anywhere — if it is lost the account becomes unrecoverable.
106
+ */
107
+ static async derivePendingIdentity() {
108
+ const mnemonic = generateMnemonic(wordlist, 128);
109
+ const seed = await mnemonicToSeed(mnemonic);
110
+ const privateKey = toHex(seed.subarray(0, 32));
111
+ const publicKey = KeyManager.derivePublicKey(privateKey);
112
+ return {
113
+ phrase: mnemonic,
114
+ words: mnemonic.split(' '),
115
+ privateKey,
116
+ publicKey,
117
+ };
118
+ }
119
+ /**
120
+ * Derive the private key from a recovery phrase WITHOUT storing it.
121
+ *
122
+ * The private-key counterpart of {@link derivePublicKeyFromPhrase}. Used to
123
+ * re-derive a key in memory (e.g. to sign a rotation proof with the current
124
+ * key when the device has no SecureStore copy). Never persists — the returned
125
+ * material lives only in the caller's memory.
126
+ */
127
+ static async derivePrivateKeyFromPhrase(phrase) {
128
+ const normalizedPhrase = phrase.trim().toLowerCase();
129
+ if (!validateMnemonic(normalizedPhrase, wordlist)) {
130
+ throw new Error('Invalid recovery phrase');
131
+ }
132
+ const seed = await mnemonicToSeed(normalizedPhrase);
133
+ return toHex(seed.subarray(0, 32));
134
+ }
135
+ /**
136
+ * Derive the encrypted-backup key material from a recovery phrase (b3 Feature
137
+ * 1). PURE and additive — it does NOT touch the frozen phrase→privateKey
138
+ * derivation ({@link derivePrivateKeyFromPhrase} slices the first 32 seed
139
+ * bytes) and never reads or writes secure storage.
140
+ *
141
+ * Both outputs are derived from the FULL 64-byte BIP-39 seed via HKDF-SHA256
142
+ * with domain-separated `info` labels, so the domain separation is real: a
143
+ * device compromise that leaks only the raw 32-byte private key can compute
144
+ * NEITHER the backup key nor the lookup id (both need the whole seed). Locating
145
+ * AND decrypting a backup therefore requires the recovery phrase.
146
+ *
147
+ * @param phrase - The BIP-39 recovery phrase (validated + normalized here).
148
+ * @returns `{ backupKey, lookupId }` — the AEAD key (kept local) and the hex
149
+ * locator (uploaded; server stores only its hash).
150
+ * @throws if the phrase is not a valid BIP-39 mnemonic.
151
+ */
152
+ static async deriveBackupMaterial(phrase) {
153
+ const normalizedPhrase = phrase.trim().toLowerCase();
154
+ if (!validateMnemonic(normalizedPhrase, wordlist)) {
155
+ throw new Error('Invalid recovery phrase. Please check the words and try again.');
156
+ }
157
+ const seed = await mnemonicToSeed(normalizedPhrase);
158
+ const salt = utf8(BACKUP_KDF_SALT);
159
+ const backupKey = hkdfSha256(seed, salt, utf8(BACKUP_KDF_ENCRYPTION_INFO), BACKUP_MATERIAL_LENGTH);
160
+ const lookupId = toHex(hkdfSha256(seed, salt, utf8(BACKUP_KDF_LOOKUP_INFO), BACKUP_MATERIAL_LENGTH));
161
+ return { backupKey, lookupId };
162
+ }
163
+ /**
164
+ * Restore an identity from a recovery phrase.
165
+ *
166
+ * Refuses to overwrite a DIFFERENT existing identity unless
167
+ * `options.overwrite === true`. Re-importing the same phrase that
168
+ * matches the current identity is always allowed (it's a no-op refresh
169
+ * of the backup record).
170
+ */
171
+ static async restoreFromPhrase(phrase, options) {
172
+ // Normalize and validate the phrase
173
+ const normalizedPhrase = phrase.trim().toLowerCase();
174
+ if (!validateMnemonic(normalizedPhrase, wordlist)) {
175
+ throw new Error('Invalid recovery phrase. Please check the words and try again.');
176
+ }
177
+ // Derive the same private key from the mnemonic
178
+ const seed = await mnemonicToSeed(normalizedPhrase);
179
+ const privateKeyHex = toHex(seed.subarray(0, 32));
180
+ // Import and store the key pair
181
+ const publicKey = await KeyManager.importKeyPair(privateKeyHex, {
182
+ overwrite: options?.overwrite === true,
183
+ });
184
+ return publicKey;
185
+ }
186
+ /**
187
+ * Validate a recovery phrase without importing it
188
+ */
189
+ static validatePhrase(phrase) {
190
+ const normalizedPhrase = phrase.trim().toLowerCase();
191
+ return validateMnemonic(normalizedPhrase, wordlist);
192
+ }
193
+ /**
194
+ * Get the word list for autocomplete/validation
195
+ */
196
+ static getWordList() {
197
+ return wordlist;
198
+ }
199
+ /**
200
+ * Check if a word is valid in the BIP39 word list
201
+ */
202
+ static isValidWord(word) {
203
+ return wordlist.includes(word.toLowerCase());
204
+ }
205
+ /**
206
+ * Get suggestions for a partial word
207
+ */
208
+ static getSuggestions(partial, limit = 5) {
209
+ const lowerPartial = partial.toLowerCase();
210
+ return wordlist.filter((word) => word.startsWith(lowerPartial)).slice(0, limit);
211
+ }
212
+ /**
213
+ * Derive the public key from a phrase without storing
214
+ * Useful for verification before importing
215
+ */
216
+ static async derivePublicKeyFromPhrase(phrase) {
217
+ const normalizedPhrase = phrase.trim().toLowerCase();
218
+ if (!validateMnemonic(normalizedPhrase, wordlist)) {
219
+ throw new Error('Invalid recovery phrase');
220
+ }
221
+ const seed = await mnemonicToSeed(normalizedPhrase);
222
+ const privateKeyHex = toHex(seed.subarray(0, 32));
223
+ return KeyManager.derivePublicKey(privateKeyHex);
224
+ }
225
+ /**
226
+ * Convert a phrase to its word array
227
+ */
228
+ static phraseToWords(phrase) {
229
+ return phrase.trim().toLowerCase().split(/\s+/);
230
+ }
231
+ /**
232
+ * Convert a word array to a phrase string
233
+ */
234
+ static wordsToPhrase(words) {
235
+ return words.map(w => w.toLowerCase().trim()).join(' ');
236
+ }
237
+ }
238
+ export default RecoveryPhraseService;
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Signature Service - ECDSA Digital Signatures (device-key bound)
3
+ *
4
+ * Handles signing and verification of messages with the user's DEVICE identity
5
+ * key (read from {@link KeyManager} / secure storage). All cryptography itself —
6
+ * canonical signing input, SHA-256, secp256k1 sign/verify, envelope assembly —
7
+ * is delegated to `@oxy.so/protocol`; this service only resolves the key from
8
+ * storage and orchestrates the protocol primitives.
9
+ */
10
+ import { signEnvelope, signMessage, verifySignature, sha256, loadExpoCrypto, loadNodeCrypto, isReactNative, isNodeJS, } from '@oxy.so/protocol';
11
+ import { KeyManager } from './keyManager.js';
12
+ import { logger } from '../logger/index.js';
13
+ export class SignatureService {
14
+ /**
15
+ * Generate a random challenge string (for offline use)
16
+ * Uses expo-crypto in React Native, crypto.randomBytes in Node.js
17
+ */
18
+ static async generateChallenge() {
19
+ // In React Native, use expo-crypto
20
+ if (isReactNative()) {
21
+ const Crypto = await loadExpoCrypto();
22
+ const randomBytes = await Crypto.getRandomBytesAsync(32);
23
+ return Array.from(new Uint8Array(randomBytes))
24
+ .map((b) => b.toString(16).padStart(2, '0'))
25
+ .join('');
26
+ }
27
+ if (isNodeJS()) {
28
+ try {
29
+ const nodeCrypto = await loadNodeCrypto();
30
+ return nodeCrypto.randomBytes(32).toString('hex');
31
+ }
32
+ catch (error) {
33
+ // Node crypto failed to load — log and fall through to Web Crypto API
34
+ logger.warn('[oxy.crypto] Node crypto unavailable, falling back to Web Crypto', { component: 'SignatureService' }, error);
35
+ }
36
+ }
37
+ // Browser: use Web Crypto API
38
+ const bytes = new Uint8Array(32);
39
+ globalThis.crypto.getRandomValues(bytes);
40
+ return Array.from(bytes)
41
+ .map(b => b.toString(16).padStart(2, '0'))
42
+ .join('');
43
+ }
44
+ /**
45
+ * Hash a message using SHA-256
46
+ */
47
+ static async hashMessage(message) {
48
+ return sha256(message);
49
+ }
50
+ /**
51
+ * Sign a message using the stored device private key
52
+ * Returns the signature in DER format (hex encoded)
53
+ */
54
+ static async sign(message) {
55
+ const privateKey = await KeyManager.getPrivateKey();
56
+ if (!privateKey) {
57
+ throw new Error('No identity found. Please create or import an identity first.');
58
+ }
59
+ return signMessage(message, privateKey);
60
+ }
61
+ /**
62
+ * Create a signed message object with metadata
63
+ */
64
+ static async createSignedMessage(message) {
65
+ const publicKey = await KeyManager.getPublicKey();
66
+ if (!publicKey) {
67
+ throw new Error('No identity found. Please create or import an identity first.');
68
+ }
69
+ const timestamp = Date.now();
70
+ const messageWithTimestamp = `${message}:${timestamp}`;
71
+ const signature = await SignatureService.sign(messageWithTimestamp);
72
+ return {
73
+ message,
74
+ signature,
75
+ publicKey,
76
+ timestamp,
77
+ };
78
+ }
79
+ /**
80
+ * Verify a signed message object
81
+ * Checks both signature validity and timestamp freshness
82
+ */
83
+ static async verifySignedMessage(signedMessage, maxAgeMs = 5 * 60 * 1000 // 5 minutes default
84
+ ) {
85
+ const { message, signature, publicKey, timestamp } = signedMessage;
86
+ // Check timestamp freshness
87
+ const now = Date.now();
88
+ if (now - timestamp > maxAgeMs) {
89
+ return false;
90
+ }
91
+ // Verify signature
92
+ const messageWithTimestamp = `${message}:${timestamp}`;
93
+ return verifySignature(messageWithTimestamp, signature, publicKey);
94
+ }
95
+ /**
96
+ * Create a signed authentication challenge response
97
+ * Used for challenge-response authentication
98
+ */
99
+ static async signChallenge(challenge) {
100
+ const publicKey = await KeyManager.getPublicKey();
101
+ if (!publicKey) {
102
+ throw new Error('No identity found. Please create or import an identity first.');
103
+ }
104
+ const timestamp = Date.now();
105
+ const message = `auth:${publicKey}:${challenge}:${timestamp}`;
106
+ const signature = await SignatureService.sign(message);
107
+ return {
108
+ challenge: signature,
109
+ publicKey,
110
+ timestamp,
111
+ };
112
+ }
113
+ /**
114
+ * Create a signed authentication challenge response using the SHARED identity
115
+ * key (the cross-app `group.so.oxy.shared` keychain key), not the primary
116
+ * device key.
117
+ *
118
+ * Mirrors {@link signChallenge} exactly — same message format
119
+ * (`auth:${publicKey}:${challenge}:${timestamp}`) so the server verification
120
+ * path is unchanged — but sources the shared public/private key from
121
+ * `KeyManager` and signs with the protocol's explicit-key {@link signMessage}.
122
+ * Used by "Sign in with Oxy" same-device shared-keychain SSO (Mechanism A): a
123
+ * sibling native app proves control of the shared identity to mint its own
124
+ * session.
125
+ *
126
+ * Throws if no shared identity exists (native-only; the shared keychain is
127
+ * unavailable on web).
128
+ */
129
+ static async signChallengeWithSharedKey(challenge) {
130
+ const publicKey = await KeyManager.getSharedPublicKey();
131
+ const privateKey = await KeyManager.getSharedPrivateKey();
132
+ if (!publicKey || !privateKey) {
133
+ throw new Error('No shared identity found. Cannot sign with the shared key.');
134
+ }
135
+ const timestamp = Date.now();
136
+ const message = `auth:${publicKey}:${challenge}:${timestamp}`;
137
+ const signature = await signMessage(message, privateKey);
138
+ return {
139
+ challenge: signature,
140
+ publicKey,
141
+ timestamp,
142
+ };
143
+ }
144
+ /**
145
+ * Verify a challenge response
146
+ */
147
+ static async verifyChallengeResponse(originalChallenge, response, maxAgeMs = 5 * 60 * 1000) {
148
+ const { challenge: signature, publicKey, timestamp } = response;
149
+ // Check timestamp freshness
150
+ const now = Date.now();
151
+ if (now - timestamp > maxAgeMs) {
152
+ return false;
153
+ }
154
+ const message = `auth:${publicKey}:${originalChallenge}:${timestamp}`;
155
+ return verifySignature(message, signature, publicKey);
156
+ }
157
+ /**
158
+ * Create a registration signature
159
+ * Used when registering a new identity with the server
160
+ * Format matches server expectation: oxy:register:{publicKey}:{timestamp}
161
+ */
162
+ static async createRegistrationSignature() {
163
+ const publicKey = await KeyManager.getPublicKey();
164
+ if (!publicKey) {
165
+ throw new Error('No identity found. Please create or import an identity first.');
166
+ }
167
+ const timestamp = Date.now();
168
+ const message = `oxy:register:${publicKey}:${timestamp}`;
169
+ const signature = await SignatureService.sign(message);
170
+ return {
171
+ signature,
172
+ publicKey,
173
+ timestamp,
174
+ };
175
+ }
176
+ /**
177
+ * Sign arbitrary data for API requests
178
+ * Creates a canonical string representation and signs it
179
+ */
180
+ static async signRequestData(data) {
181
+ const publicKey = await KeyManager.getPublicKey();
182
+ if (!publicKey) {
183
+ throw new Error('No identity found. Please create or import an identity first.');
184
+ }
185
+ const timestamp = Date.now();
186
+ // Create canonical string representation
187
+ const sortedKeys = Object.keys(data).sort();
188
+ const canonicalParts = sortedKeys.map(key => `${key}:${JSON.stringify(data[key])}`);
189
+ const canonicalString = canonicalParts.join('|');
190
+ const message = `request:${publicKey}:${timestamp}:${canonicalString}`;
191
+ const signature = await SignatureService.sign(message);
192
+ return {
193
+ signature,
194
+ publicKey,
195
+ timestamp,
196
+ };
197
+ }
198
+ /**
199
+ * Build a signed-record envelope for a self-issued identity/profile record.
200
+ *
201
+ * The envelope is self-issued: `issuer` equals `subject` (the signer's DID).
202
+ * The signature covers the canonical JSON of every field EXCEPT `publicKey`
203
+ * and `signature`; `alg` is `ES256K-DER-SHA256` (secp256k1 over the SHA-256 of
204
+ * the canonical bytes, DER-encoded). The cryptography is delegated to the
205
+ * protocol's {@link signEnvelope}, which derives the (uncompressed-hex)
206
+ * `publicKey` from the stored device key — identical to the registered
207
+ * verification method.
208
+ *
209
+ * Requires a stored identity (native secure storage); throws if none exists.
210
+ *
211
+ * @param type - The record category (`'identity'` or `'profile'`).
212
+ * @param subject - The subject DID the record is about (also the issuer).
213
+ * @param record - The arbitrary record payload to attest to.
214
+ */
215
+ static async signRecord(type, subject, record) {
216
+ const privateKey = await KeyManager.getPrivateKey();
217
+ if (!privateKey) {
218
+ throw new Error('No identity found. Please create or import an identity first.');
219
+ }
220
+ return signEnvelope({
221
+ version: 1,
222
+ type,
223
+ subject,
224
+ issuer: subject,
225
+ record,
226
+ issuedAt: Date.now(),
227
+ }, privateKey);
228
+ }
229
+ /**
230
+ * Build a signed-record envelope (v2) carrying the per-subject hash-chain
231
+ * fields.
232
+ *
233
+ * Identical to {@link signRecord} (self-issued: `issuer === subject`; same
234
+ * `ES256K-DER-SHA256` scheme) but `version` is `2` and the signed bytes
235
+ * additionally cover the chain fields:
236
+ *
237
+ * @param type - The record category.
238
+ * @param subject - The subject DID the record is about (also the issuer).
239
+ * @param record - The arbitrary record payload to attest to.
240
+ * @param chain - The hash-chain coordinates:
241
+ * - `seq` — strictly-increasing sequence number for this subject's chain.
242
+ * - `prev` — the `recordId` of the previous record, or `null` at genesis.
243
+ * - `collection` + `rkey` — the AtProto-style record key.
244
+ *
245
+ * The caller is responsible for fetching the current chain head (so `seq` /
246
+ * `prev` are correct) before signing. Requires a stored identity; throws if
247
+ * none exists.
248
+ */
249
+ static async signRecordV2(type, subject, record, chain) {
250
+ const privateKey = await KeyManager.getPrivateKey();
251
+ if (!privateKey) {
252
+ throw new Error('No identity found. Please create or import an identity first.');
253
+ }
254
+ const { seq, prev, collection, rkey } = chain;
255
+ return signEnvelope({
256
+ version: 2,
257
+ type,
258
+ subject,
259
+ issuer: subject,
260
+ record,
261
+ issuedAt: Date.now(),
262
+ seq,
263
+ prev,
264
+ collection,
265
+ rkey,
266
+ }, privateKey);
267
+ }
268
+ }
269
+ export default SignatureService;
@@ -0,0 +1,37 @@
1
+ import enUS from './locales/en-US.json' with { type: "json" };
2
+ import { translate } from './index.js';
3
+ /**
4
+ * Every account category's English name, keyed by its stable id.
5
+ *
6
+ * **The annotation is the point.** The vocabulary lives in `@oxy.so/contracts`
7
+ * and the names live in `locales/en-US.json`, so they are two lists that must
8
+ * agree and nothing but a type can make them. Declaring the JSON node as a
9
+ * TOTAL `Record<AccountCategoryId, string>` turns "somebody added a category at
10
+ * Oxy and nobody wrote its English" into a `TS2741` naming the missing id, at
11
+ * build time, instead of a picker row that paints `accounts.accountCategory.<id>`
12
+ * at a user trying to choose one.
13
+ *
14
+ * That failure is not hypothetical. The screen previously wrote `t(key) || id`,
15
+ * whose author believed an unnamed id would degrade to its raw slug. It cannot:
16
+ * {@link translate} echoes the KEY when it resolves nothing, and a non-empty
17
+ * string is never falsy, so the `|| id` arm was unreachable and the output was
18
+ * the dotted key. A runtime fallback that cannot run is worse than none,
19
+ * because it reads as protection.
20
+ *
21
+ * Totality is over `ACCOUNT_CATEGORY_IDS`, which RETAINS withdrawn ids, so an
22
+ * account still carrying a retired category keeps rendering its name while no
23
+ * picker offers it again. Retired and unknown are different cases: only an id
24
+ * outside the union is unnameable, which is why this is keyed by
25
+ * `AccountCategoryId` and not by `string`.
26
+ */
27
+ /**
28
+ * Module-scoped, NOT re-exported from the package index: the annotation is the
29
+ * whole job, and it does that job without being public API. It carries no
30
+ * `Object.freeze` and no `Readonly<>` for the same reason — those existed only
31
+ * to make an exported reference safe from a consumer's stray write, and there
32
+ * is no such consumer. Exported from the MODULE so its own test can name it.
33
+ */
34
+ export const EN_ACCOUNT_CATEGORY_LABELS = enUS.accounts.accountCategory;
35
+ export function accountCategoryLabel(locale, id) {
36
+ return translate(locale, `accounts.accountCategory.${id}`);
37
+ }