@oxyhq/core 1.11.12 → 1.11.14

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 (130) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/CrossDomainAuth.js +3 -1
  3. package/dist/cjs/HttpService.js +214 -33
  4. package/dist/cjs/OxyServices.base.js +9 -0
  5. package/dist/cjs/OxyServices.js +8 -3
  6. package/dist/cjs/crypto/index.js +3 -1
  7. package/dist/cjs/crypto/keyManager.js +476 -172
  8. package/dist/cjs/crypto/polyfill.js +14 -65
  9. package/dist/cjs/crypto/recoveryPhrase.js +30 -11
  10. package/dist/cjs/crypto/signatureService.js +25 -60
  11. package/dist/cjs/i18n/locales/en-US.json +46 -1
  12. package/dist/cjs/i18n/locales/es-ES.json +46 -1
  13. package/dist/cjs/i18n/locales/locales/en-US.json +46 -1
  14. package/dist/cjs/i18n/locales/locales/es-ES.json +46 -1
  15. package/dist/cjs/index.js +10 -2
  16. package/dist/cjs/mixins/OxyServices.assets.js +9 -4
  17. package/dist/cjs/mixins/OxyServices.auth.js +147 -14
  18. package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
  19. package/dist/cjs/mixins/OxyServices.features.js +0 -11
  20. package/dist/cjs/mixins/OxyServices.fedcm.js +4 -3
  21. package/dist/cjs/mixins/OxyServices.language.js +5 -36
  22. package/dist/cjs/mixins/OxyServices.redirect.js +6 -2
  23. package/dist/cjs/mixins/OxyServices.security.js +13 -2
  24. package/dist/cjs/mixins/OxyServices.user.js +59 -38
  25. package/dist/cjs/mixins/OxyServices.utility.js +416 -110
  26. package/dist/cjs/mixins/index.js +11 -3
  27. package/dist/cjs/utils/accountUtils.js +71 -2
  28. package/dist/cjs/utils/deviceManager.js +5 -36
  29. package/dist/cjs/utils/languageUtils.js +22 -0
  30. package/dist/cjs/utils/platformCrypto.js +165 -0
  31. package/dist/cjs/utils/platformCrypto.native.js +123 -0
  32. package/dist/esm/.tsbuildinfo +1 -1
  33. package/dist/esm/CrossDomainAuth.js +3 -1
  34. package/dist/esm/HttpService.js +215 -34
  35. package/dist/esm/OxyServices.base.js +9 -0
  36. package/dist/esm/OxyServices.js +8 -3
  37. package/dist/esm/crypto/index.js +1 -1
  38. package/dist/esm/crypto/keyManager.js +473 -138
  39. package/dist/esm/crypto/polyfill.js +14 -32
  40. package/dist/esm/crypto/recoveryPhrase.js +30 -11
  41. package/dist/esm/crypto/signatureService.js +25 -27
  42. package/dist/esm/i18n/locales/en-US.json +46 -1
  43. package/dist/esm/i18n/locales/es-ES.json +46 -1
  44. package/dist/esm/i18n/locales/locales/en-US.json +46 -1
  45. package/dist/esm/i18n/locales/locales/es-ES.json +46 -1
  46. package/dist/esm/index.js +4 -3
  47. package/dist/esm/mixins/OxyServices.assets.js +9 -4
  48. package/dist/esm/mixins/OxyServices.auth.js +145 -14
  49. package/dist/esm/mixins/OxyServices.contacts.js +47 -0
  50. package/dist/esm/mixins/OxyServices.features.js +0 -11
  51. package/dist/esm/mixins/OxyServices.fedcm.js +4 -3
  52. package/dist/esm/mixins/OxyServices.language.js +5 -3
  53. package/dist/esm/mixins/OxyServices.redirect.js +6 -2
  54. package/dist/esm/mixins/OxyServices.security.js +13 -2
  55. package/dist/esm/mixins/OxyServices.user.js +59 -38
  56. package/dist/esm/mixins/OxyServices.utility.js +416 -77
  57. package/dist/esm/mixins/index.js +11 -3
  58. package/dist/esm/utils/accountUtils.js +67 -1
  59. package/dist/esm/utils/deviceManager.js +5 -3
  60. package/dist/esm/utils/languageUtils.js +21 -0
  61. package/dist/esm/utils/platformCrypto.js +125 -0
  62. package/dist/esm/utils/platformCrypto.native.js +80 -0
  63. package/dist/types/.tsbuildinfo +1 -1
  64. package/dist/types/HttpService.d.ts +47 -3
  65. package/dist/types/OxyServices.base.d.ts +7 -0
  66. package/dist/types/OxyServices.d.ts +50 -7
  67. package/dist/types/crypto/index.d.ts +1 -1
  68. package/dist/types/crypto/keyManager.d.ts +110 -9
  69. package/dist/types/crypto/polyfill.d.ts +3 -1
  70. package/dist/types/crypto/recoveryPhrase.d.ts +31 -7
  71. package/dist/types/crypto/signatureService.d.ts +4 -0
  72. package/dist/types/index.d.ts +7 -5
  73. package/dist/types/mixins/OxyServices.analytics.d.ts +1 -0
  74. package/dist/types/mixins/OxyServices.assets.d.ts +6 -10
  75. package/dist/types/mixins/OxyServices.auth.d.ts +82 -5
  76. package/dist/types/mixins/OxyServices.contacts.d.ts +99 -0
  77. package/dist/types/mixins/OxyServices.developer.d.ts +1 -0
  78. package/dist/types/mixins/OxyServices.devices.d.ts +1 -0
  79. package/dist/types/mixins/OxyServices.features.d.ts +2 -7
  80. package/dist/types/mixins/OxyServices.fedcm.d.ts +1 -0
  81. package/dist/types/mixins/OxyServices.karma.d.ts +1 -0
  82. package/dist/types/mixins/OxyServices.language.d.ts +1 -0
  83. package/dist/types/mixins/OxyServices.location.d.ts +1 -0
  84. package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -0
  85. package/dist/types/mixins/OxyServices.payment.d.ts +1 -0
  86. package/dist/types/mixins/OxyServices.popup.d.ts +1 -0
  87. package/dist/types/mixins/OxyServices.privacy.d.ts +1 -0
  88. package/dist/types/mixins/OxyServices.redirect.d.ts +1 -0
  89. package/dist/types/mixins/OxyServices.security.d.ts +1 -0
  90. package/dist/types/mixins/OxyServices.topics.d.ts +1 -0
  91. package/dist/types/mixins/OxyServices.user.d.ts +28 -11
  92. package/dist/types/mixins/OxyServices.utility.d.ts +145 -10
  93. package/dist/types/mixins/index.d.ts +52 -4
  94. package/dist/types/models/interfaces.d.ts +62 -3
  95. package/dist/types/utils/accountUtils.d.ts +41 -1
  96. package/dist/types/utils/languageUtils.d.ts +1 -0
  97. package/dist/types/utils/platformCrypto.d.ts +87 -0
  98. package/dist/types/utils/platformCrypto.native.d.ts +54 -0
  99. package/package.json +45 -2
  100. package/src/CrossDomainAuth.ts +12 -10
  101. package/src/HttpService.ts +251 -40
  102. package/src/OxyServices.base.ts +10 -0
  103. package/src/OxyServices.ts +26 -7
  104. package/src/crypto/__tests__/keyManager.test.ts +336 -0
  105. package/src/crypto/index.ts +6 -1
  106. package/src/crypto/keyManager.ts +529 -151
  107. package/src/crypto/polyfill.ts +14 -34
  108. package/src/crypto/recoveryPhrase.ts +56 -17
  109. package/src/crypto/signatureService.ts +25 -30
  110. package/src/i18n/locales/en-US.json +46 -1
  111. package/src/i18n/locales/es-ES.json +46 -1
  112. package/src/index.ts +19 -4
  113. package/src/mixins/OxyServices.assets.ts +15 -11
  114. package/src/mixins/OxyServices.auth.ts +175 -15
  115. package/src/mixins/OxyServices.contacts.ts +73 -0
  116. package/src/mixins/OxyServices.features.ts +2 -12
  117. package/src/mixins/OxyServices.fedcm.ts +4 -3
  118. package/src/mixins/OxyServices.language.ts +6 -4
  119. package/src/mixins/OxyServices.redirect.ts +6 -2
  120. package/src/mixins/OxyServices.security.ts +18 -8
  121. package/src/mixins/OxyServices.user.ts +72 -49
  122. package/src/mixins/OxyServices.utility.ts +562 -89
  123. package/src/mixins/__tests__/serviceAuth.test.ts +623 -0
  124. package/src/mixins/index.ts +58 -7
  125. package/src/models/interfaces.ts +65 -3
  126. package/src/utils/accountUtils.ts +82 -2
  127. package/src/utils/deviceManager.ts +7 -4
  128. package/src/utils/languageUtils.ts +23 -2
  129. package/src/utils/platformCrypto.native.ts +101 -0
  130. package/src/utils/platformCrypto.ts +145 -0
@@ -18,6 +18,40 @@ export interface OxyConfig {
18
18
  onRequestEnd?: (url: string, method: string, duration: number, success: boolean) => void;
19
19
  onRequestError?: (url: string, method: string, error: Error) => void;
20
20
  }
21
+ /**
22
+ * Privacy settings for a user account.
23
+ *
24
+ * All fields are optional because:
25
+ * - Updates are dot-path partial PATCHes — clients send only changed keys.
26
+ * - The server may return a partial subdocument depending on the API
27
+ * build (older builds returned only the field that changed).
28
+ * - User accounts created before a new toggle was introduced won't
29
+ * have that key persisted yet.
30
+ *
31
+ * Mirrors `IPrivacySettings` from `packages/api/src/types/privacy.types.ts`,
32
+ * but with every field marked optional.
33
+ */
34
+ export interface PrivacySettings {
35
+ isPrivateAccount?: boolean;
36
+ hideOnlineStatus?: boolean;
37
+ hideLastSeen?: boolean;
38
+ profileVisibility?: boolean;
39
+ loginAlerts?: boolean;
40
+ blockScreenshots?: boolean;
41
+ login?: boolean;
42
+ biometricLogin?: boolean;
43
+ showActivity?: boolean;
44
+ allowTagging?: boolean;
45
+ allowMentions?: boolean;
46
+ hideReadReceipts?: boolean;
47
+ allowDirectMessages?: boolean;
48
+ dataSharing?: boolean;
49
+ locationSharing?: boolean;
50
+ analyticsSharing?: boolean;
51
+ sensitiveContent?: boolean;
52
+ autoFilter?: boolean;
53
+ muteKeywords?: boolean;
54
+ }
21
55
  export interface User {
22
56
  id: string;
23
57
  publicKey: string;
@@ -25,9 +59,7 @@ export interface User {
25
59
  email?: string;
26
60
  avatar?: string;
27
61
  color?: string;
28
- privacySettings?: {
29
- [key: string]: unknown;
30
- };
62
+ privacySettings?: PrivacySettings;
31
63
  name?: {
32
64
  first?: string;
33
65
  last?: string;
@@ -240,6 +272,33 @@ export interface FileDeleteResponse {
240
272
  message: string;
241
273
  fileId: string;
242
274
  }
275
+ /**
276
+ * React Native file descriptor accepted by FormData.
277
+ *
278
+ * On React Native, the multipart upload reads the file from disk via the URI
279
+ * during the network request — no in-JS Blob construction is required (and
280
+ * doing so would fail on Hermes since RN's BlobManager cannot wrap an
281
+ * ArrayBuffer/ArrayBufferView).
282
+ *
283
+ * This shape matches what `expo-document-picker` and `expo-image-picker`
284
+ * return for selected assets, and is what `OxyServices.assetUpload` accepts
285
+ * on native platforms.
286
+ */
287
+ export interface RNFileDescriptor {
288
+ uri: string;
289
+ type?: string;
290
+ name?: string;
291
+ size?: number;
292
+ }
293
+ /**
294
+ * Asset upload input — accepted by `OxyServices.assetUpload` and `uploadRawFile`.
295
+ *
296
+ * - `File` / `Blob`: standard web browser path. `assetUpload` appends the
297
+ * Blob to FormData directly.
298
+ * - {@link RNFileDescriptor}: React Native path. FormData reads the file from
299
+ * disk via the URI during the multipart request.
300
+ */
301
+ export type AssetUploadInput = File | Blob | RNFileDescriptor;
243
302
  /**
244
303
  * Central Asset Service interfaces
245
304
  */
@@ -10,6 +10,44 @@ export interface QuickAccount {
10
10
  avatar?: string;
11
11
  avatarUrl?: string;
12
12
  }
13
+ /** Minimal user shape accepted by display-name helpers. Avoids importing the full User type. */
14
+ export interface DisplayNameUserShape {
15
+ name?: string | {
16
+ first?: string;
17
+ last?: string;
18
+ full?: string;
19
+ [key: string]: unknown;
20
+ };
21
+ username?: string;
22
+ publicKey?: string;
23
+ }
24
+ /**
25
+ * Truncate a long public key for display, e.g. `0x12345678…`.
26
+ * Falls back to the raw key if it's too short to truncate.
27
+ */
28
+ export declare const formatPublicKeyHandle: (publicKey: string) => string;
29
+ /**
30
+ * Resolve a friendly display name for a user.
31
+ *
32
+ * Order of preference:
33
+ * 1. `name.full`, or composed `name.first name.last`
34
+ * 2. `name` (when stored as a plain string)
35
+ * 3. `username`
36
+ * 4. `Account 0x12345678…` (derived from publicKey, when present)
37
+ * 5. Translated fallback (e.g. "Unnamed")
38
+ *
39
+ * The translation key `common.unnamed` is used for the final fallback. If the
40
+ * caller does not pass a locale, the default English translation is used.
41
+ */
42
+ export declare const getAccountDisplayName: (user: DisplayNameUserShape | null | undefined, locale?: string) => string;
43
+ /**
44
+ * Resolve a `@handle` style identifier for a user.
45
+ *
46
+ * Returns the bare username when present (without the `@`), otherwise a
47
+ * truncated public-key handle (`0x12345678…`), or `undefined` when neither is
48
+ * available — callers can decide whether to hide the line entirely.
49
+ */
50
+ export declare const getAccountFallbackHandle: (user: DisplayNameUserShape | null | undefined) => string | undefined;
13
51
  /**
14
52
  * Build an ordered array of QuickAccounts from a map and order list.
15
53
  */
@@ -23,11 +61,13 @@ export declare const buildAccountsArray: (accounts: Record<string, QuickAccount>
23
61
  * @param getFileDownloadUrl - Function to generate avatar download URL from file ID
24
62
  */
25
63
  export declare const createQuickAccount: (sessionId: string, userData: {
26
- name?: {
64
+ name?: string | {
27
65
  full?: string;
28
66
  first?: string;
67
+ last?: string;
29
68
  };
30
69
  username?: string;
70
+ publicKey?: string;
31
71
  id?: string;
32
72
  _id?: {
33
73
  toString(): string;
@@ -35,3 +35,4 @@ export declare function getNativeLanguageName(languageCode: string | null | unde
35
35
  * @returns Normalized BCP-47 language code
36
36
  */
37
37
  export declare function normalizeLanguageCode(lang?: string | null): string;
38
+ export declare function isRTLLocale(locale?: string | null): boolean;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Platform Crypto / Storage — Default Variant (Node.js, Browser, generic bundlers)
3
+ *
4
+ * Provides lazy access to platform-specific crypto and storage modules.
5
+ *
6
+ * # Variants
7
+ *
8
+ * This module ships in two physical variants on disk, selected per consumer
9
+ * by the bundler / runtime:
10
+ *
11
+ * - `platformCrypto.js` — this file. Used by Node.js, Vite, webpack,
12
+ * Rollup, esbuild, and anything that does
13
+ * not match Metro's `*.native.js`
14
+ * source-extension preference.
15
+ * - `platformCrypto.native.js` — sibling file. Picked up automatically by
16
+ * Metro's resolver (which prefers
17
+ * `*.<platform>.js` and `*.native.js` over
18
+ * plain `*.js` when `preferNativePlatform`
19
+ * is true — Expo sets this for all non-web
20
+ * builds).
21
+ *
22
+ * The `package.json#exports` map also declares a `"react-native"` condition
23
+ * pointing at the same `dist/esm/index.js` entry — that entry transitively
24
+ * imports `./platformCrypto`, and Metro's per-file source-extension lookup
25
+ * substitutes the `.native.js` sibling automatically inside `dist/`. This
26
+ * means consumers never have to add resolver shims; Metro Just Works.
27
+ *
28
+ * Both variants expose the EXACT same public API; importers don't need to know
29
+ * which one they got. The variant difference is purely about which underlying
30
+ * native modules each one references:
31
+ *
32
+ * ┌──────────────────┬───────────────────────┬───────────────────────────────┐
33
+ * │ Function │ Default variant │ React Native variant │
34
+ * ├──────────────────┼───────────────────────┼───────────────────────────────┤
35
+ * │ loadNodeCrypto │ `await import('crypto')` (Node built-in) │
36
+ * │ │ │ throws — Node crypto is not │
37
+ * │ │ │ available on Hermes/RN │
38
+ * ├──────────────────┼───────────────────────┼───────────────────────────────┤
39
+ * │ loadExpoCrypto │ throws — expo-crypto │ static `import 'expo-crypto'` │
40
+ * │ │ is not part of a │ │
41
+ * │ │ Node/Vite bundle │ │
42
+ * ├──────────────────┼───────────────────────┼───────────────────────────────┤
43
+ * │ loadSecureStore │ throws (web/Node have │ static `import 'expo-secure-` │
44
+ * │ │ their own storage) │ store' │
45
+ * ├──────────────────┼───────────────────────┼───────────────────────────────┤
46
+ * │ loadAsyncStorage │ throws (web/Node have │ static `import '@react- │
47
+ * │ │ their own storage) │ native-async-storage/...' │
48
+ * ├──────────────────┼───────────────────────┼───────────────────────────────┤
49
+ * │ getRandomBytesRN │ throws (RN-only) │ direct call into expo-crypto │
50
+ * └──────────────────┴───────────────────────┴───────────────────────────────┘
51
+ *
52
+ * Crucially, the default variant references ONLY Node's `'crypto'`. It never
53
+ * mentions `expo-*` or `@react-native-async-storage/*` — so Vite, webpack,
54
+ * esbuild, Rollup, and Node itself can bundle / require it without ever
55
+ * attempting to resolve those RN-only packages.
56
+ *
57
+ * The React Native variant references ONLY the RN packages. It never
58
+ * mentions `'crypto'` — so Metro and Hermes have nothing to choke on.
59
+ *
60
+ * # Why not a single file with dynamic import?
61
+ *
62
+ * A previous iteration used a "bundler-opaque" `new Function('s', 'return
63
+ * import(s)')` trick so a single file could service every platform. It
64
+ * bundled cleanly on Metro but Hermes refused to PARSE the resulting
65
+ * `import()` expression inside a Function-constructor body
66
+ * (`SyntaxError: Invalid expression encountered` at the `(` of `import(`).
67
+ * The platform-extension split is the only approach that lets each runtime
68
+ * see a file containing only specifiers it can understand — no tricks, no
69
+ * runtime parsing risks.
70
+ */
71
+ export declare function loadNodeCrypto(): Promise<typeof import('crypto')>;
72
+ export declare function loadExpoCrypto(): Promise<typeof import('expo-crypto')>;
73
+ export declare function loadSecureStore(): Promise<typeof import('expo-secure-store')>;
74
+ export declare function loadAsyncStorage(): Promise<{
75
+ default: {
76
+ getItem: (key: string) => Promise<string | null>;
77
+ setItem: (key: string, value: string) => Promise<void>;
78
+ removeItem: (key: string) => Promise<void>;
79
+ };
80
+ }>;
81
+ /**
82
+ * Synchronous random-bytes via `expo-crypto.getRandomBytes`. Only available
83
+ * in the React Native variant. The default variant throws because Node and
84
+ * browsers have their own native CSPRNGs (`crypto.randomBytes` and
85
+ * `crypto.getRandomValues` respectively) — callers should use those.
86
+ */
87
+ export declare function getRandomBytesRN(_byteCount: number): Uint8Array;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Platform Crypto / Storage — React Native Variant
3
+ *
4
+ * Companion to `./platformCrypto.ts`. See the doc-comment at the top of that
5
+ * file for the full design.
6
+ *
7
+ * Metro auto-selects this file in any non-web build (`preferNativePlatform`
8
+ * is `true` for iOS / Android, so `*.native.js` shadows `*.js` during
9
+ * source-extension resolution inside `node_modules/@oxyhq/core/dist/`). On
10
+ * iOS / Android `<base>.ios.js` / `<base>.android.js` would shadow this file
11
+ * if they existed, but they don't — `.native.js` is the shared RN variant.
12
+ *
13
+ * - The default variant references Node's `'crypto'` and would crash Metro
14
+ * if bundled into an RN app.
15
+ * - This variant references the RN-only modules (`expo-crypto`,
16
+ * `expo-secure-store`, `@react-native-async-storage/async-storage`)
17
+ * as static imports, so Metro and Hermes both resolve and parse them
18
+ * cleanly.
19
+ *
20
+ * Both variants expose the same surface; importers don't care which one
21
+ * they got.
22
+ *
23
+ * # Why static imports?
24
+ *
25
+ * Every RN consumer of `@oxyhq/core` already lists or transitively pulls
26
+ * in `expo-crypto`, `expo-secure-store`, and
27
+ * `@react-native-async-storage/async-storage` (they're stable Expo modules
28
+ * present in `services`, `accounts`, `inbox`, and `test-app`). A static
29
+ * import is what Metro wants to see anyway, and Hermes parses it like any
30
+ * other ES module — no `Function`-constructor parser exotic-mode involved.
31
+ *
32
+ * This is also clearer to debug: Metro fails up-front with a normal
33
+ * unresolved-module error if a consumer is missing a peer dep, instead of
34
+ * a confusing runtime throw the first time a code path that needs the
35
+ * module is exercised.
36
+ */
37
+ export declare function loadNodeCrypto(): Promise<typeof import('crypto')>;
38
+ export declare function loadExpoCrypto(): Promise<typeof import('expo-crypto')>;
39
+ export declare function loadSecureStore(): Promise<typeof import('expo-secure-store')>;
40
+ type AsyncStorageLike = {
41
+ getItem: (key: string) => Promise<string | null>;
42
+ setItem: (key: string, value: string) => Promise<void>;
43
+ removeItem: (key: string) => Promise<void>;
44
+ };
45
+ export declare function loadAsyncStorage(): Promise<{
46
+ default: AsyncStorageLike;
47
+ }>;
48
+ /**
49
+ * Synchronous random-bytes via `expo-crypto.getRandomBytes`. Available
50
+ * synchronously because `expo-crypto` is statically imported by this file
51
+ * — no async initialization race.
52
+ */
53
+ export declare function getRandomBytesRN(byteCount: number): Uint8Array;
54
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/core",
3
- "version": "1.11.12",
3
+ "version": "1.11.14",
4
4
  "description": "OxyHQ SDK Foundation — API client, authentication, cryptographic identity, and shared utilities",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -13,24 +13,31 @@
13
13
  "exports": {
14
14
  ".": {
15
15
  "types": "./dist/types/index.d.ts",
16
+ "react-native": "./dist/esm/index.js",
16
17
  "import": "./dist/esm/index.js",
17
18
  "require": "./dist/cjs/index.js",
18
19
  "default": "./dist/esm/index.js"
19
20
  },
20
21
  "./crypto": {
21
22
  "types": "./dist/types/crypto/index.d.ts",
23
+ "react-native": "./dist/esm/crypto/index.js",
22
24
  "import": "./dist/esm/crypto/index.js",
23
25
  "require": "./dist/cjs/crypto/index.js",
24
26
  "default": "./dist/esm/crypto/index.js"
25
27
  },
26
28
  "./shared": {
27
29
  "types": "./dist/types/shared/index.d.ts",
30
+ "react-native": "./dist/esm/shared/index.js",
28
31
  "import": "./dist/esm/shared/index.js",
29
32
  "require": "./dist/cjs/shared/index.js",
30
33
  "default": "./dist/esm/shared/index.js"
31
34
  },
32
35
  "./package.json": "./package.json"
33
36
  },
37
+ "react-native": {
38
+ "./dist/esm/utils/platformCrypto.js": "./dist/esm/utils/platformCrypto.native.js",
39
+ "./dist/cjs/utils/platformCrypto.js": "./dist/cjs/utils/platformCrypto.native.js"
40
+ },
34
41
  "files": [
35
42
  "dist",
36
43
  "src"
@@ -62,7 +69,23 @@
62
69
  "build:types": "tsc -p tsconfig.types.json",
63
70
  "clean": "rm -rf dist",
64
71
  "typescript": "tsc --noEmit",
65
- "lint": "biome lint --error-on-warnings ./src"
72
+ "test": "jest --passWithNoTests",
73
+ "lint": "biome lint --error-on-warnings ./src",
74
+ "release": "rm -rf dist && bun run build && release-it"
75
+ },
76
+ "release-it": {
77
+ "git": {
78
+ "tagName": "@oxyhq/core@${version}",
79
+ "tagAnnotation": "Release @oxyhq/core@${version}",
80
+ "commitMessage": "chore(core): release @oxyhq/core@${version}"
81
+ },
82
+ "github": {
83
+ "release": true,
84
+ "releaseName": "@oxyhq/core@${version}"
85
+ },
86
+ "npm": {
87
+ "publish": true
88
+ }
66
89
  },
67
90
  "dependencies": {
68
91
  "bip39": "^3.1.0",
@@ -73,11 +96,31 @@
73
96
  "socket.io-client": "^4.8.1",
74
97
  "zod": "^3.25.64"
75
98
  },
99
+ "peerDependencies": {
100
+ "@react-native-async-storage/async-storage": "*",
101
+ "expo-crypto": "*",
102
+ "expo-secure-store": "*"
103
+ },
104
+ "peerDependenciesMeta": {
105
+ "@react-native-async-storage/async-storage": {
106
+ "optional": true
107
+ },
108
+ "expo-crypto": {
109
+ "optional": true
110
+ },
111
+ "expo-secure-store": {
112
+ "optional": true
113
+ }
114
+ },
76
115
  "devDependencies": {
77
116
  "@biomejs/biome": "^1.9.4",
117
+ "@react-native-async-storage/async-storage": "^2.2.0",
78
118
  "@types/elliptic": "^6.4.18",
79
119
  "@types/invariant": "^2.2.34",
80
120
  "@types/node": "^20.19.9",
121
+ "expo-crypto": "~56.0.3",
122
+ "expo-secure-store": "~56.0.4",
123
+ "release-it": "^19.0.6",
81
124
  "typescript": "^5.9.2"
82
125
  }
83
126
  }
@@ -130,7 +130,7 @@ export class CrossDomainAuth {
130
130
  * Best method - browser-native, no popups, Google-like experience
131
131
  */
132
132
  async signInWithFedCM(options: CrossDomainAuthOptions = {}): Promise<SessionLoginResponse> {
133
- return (this.oxyServices as any).signInWithFedCM({
133
+ return this.oxyServices.signInWithFedCM({
134
134
  context: options.isSignup ? 'signup' : 'signin',
135
135
  });
136
136
  }
@@ -141,7 +141,7 @@ export class CrossDomainAuth {
141
141
  * Good method - preserves app state, no full page reload
142
142
  */
143
143
  async signInWithPopup(options: CrossDomainAuthOptions = {}): Promise<SessionLoginResponse> {
144
- return (this.oxyServices as any).signInWithPopup({
144
+ return this.oxyServices.signInWithPopup({
145
145
  mode: options.isSignup ? 'signup' : 'login',
146
146
  width: options.popupDimensions?.width,
147
147
  height: options.popupDimensions?.height,
@@ -154,7 +154,7 @@ export class CrossDomainAuth {
154
154
  * Fallback method - works everywhere but loses app state
155
155
  */
156
156
  signInWithRedirect(options: CrossDomainAuthOptions = {}): void {
157
- (this.oxyServices as any).signInWithRedirect({
157
+ this.oxyServices.signInWithRedirect({
158
158
  redirectUri: options.redirectUri,
159
159
  mode: options.isSignup ? 'signup' : 'login',
160
160
  });
@@ -166,7 +166,7 @@ export class CrossDomainAuth {
166
166
  * Call this on app startup to check if we're returning from auth redirect
167
167
  */
168
168
  handleRedirectCallback(): SessionLoginResponse | null {
169
- return (this.oxyServices as any).handleAuthCallback();
169
+ return this.oxyServices.handleAuthCallback();
170
170
  }
171
171
 
172
172
  /**
@@ -181,7 +181,7 @@ export class CrossDomainAuth {
181
181
  // Try FedCM silent sign-in first (if supported)
182
182
  if (this.isFedCMSupported()) {
183
183
  try {
184
- const session = await (this.oxyServices as any).silentSignInWithFedCM();
184
+ const session = await this.oxyServices.silentSignInWithFedCM();
185
185
  if (session) {
186
186
  return session;
187
187
  }
@@ -192,7 +192,7 @@ export class CrossDomainAuth {
192
192
 
193
193
  // Fallback to iframe-based silent auth
194
194
  try {
195
- return await (this.oxyServices as any).silentSignIn();
195
+ return await this.oxyServices.silentSignIn();
196
196
  } catch (error) {
197
197
  console.warn('[CrossDomainAuth] Silent sign-in failed:', error);
198
198
  return null;
@@ -205,14 +205,16 @@ export class CrossDomainAuth {
205
205
  * For redirect method - restores previously authenticated session from localStorage
206
206
  */
207
207
  restoreSession(): boolean {
208
- return (this.oxyServices as any).restoreSession?.() || false;
208
+ return this.oxyServices.restoreSession?.() || false;
209
209
  }
210
210
 
211
211
  /**
212
212
  * Check if FedCM is supported in current browser
213
213
  */
214
214
  isFedCMSupported(): boolean {
215
- return (this.oxyServices as any).constructor.isFedCMSupported?.() || false;
215
+ // FedCM support is exposed both as a static and an instance method on
216
+ // OxyServices; the instance method is reliable across mixin composition.
217
+ return this.oxyServices.isFedCMSupported?.() || false;
216
218
  }
217
219
 
218
220
  /**
@@ -263,10 +265,10 @@ export class CrossDomainAuth {
263
265
  if (restored) {
264
266
  // Verify session is still valid by fetching user
265
267
  try {
266
- const user = await (this.oxyServices as any).getCurrentUser();
268
+ const user = await this.oxyServices.getCurrentUser();
267
269
  if (user) {
268
270
  return {
269
- sessionId: (this.oxyServices as any).getStoredSessionId?.() || '',
271
+ sessionId: this.oxyServices.getStoredSessionId?.() || '',
270
272
  deviceId: '',
271
273
  expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
272
274
  user,