@moon-x/core 0.2.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 (55) hide show
  1. package/README.md +39 -0
  2. package/dist/chain-C9dvKXUY.d.mts +48 -0
  3. package/dist/chain-C9dvKXUY.d.ts +48 -0
  4. package/dist/chunk-264CEGDS.mjs +46 -0
  5. package/dist/chunk-CDT4MC7S.mjs +1532 -0
  6. package/dist/chunk-CMYR6AOY.mjs +0 -0
  7. package/dist/chunk-GQKIA37O.mjs +20 -0
  8. package/dist/chunk-IMLBIIJ4.mjs +36 -0
  9. package/dist/chunk-MOREUKOG.mjs +18 -0
  10. package/dist/chunk-SOKLPX7V.mjs +270 -0
  11. package/dist/index.d.mts +4 -0
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.js +402 -0
  14. package/dist/index.mjs +33 -0
  15. package/dist/interfaces-9k0eKCc4.d.ts +120 -0
  16. package/dist/interfaces-fNhwnCeY.d.mts +120 -0
  17. package/dist/lib/index.d.mts +410 -0
  18. package/dist/lib/index.d.ts +410 -0
  19. package/dist/lib/index.js +1622 -0
  20. package/dist/lib/index.mjs +89 -0
  21. package/dist/passkey-cache-B9PT3AWX.d.mts +47 -0
  22. package/dist/passkey-cache-B9PT3AWX.d.ts +47 -0
  23. package/dist/passkey-metadata-QqFF2SWQ.d.mts +25 -0
  24. package/dist/passkey-metadata-QqFF2SWQ.d.ts +25 -0
  25. package/dist/post-message-C_99BCBh.d.mts +70 -0
  26. package/dist/post-message-C_99BCBh.d.ts +70 -0
  27. package/dist/react/ethereum.d.mts +26 -0
  28. package/dist/react/ethereum.d.ts +26 -0
  29. package/dist/react/ethereum.js +99 -0
  30. package/dist/react/ethereum.mjs +56 -0
  31. package/dist/react/index.d.mts +182 -0
  32. package/dist/react/index.d.ts +182 -0
  33. package/dist/react/index.js +586 -0
  34. package/dist/react/index.mjs +328 -0
  35. package/dist/react/solana.d.mts +17 -0
  36. package/dist/react/solana.d.ts +17 -0
  37. package/dist/react/solana.js +75 -0
  38. package/dist/react/solana.mjs +35 -0
  39. package/dist/sdk/index.d.mts +126 -0
  40. package/dist/sdk/index.d.ts +126 -0
  41. package/dist/sdk/index.js +864 -0
  42. package/dist/sdk/index.mjs +579 -0
  43. package/dist/types/index.d.mts +1190 -0
  44. package/dist/types/index.d.ts +1190 -0
  45. package/dist/types/index.js +64 -0
  46. package/dist/types/index.mjs +10 -0
  47. package/dist/utils/index.d.mts +11 -0
  48. package/dist/utils/index.d.ts +11 -0
  49. package/dist/utils/index.js +365 -0
  50. package/dist/utils/index.mjs +25 -0
  51. package/dist/web/index.d.mts +20 -0
  52. package/dist/web/index.d.ts +20 -0
  53. package/dist/web/index.js +470 -0
  54. package/dist/web/index.mjs +155 -0
  55. package/package.json +111 -0
package/dist/index.js ADDED
@@ -0,0 +1,402 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ FORWARDED_ERROR_FIELDS: () => FORWARDED_ERROR_FIELDS,
24
+ Network: () => Network,
25
+ PostMessageClient: () => PostMessageClient,
26
+ PostMessageMethod: () => PostMessageMethod,
27
+ PostMessageServer: () => PostMessageServer,
28
+ PostMessageType: () => PostMessageType,
29
+ WALLET_ERROR_CODES: () => WALLET_ERROR_CODES,
30
+ WalletCreationError: () => WalletCreationError,
31
+ getIframeOrigin: () => getIframeOrigin,
32
+ getIframeUrl: () => getIframeUrl,
33
+ getMoonKeyApiUrl: () => getMoonKeyApiUrl
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+
37
+ // src/types/wallet.ts
38
+ var WALLET_ERROR_CODES = {
39
+ WALLET_NOT_CONNECTED: "WALLET_NOT_CONNECTED",
40
+ USER_REJECTED: "USER_REJECTED",
41
+ INVALID_MESSAGE: "INVALID_MESSAGE",
42
+ INVALID_TRANSACTION: "INVALID_TRANSACTION",
43
+ NETWORK_ERROR: "NETWORK_ERROR",
44
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
45
+ };
46
+
47
+ // src/types/index.ts
48
+ var WalletCreationError = /* @__PURE__ */ ((WalletCreationError2) => {
49
+ WalletCreationError2["SESSION_INVALID"] = "Session is invalid - cannot create wallet";
50
+ WalletCreationError2["FAILED_TO_CREATE_WALLET"] = "Failed to create wallet";
51
+ return WalletCreationError2;
52
+ })(WalletCreationError || {});
53
+ var Network = /* @__PURE__ */ ((Network2) => {
54
+ Network2["Bitcoin"] = "bitcoin";
55
+ Network2["Solana"] = "solana";
56
+ Network2["Ripple"] = "ripple";
57
+ Network2["Ethereum"] = "ethereum";
58
+ Network2["Polygon"] = "polygon";
59
+ Network2["Arbitrum"] = "arbitrum";
60
+ Network2["Optimism"] = "optimism";
61
+ Network2["Base"] = "base";
62
+ Network2["ZkSync"] = "zksync";
63
+ Network2["BinanceSmartChain"] = "bsc";
64
+ Network2["Tron"] = "tron";
65
+ return Network2;
66
+ })(Network || {});
67
+
68
+ // src/utils/get-api-url.ts
69
+ var getMoonKeyApiUrl = () => {
70
+ if (process.env?.NEXT_PUBLIC_MOONKEY_API_URL) {
71
+ return process.env.NEXT_PUBLIC_MOONKEY_API_URL;
72
+ }
73
+ if (process.env?.NEXT_PUBLIC_MOONKEY_IFRAME_URL) {
74
+ const iframeUrl = process.env.NEXT_PUBLIC_MOONKEY_IFRAME_URL;
75
+ if (iframeUrl.includes("staging") || iframeUrl.includes("auth-staging")) {
76
+ return "https://api.moonx-dev.com";
77
+ }
78
+ }
79
+ if (process.env?.NEXT_PUBLIC_VERCEL_ENV === "preview") {
80
+ return "https://api.moonx-dev.com";
81
+ }
82
+ return "https://api.moonx-dev.com";
83
+ };
84
+
85
+ // src/utils/get-iframe-url.ts
86
+ var DEFAULT_IFRAME_PROJECT_NAME = "moonx-wallet-iframe";
87
+ var joinUrl = (baseUrl, path) => {
88
+ if (!path) return baseUrl;
89
+ const normalizedBase = baseUrl.replace(/\/$/, "");
90
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
91
+ return `${normalizedBase}${normalizedPath}`;
92
+ };
93
+ var withBypass = (url) => {
94
+ const bypass = process.env.NEXT_PUBLIC_VERCEL_PROTECTION_BYPASS;
95
+ if (!bypass) return url;
96
+ const separator = url.includes("?") ? "&" : "?";
97
+ return `${url}${separator}x-vercel-protection-bypass=${bypass}&x-vercel-set-bypass-cookie=samesitenone`;
98
+ };
99
+ var getIframeUrl = (path = "") => {
100
+ if (process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" && process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL) {
101
+ const vercelUrl = process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL.replace(
102
+ /^https?:\/\//,
103
+ ""
104
+ ).replace(/\/$/, "");
105
+ const iframeProjectName = process.env.NEXT_PUBLIC_MOONKEY_IFRAME_PROJECT_NAME || DEFAULT_IFRAME_PROJECT_NAME;
106
+ const iframeUrl = /-git-/.test(vercelUrl) ? vercelUrl.replace(/^[^.]+?-git-/, `${iframeProjectName}-git-`) : (
107
+ // Fallback: legacy `{prefix}-{hash}.vercel.app` style
108
+ vercelUrl.replace(/^[^-]+-/, `${iframeProjectName}-`)
109
+ );
110
+ return withBypass(joinUrl(`https://${iframeUrl}`, path));
111
+ }
112
+ if (process.env.NEXT_PUBLIC_MOONKEY_IFRAME_URL) {
113
+ return joinUrl(process.env.NEXT_PUBLIC_MOONKEY_IFRAME_URL, path);
114
+ }
115
+ return joinUrl("https://iframe.moonx-dev.com", path);
116
+ };
117
+ var getIframeOrigin = (url) => {
118
+ try {
119
+ const urlObj = new URL(url);
120
+ return urlObj.origin;
121
+ } catch (error) {
122
+ console.error("Invalid URL:", url);
123
+ return "";
124
+ }
125
+ };
126
+
127
+ // src/utils/post-message.ts
128
+ var FORWARDED_ERROR_FIELDS = [
129
+ "error_type",
130
+ "error_code",
131
+ "status_code"
132
+ ];
133
+ var generateUUID = () => {
134
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
135
+ return crypto.randomUUID();
136
+ }
137
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
138
+ const r = Math.random() * 16 | 0;
139
+ const v = c === "x" ? r : r & 3 | 8;
140
+ return v.toString(16);
141
+ });
142
+ };
143
+ var PostMessageType = {
144
+ AUTH: "auth",
145
+ INIT: "init",
146
+ WALLET: "wallet",
147
+ EXTERNAL_WALLET: "external_wallet"
148
+ };
149
+ var PostMessageMethod = {
150
+ CLOSE: "CLOSE",
151
+ CREATE_WALLET: "CREATE_WALLET",
152
+ IMPORT_KEY: "IMPORT_KEY",
153
+ FUND_WALLET: "FUND_WALLET",
154
+ GET_APP_CONFIG: "GET_APP_CONFIG",
155
+ GET_BALANCE: "GET_BALANCE",
156
+ GET_CONFIRM_TRANSACTION: "GET_CONFIRM_TRANSACTION",
157
+ GET_CONFIRM_ETHEREUM_TRANSACTION: "GET_CONFIRM_ETHEREUM_TRANSACTION",
158
+ GET_CURRENT_SESSION: "GET_CURRENT_SESSION",
159
+ GET_TOKEN_ACCOUNTS_BY_OWNER: "GET_TOKEN_ACCOUNTS_BY_OWNER",
160
+ GET_USER: "GET_USER",
161
+ GET_WALLET: "GET_WALLET",
162
+ GET_WALLETS: "GET_WALLETS",
163
+ IS_AUTHENTICATED: "IS_AUTHENTICATED",
164
+ LOGIN_CREATE: "LOGIN_CREATE",
165
+ LOGOUT: "LOGOUT",
166
+ PREFETCH_CAPTCHA: "PREFETCH_CAPTCHA",
167
+ READY: "READY",
168
+ SEND_TRANSACTION: "SEND_TRANSACTION",
169
+ SIGN_MESSAGE: "SIGN_MESSAGE",
170
+ SIGN_TRANSACTION: "SIGN_TRANSACTION",
171
+ SIGN_TYPED_DATA: "SIGN_TYPED_DATA",
172
+ // Sign a pre-computed 32-byte digest as ECDSA. Caller-supplied hash
173
+ // — no EIP-191 prefix, no tx parsing, no domain separator. Useful
174
+ // for ZK circuits / custom auth flows / anywhere the digest is
175
+ // computed externally. Mirrors Privy's `secp256k1_sign` provider
176
+ // method but exposed as its own postMessage to keep the iframe
177
+ // dispatcher boring.
178
+ SIGN_HASH: "SIGN_HASH",
179
+ SIGN_7702_AUTHORIZATION: "SIGN_7702_AUTHORIZATION",
180
+ VERIFY_EMAIL_OTP: "VERIFY_EMAIL_OTP",
181
+ VERIFY_OAUTH: "VERIFY_OAUTH",
182
+ START_OAUTH: "START_OAUTH",
183
+ WALLET_REGISTRATION_NONCE: "WALLET_REGISTRATION_NONCE",
184
+ VERIFY_SIWE_WALLET_REGISTRATION: "VERIFY_SIWE_WALLET_REGISTRATION",
185
+ ATTACH_OAUTH: "ATTACH_OAUTH",
186
+ DETACH_OAUTH: "DETACH_OAUTH",
187
+ // Passkey as a post-identity enrollment / unlock ceremony. The two
188
+ // methods below split the ceremony so the parent owns the WebAuthn
189
+ // API call (where user activation lives) and the iframe owns the
190
+ // begin/verify HTTP calls (where the session JWT lives).
191
+ PASSKEY_REGISTER_BEGIN: "PASSKEY_REGISTER_BEGIN",
192
+ PASSKEY_REGISTER_VERIFY: "PASSKEY_REGISTER_VERIFY",
193
+ GET_PASSKEY_STATUS: "GET_PASSKEY_STATUS",
194
+ // Parent-side passkey assertion plumbing. Parent calls GET_DEK_INFO
195
+ // to learn which credential IDs to put in allowCredentials and to
196
+ // know whether bootstrap-vs-unwrap path applies, then runs
197
+ // navigator.credentials.get itself (where iframe-cross-origin
198
+ // activation rules don't bite). Wallet-op postMessages then carry
199
+ // the resulting user_handle_b64url + credential_id_b64url back into
200
+ // the iframe so encrypted-keyshare helpers can unwrap the DEK.
201
+ GET_DEK_INFO: "GET_DEK_INFO",
202
+ // Multi-passkey management on an existing user. ADD_PASSKEY_WRAP is
203
+ // the iframe half of the parent-driven add-passkey flow: parent runs
204
+ // both WebAuthn ceremonies (assert old credential, register new
205
+ // credential), then posts the two resulting (userHandle, credId)
206
+ // pairs here so the iframe can unlock the DEK with the old
207
+ // credential and seal a new wrap with the new credential.
208
+ ADD_PASSKEY_WRAP: "ADD_PASSKEY_WRAP",
209
+ REMOVE_PASSKEY: "REMOVE_PASSKEY"
210
+ };
211
+ var PostMessageClient = class {
212
+ constructor(target, origin = "*") {
213
+ this.target = target;
214
+ this.origin = origin;
215
+ }
216
+ async send(type, method, payload) {
217
+ const id = generateUUID();
218
+ return new Promise((resolve, reject) => {
219
+ const timeout = setTimeout(() => {
220
+ window.removeEventListener("message", handler);
221
+ reject(new Error("Timeout: No response from iframe"));
222
+ }, 3e4);
223
+ const handler = (event) => {
224
+ if (this.origin !== "*" && event.origin !== this.origin) {
225
+ return;
226
+ }
227
+ const response = event.data;
228
+ if (response.id === id) {
229
+ clearTimeout(timeout);
230
+ window.removeEventListener("message", handler);
231
+ if (response.success) {
232
+ resolve(response.data);
233
+ } else {
234
+ const err = new Error(response.error);
235
+ for (const key of FORWARDED_ERROR_FIELDS) {
236
+ const value = response[key];
237
+ if (value !== void 0) {
238
+ err[key] = value;
239
+ }
240
+ }
241
+ reject(err);
242
+ }
243
+ }
244
+ };
245
+ window.addEventListener("message", handler);
246
+ this.target.postMessage(
247
+ {
248
+ id,
249
+ type,
250
+ method,
251
+ payload
252
+ },
253
+ this.origin
254
+ );
255
+ });
256
+ }
257
+ async sendOneWay(type, method, payload) {
258
+ const id = generateUUID();
259
+ const envelope = {
260
+ id,
261
+ type,
262
+ method,
263
+ payload
264
+ };
265
+ if (typeof window !== "undefined" && typeof window.ReactNativeWebView !== "undefined") {
266
+ try {
267
+ window.ReactNativeWebView.postMessage(JSON.stringify(envelope));
268
+ } catch {
269
+ }
270
+ return;
271
+ }
272
+ this.target.postMessage(envelope, this.origin);
273
+ }
274
+ };
275
+ var isReactNativeWebView = () => typeof window !== "undefined" && typeof window.ReactNativeWebView !== "undefined";
276
+ var sendReactNativeReply = (response) => {
277
+ try {
278
+ window.ReactNativeWebView.postMessage(JSON.stringify(response));
279
+ } catch {
280
+ }
281
+ };
282
+ var PostMessageServer = class {
283
+ constructor(originValidator) {
284
+ this.trustedSources = /* @__PURE__ */ new Set();
285
+ this.handlers = /* @__PURE__ */ new Map();
286
+ this.originValidator = originValidator;
287
+ window.addEventListener("message", this.handleMessage.bind(this));
288
+ }
289
+ addTrustedSource(source) {
290
+ this.trustedSources.add(source);
291
+ }
292
+ removeTrustedSource(source) {
293
+ this.trustedSources.delete(source);
294
+ }
295
+ register(type, method, handler) {
296
+ const key = `${type}:${method}`;
297
+ this.handlers.set(key, handler);
298
+ }
299
+ cleanup() {
300
+ window.removeEventListener("message", this.handleMessage.bind(this));
301
+ this.handlers.clear();
302
+ }
303
+ static isLocalhostOrigin(origin) {
304
+ try {
305
+ const url = new URL(origin);
306
+ return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
307
+ } catch {
308
+ return false;
309
+ }
310
+ }
311
+ isValidPostMessageRequest(data) {
312
+ return data && typeof data === "object" && typeof data.id === "string" && typeof data.type === "string" && typeof data.method === "string";
313
+ }
314
+ async handleMessage(event) {
315
+ if (!this.isValidPostMessageRequest(event.data)) {
316
+ return;
317
+ }
318
+ if (!event.origin || event.origin === "null") {
319
+ console.error("[PostMessageServer] Invalid or null origin received");
320
+ return;
321
+ }
322
+ const request = event.data;
323
+ const rnMode = isReactNativeWebView();
324
+ const reply = (response) => {
325
+ if (rnMode) {
326
+ sendReactNativeReply(response);
327
+ return;
328
+ }
329
+ if (event.source && event.origin) {
330
+ event.source.postMessage(response, { targetOrigin: event.origin });
331
+ }
332
+ };
333
+ if (this.originValidator && !rnMode) {
334
+ const publishableKey = request.payload?.publishableKey;
335
+ try {
336
+ const isAllowed = await this.originValidator(
337
+ event.origin,
338
+ publishableKey
339
+ );
340
+ if (!isAllowed) {
341
+ reply({
342
+ id: request.id,
343
+ type: request.type,
344
+ success: false,
345
+ error: `Origin ${event.origin} is not whitelisted. Please add it to your MoonKey dashboard.`
346
+ });
347
+ return;
348
+ }
349
+ } catch (error) {
350
+ reply({
351
+ id: request.id,
352
+ type: request.type,
353
+ success: false,
354
+ error: "Origin validation failed"
355
+ });
356
+ return;
357
+ }
358
+ }
359
+ const key = `${request.type}:${request.method}`;
360
+ const handler = this.handlers.get(key);
361
+ if (handler) {
362
+ try {
363
+ const data = await handler(request.payload);
364
+ reply({
365
+ id: request.id,
366
+ type: request.type,
367
+ success: true,
368
+ data
369
+ });
370
+ } catch (error) {
371
+ const extras = {};
372
+ if (error && typeof error === "object") {
373
+ for (const key2 of FORWARDED_ERROR_FIELDS) {
374
+ const value = error[key2];
375
+ if (value !== void 0) extras[key2] = value;
376
+ }
377
+ }
378
+ reply({
379
+ ...extras,
380
+ id: request.id,
381
+ type: request.type,
382
+ success: false,
383
+ error: error instanceof Error ? error.message : "Unknown error"
384
+ });
385
+ }
386
+ }
387
+ }
388
+ };
389
+ // Annotate the CommonJS export names for ESM import in node:
390
+ 0 && (module.exports = {
391
+ FORWARDED_ERROR_FIELDS,
392
+ Network,
393
+ PostMessageClient,
394
+ PostMessageMethod,
395
+ PostMessageServer,
396
+ PostMessageType,
397
+ WALLET_ERROR_CODES,
398
+ WalletCreationError,
399
+ getIframeOrigin,
400
+ getIframeUrl,
401
+ getMoonKeyApiUrl
402
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,33 @@
1
+ import {
2
+ Network,
3
+ WALLET_ERROR_CODES,
4
+ WalletCreationError
5
+ } from "./chunk-IMLBIIJ4.mjs";
6
+ import "./chunk-CMYR6AOY.mjs";
7
+ import {
8
+ getIframeOrigin,
9
+ getIframeUrl
10
+ } from "./chunk-264CEGDS.mjs";
11
+ import {
12
+ FORWARDED_ERROR_FIELDS,
13
+ PostMessageClient,
14
+ PostMessageMethod,
15
+ PostMessageServer,
16
+ PostMessageType
17
+ } from "./chunk-SOKLPX7V.mjs";
18
+ import {
19
+ getMoonKeyApiUrl
20
+ } from "./chunk-GQKIA37O.mjs";
21
+ export {
22
+ FORWARDED_ERROR_FIELDS,
23
+ Network,
24
+ PostMessageClient,
25
+ PostMessageMethod,
26
+ PostMessageServer,
27
+ PostMessageType,
28
+ WALLET_ERROR_CODES,
29
+ WalletCreationError,
30
+ getIframeOrigin,
31
+ getIframeUrl,
32
+ getMoonKeyApiUrl
33
+ };
@@ -0,0 +1,120 @@
1
+ import { c as PostMessageType, a as PostMessageMethod } from './post-message-C_99BCBh.js';
2
+
3
+ /**
4
+ * Transport — the bidirectional postMessage channel between the parent
5
+ * (web SDK or RN SDK) and the iframe-app. Web wraps
6
+ * `createPostMessageClient(iframeRef.current.contentWindow, ...)`; RN
7
+ * wraps a `WebViewBridge` over react-native-webview.
8
+ *
9
+ * `send` resolves with the iframe handler's raw return value and rejects
10
+ * with the handler's thrown error (canonical envelope, no
11
+ * {success, data} unwrap at the call site).
12
+ */
13
+ interface Transport {
14
+ send<P, R>(type: PostMessageType, method: PostMessageMethod, payload: P): Promise<R>;
15
+ /**
16
+ * Register a handler for inbound messages from the iframe-app. Only
17
+ * needed by the parent-side `*WithUI` flow path, where the modal
18
+ * postMessages a result back that the SDK's pending Promise needs to
19
+ * resolve. Returns an unregister fn.
20
+ */
21
+ register?<P, R>(type: PostMessageType, method: PostMessageMethod, handler: (payload: P) => Promise<R> | R): () => void;
22
+ /**
23
+ * Whether the underlying iframe / WebView is loaded and ready to
24
+ * receive messages. SDK methods short-circuit with "SDK not ready"
25
+ * before calling `send` if this returns false.
26
+ */
27
+ isReady(): boolean;
28
+ }
29
+ /**
30
+ * PasskeyAssertor — runs the WebAuthn ceremony in the *parent* (where
31
+ * user activation lives — cross-origin iframes/WebViews can't reliably
32
+ * get their own click handler).
33
+ *
34
+ * Both `assert` and `create` use empty `allowCredentials` on the
35
+ * underlying API to force the discoverable-login codepath where
36
+ * userHandle is REQUIRED. The userHandle bytes are the wrap key the
37
+ * iframe-app uses to unwrap the DEK before signing.
38
+ */
39
+ interface PasskeyAssertor {
40
+ /**
41
+ * Run a WebAuthn assertion (`navigator.credentials.get` on web,
42
+ * `passkeyGet` from react-native-passkeys on RN). Returns the
43
+ * platform-decoded base64url forms of the credential id and userHandle.
44
+ */
45
+ assert(opts: {
46
+ rpId: string;
47
+ challenge: string;
48
+ /**
49
+ * The wire `allow_credential_ids_b64url` list from GET_DEK_INFO,
50
+ * passed through for platforms that want to use it. Note both
51
+ * platforms today pass an empty array to the underlying API; this
52
+ * field is informational only (e.g. for telemetry or for a future
53
+ * platform that prefers non-discoverable login).
54
+ */
55
+ allowCredentials: string[];
56
+ }): Promise<{
57
+ rawIdB64url: string;
58
+ userHandleB64url: string;
59
+ }>;
60
+ /**
61
+ * Run a WebAuthn registration (`navigator.credentials.create` on web,
62
+ * `passkeyCreate` from react-native-passkeys on RN). Used by passkey
63
+ * register flows.
64
+ */
65
+ create(opts: {
66
+ rpId: string;
67
+ rpName: string;
68
+ userId: Uint8Array;
69
+ userName: string;
70
+ userDisplayName: string;
71
+ challenge: string;
72
+ excludeCredentials?: string[];
73
+ }): Promise<{
74
+ rawIdB64url: string;
75
+ clientDataJSONB64url: string;
76
+ attestationObjectB64url: string;
77
+ }>;
78
+ }
79
+ /**
80
+ * KvStorage — async key/value storage for ID tokens + session metadata.
81
+ * Web wraps `localStorage` (sync, lifted to a resolved Promise); RN
82
+ * wraps `@react-native-async-storage/async-storage` (natively async).
83
+ *
84
+ * Always async at the interface to unify both platforms.
85
+ */
86
+ interface KvStorage {
87
+ get(key: string): Promise<string | null>;
88
+ set(key: string, value: string): Promise<void>;
89
+ remove(key: string): Promise<void>;
90
+ }
91
+ /**
92
+ * OAuthOpener — start an OAuth authorize request and wait for the
93
+ * provider redirect to return with `code` + `state`. Web uses a
94
+ * full-page redirect or popup (completion picked up by
95
+ * `useOAuthCompletion` listening for postMessages); RN uses
96
+ * `expo-web-browser.openAuthSessionAsync` (single Promise resolves on
97
+ * deep-link callback).
98
+ */
99
+ interface OAuthOpener {
100
+ open(opts: {
101
+ authorizeUrl: string;
102
+ redirectUrl: string;
103
+ }): Promise<{
104
+ code: string;
105
+ state: string;
106
+ }>;
107
+ }
108
+ /**
109
+ * The bundle of platform impls that the SDK factories accept. Provider
110
+ * components on each platform construct one of these once and pass it
111
+ * through to the factories.
112
+ */
113
+ interface PlatformImpls {
114
+ transport: Transport;
115
+ passkey: PasskeyAssertor;
116
+ storage: KvStorage;
117
+ oauth: OAuthOpener;
118
+ }
119
+
120
+ export type { KvStorage as K, OAuthOpener as O, PasskeyAssertor as P, Transport as T, PlatformImpls as a };
@@ -0,0 +1,120 @@
1
+ import { c as PostMessageType, a as PostMessageMethod } from './post-message-C_99BCBh.mjs';
2
+
3
+ /**
4
+ * Transport — the bidirectional postMessage channel between the parent
5
+ * (web SDK or RN SDK) and the iframe-app. Web wraps
6
+ * `createPostMessageClient(iframeRef.current.contentWindow, ...)`; RN
7
+ * wraps a `WebViewBridge` over react-native-webview.
8
+ *
9
+ * `send` resolves with the iframe handler's raw return value and rejects
10
+ * with the handler's thrown error (canonical envelope, no
11
+ * {success, data} unwrap at the call site).
12
+ */
13
+ interface Transport {
14
+ send<P, R>(type: PostMessageType, method: PostMessageMethod, payload: P): Promise<R>;
15
+ /**
16
+ * Register a handler for inbound messages from the iframe-app. Only
17
+ * needed by the parent-side `*WithUI` flow path, where the modal
18
+ * postMessages a result back that the SDK's pending Promise needs to
19
+ * resolve. Returns an unregister fn.
20
+ */
21
+ register?<P, R>(type: PostMessageType, method: PostMessageMethod, handler: (payload: P) => Promise<R> | R): () => void;
22
+ /**
23
+ * Whether the underlying iframe / WebView is loaded and ready to
24
+ * receive messages. SDK methods short-circuit with "SDK not ready"
25
+ * before calling `send` if this returns false.
26
+ */
27
+ isReady(): boolean;
28
+ }
29
+ /**
30
+ * PasskeyAssertor — runs the WebAuthn ceremony in the *parent* (where
31
+ * user activation lives — cross-origin iframes/WebViews can't reliably
32
+ * get their own click handler).
33
+ *
34
+ * Both `assert` and `create` use empty `allowCredentials` on the
35
+ * underlying API to force the discoverable-login codepath where
36
+ * userHandle is REQUIRED. The userHandle bytes are the wrap key the
37
+ * iframe-app uses to unwrap the DEK before signing.
38
+ */
39
+ interface PasskeyAssertor {
40
+ /**
41
+ * Run a WebAuthn assertion (`navigator.credentials.get` on web,
42
+ * `passkeyGet` from react-native-passkeys on RN). Returns the
43
+ * platform-decoded base64url forms of the credential id and userHandle.
44
+ */
45
+ assert(opts: {
46
+ rpId: string;
47
+ challenge: string;
48
+ /**
49
+ * The wire `allow_credential_ids_b64url` list from GET_DEK_INFO,
50
+ * passed through for platforms that want to use it. Note both
51
+ * platforms today pass an empty array to the underlying API; this
52
+ * field is informational only (e.g. for telemetry or for a future
53
+ * platform that prefers non-discoverable login).
54
+ */
55
+ allowCredentials: string[];
56
+ }): Promise<{
57
+ rawIdB64url: string;
58
+ userHandleB64url: string;
59
+ }>;
60
+ /**
61
+ * Run a WebAuthn registration (`navigator.credentials.create` on web,
62
+ * `passkeyCreate` from react-native-passkeys on RN). Used by passkey
63
+ * register flows.
64
+ */
65
+ create(opts: {
66
+ rpId: string;
67
+ rpName: string;
68
+ userId: Uint8Array;
69
+ userName: string;
70
+ userDisplayName: string;
71
+ challenge: string;
72
+ excludeCredentials?: string[];
73
+ }): Promise<{
74
+ rawIdB64url: string;
75
+ clientDataJSONB64url: string;
76
+ attestationObjectB64url: string;
77
+ }>;
78
+ }
79
+ /**
80
+ * KvStorage — async key/value storage for ID tokens + session metadata.
81
+ * Web wraps `localStorage` (sync, lifted to a resolved Promise); RN
82
+ * wraps `@react-native-async-storage/async-storage` (natively async).
83
+ *
84
+ * Always async at the interface to unify both platforms.
85
+ */
86
+ interface KvStorage {
87
+ get(key: string): Promise<string | null>;
88
+ set(key: string, value: string): Promise<void>;
89
+ remove(key: string): Promise<void>;
90
+ }
91
+ /**
92
+ * OAuthOpener — start an OAuth authorize request and wait for the
93
+ * provider redirect to return with `code` + `state`. Web uses a
94
+ * full-page redirect or popup (completion picked up by
95
+ * `useOAuthCompletion` listening for postMessages); RN uses
96
+ * `expo-web-browser.openAuthSessionAsync` (single Promise resolves on
97
+ * deep-link callback).
98
+ */
99
+ interface OAuthOpener {
100
+ open(opts: {
101
+ authorizeUrl: string;
102
+ redirectUrl: string;
103
+ }): Promise<{
104
+ code: string;
105
+ state: string;
106
+ }>;
107
+ }
108
+ /**
109
+ * The bundle of platform impls that the SDK factories accept. Provider
110
+ * components on each platform construct one of these once and pass it
111
+ * through to the factories.
112
+ */
113
+ interface PlatformImpls {
114
+ transport: Transport;
115
+ passkey: PasskeyAssertor;
116
+ storage: KvStorage;
117
+ oauth: OAuthOpener;
118
+ }
119
+
120
+ export type { KvStorage as K, OAuthOpener as O, PasskeyAssertor as P, Transport as T, PlatformImpls as a };