@dynamic-labs-sdk/legacy-embedded-wallet-upgrade 1.21.2 → 1.22.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 (58) hide show
  1. package/dist/consumeUpgradeRedirect/consumeUpgradeRedirect.d.ts +57 -0
  2. package/dist/consumeUpgradeRedirect/consumeUpgradeRedirect.d.ts.map +1 -0
  3. package/dist/consumeUpgradeRedirect/index.d.ts +2 -0
  4. package/dist/consumeUpgradeRedirect/index.d.ts.map +1 -0
  5. package/dist/errors/UpgradeIframeClosedError.d.ts +5 -0
  6. package/dist/errors/UpgradeIframeClosedError.d.ts.map +1 -0
  7. package/dist/errors/UpgradeIframeUnavailableInReactNativeError.d.ts +5 -0
  8. package/dist/errors/UpgradeIframeUnavailableInReactNativeError.d.ts.map +1 -0
  9. package/dist/exports/index.d.ts +6 -0
  10. package/dist/exports/index.d.ts.map +1 -1
  11. package/dist/exports/react.d.ts +5 -0
  12. package/dist/exports/react.d.ts.map +1 -0
  13. package/dist/index.cjs +110 -151
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.esm.js +105 -150
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.native.esm.js +365 -0
  18. package/dist/index.native.esm.js.map +1 -0
  19. package/dist/openUpgradeIframe/index.d.ts +3 -0
  20. package/dist/openUpgradeIframe/index.d.ts.map +1 -0
  21. package/dist/openUpgradeIframe/openUpgradeIframe.d.ts +33 -0
  22. package/dist/openUpgradeIframe/openUpgradeIframe.d.ts.map +1 -0
  23. package/dist/openUpgradeIframe/openUpgradeIframe.types.d.ts +38 -0
  24. package/dist/openUpgradeIframe/openUpgradeIframe.types.d.ts.map +1 -0
  25. package/dist/react/useHasWalletsRequiringUpgrade/index.d.ts +2 -0
  26. package/dist/react/useHasWalletsRequiringUpgrade/index.d.ts.map +1 -0
  27. package/dist/react/useHasWalletsRequiringUpgrade/useHasWalletsRequiringUpgrade.d.ts +16 -0
  28. package/dist/react/useHasWalletsRequiringUpgrade/useHasWalletsRequiringUpgrade.d.ts.map +1 -0
  29. package/dist/react/useUpgradeIframe/index.d.ts +2 -0
  30. package/dist/react/useUpgradeIframe/index.d.ts.map +1 -0
  31. package/dist/react/useUpgradeIframe/useUpgradeIframe.d.ts +56 -0
  32. package/dist/react/useUpgradeIframe/useUpgradeIframe.d.ts.map +1 -0
  33. package/dist/react/useUpgradeRedirectResult/index.d.ts +2 -0
  34. package/dist/react/useUpgradeRedirectResult/index.d.ts.map +1 -0
  35. package/dist/react/useUpgradeRedirectResult/useUpgradeRedirectResult.d.ts +47 -0
  36. package/dist/react/useUpgradeRedirectResult/useUpgradeRedirectResult.d.ts.map +1 -0
  37. package/dist/react/useWalletsRequiringUpgrade/index.d.ts +2 -0
  38. package/dist/react/useWalletsRequiringUpgrade/index.d.ts.map +1 -0
  39. package/dist/react/useWalletsRequiringUpgrade/useWalletsRequiringUpgrade.d.ts +17 -0
  40. package/dist/react/useWalletsRequiringUpgrade/useWalletsRequiringUpgrade.d.ts.map +1 -0
  41. package/dist/react.cjs +179 -0
  42. package/dist/react.cjs.map +1 -0
  43. package/dist/react.esm.js +176 -0
  44. package/dist/react.esm.js.map +1 -0
  45. package/dist/startUpgradeRedirect/index.d.ts +2 -0
  46. package/dist/startUpgradeRedirect/index.d.ts.map +1 -0
  47. package/dist/startUpgradeRedirect/startUpgradeRedirect.d.ts +39 -0
  48. package/dist/startUpgradeRedirect/startUpgradeRedirect.d.ts.map +1 -0
  49. package/dist/subscribeToUpgradeCompletion/index.d.ts +2 -0
  50. package/dist/subscribeToUpgradeCompletion/index.d.ts.map +1 -0
  51. package/dist/subscribeToUpgradeCompletion/subscribeToUpgradeCompletion.d.ts +53 -0
  52. package/dist/subscribeToUpgradeCompletion/subscribeToUpgradeCompletion.d.ts.map +1 -0
  53. package/dist/subscribeToUpgradeCompletion-CfKOBwip.cjs +311 -0
  54. package/dist/subscribeToUpgradeCompletion-CfKOBwip.cjs.map +1 -0
  55. package/dist/subscribeToUpgradeCompletion-D7xhWUn8.esm.js +270 -0
  56. package/dist/subscribeToUpgradeCompletion-D7xhWUn8.esm.js.map +1 -0
  57. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  58. package/package.json +25 -5
@@ -0,0 +1,57 @@
1
+ import { type WalletUpgradeOutcome } from '../upgradeAppContract';
2
+ /**
3
+ * Options for {@link consumeUpgradeRedirect}.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * // Browser: read the outcome from the current page.
8
+ * await consumeUpgradeRedirect({ url: window.location.href });
9
+ * ```
10
+ * @see consumeUpgradeRedirect
11
+ * @see startUpgradeRedirect
12
+ */
13
+ export type ConsumeUpgradeRedirectParams = {
14
+ /**
15
+ * The return URL to read the upgrade outcome from. Pass the URL yourself so
16
+ * the flow works everywhere: in the browser pass `window.location.href`; in
17
+ * React Native pass the deep-link URL you received. This mirrors how social
18
+ * sign-in and device registration consume their redirects, and keeps the
19
+ * function free of any implicit `window` dependency.
20
+ */
21
+ url: string;
22
+ };
23
+ /**
24
+ * Handles the return leg of the redirect upgrade path.
25
+ *
26
+ * The upgrade app sends the user back with the outcome in the
27
+ * `dynamicWaasMigrationStatus` query param. Call this once on app load with the
28
+ * return URL: it reads the param, and when it is present refreshes the session
29
+ * on success (so the upgraded wallet appears). Returns the outcome, or `null`
30
+ * when the URL carries no upgrade result — so callers can drive their own
31
+ * toast/UI.
32
+ *
33
+ * You always pass the URL (`window.location.href` in the browser, the deep-link
34
+ * URL in React Native), matching how social sign-in and device registration
35
+ * consume their redirects. The function never touches browser history, so you
36
+ * own clearing the param from your navigation state once you have the outcome.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * // Browser
41
+ * const outcome = await consumeUpgradeRedirect({ url: window.location.href });
42
+ * if (outcome?.status === 'error') showRetryToast();
43
+ * ```
44
+ * @example
45
+ * ```ts
46
+ * // React Native: pass the deep-link URL you received.
47
+ * const outcome = await consumeUpgradeRedirect({ url: deepLinkUrl });
48
+ * ```
49
+ * @param params - Options.
50
+ * @param params.url - Return URL to read the outcome from (e.g. `window.location.href`).
51
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
52
+ * @returns A promise resolving to the upgrade outcome, or `null` when there was no upgrade result to consume.
53
+ * @see startUpgradeRedirect
54
+ * @see subscribeToUpgradeCompletion
55
+ */
56
+ export declare const consumeUpgradeRedirect: ({ url }: ConsumeUpgradeRedirectParams, client?: import("@dynamic-labs-sdk/client").DynamicClient) => Promise<WalletUpgradeOutcome | null>;
57
+ //# sourceMappingURL=consumeUpgradeRedirect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consumeUpgradeRedirect.d.ts","sourceRoot":"","sources":["../../src/consumeUpgradeRedirect/consumeUpgradeRedirect.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;GAUG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;;;;OAMG;IACH,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,sBAAsB,YACxB,4BAA4B,gEAEpC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAmBrC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { consumeUpgradeRedirect, type ConsumeUpgradeRedirectParams, } from './consumeUpgradeRedirect';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumeUpgradeRedirect/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { BaseError } from '@dynamic-labs-sdk/client';
2
+ export declare class UpgradeIframeClosedError extends BaseError {
3
+ constructor();
4
+ }
5
+ //# sourceMappingURL=UpgradeIframeClosedError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpgradeIframeClosedError.d.ts","sourceRoot":"","sources":["../../src/errors/UpgradeIframeClosedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,wBAAyB,SAAQ,SAAS;;CAUtD"}
@@ -0,0 +1,5 @@
1
+ import { BaseError } from '@dynamic-labs-sdk/client';
2
+ export declare class UpgradeIframeUnavailableInReactNativeError extends BaseError {
3
+ constructor();
4
+ }
5
+ //# sourceMappingURL=UpgradeIframeUnavailableInReactNativeError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpgradeIframeUnavailableInReactNativeError.d.ts","sourceRoot":"","sources":["../../src/errors/UpgradeIframeUnavailableInReactNativeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,0CAA2C,SAAQ,SAAS;;CAWxE"}
@@ -1,4 +1,10 @@
1
1
  export { buildUpgradeUrl } from '../buildUpgradeUrl';
2
2
  export { getWalletsRequiringUpgrade } from '../getWalletsRequiringUpgrade';
3
3
  export { hasWalletsRequiringUpgrade } from '../hasWalletsRequiringUpgrade';
4
+ export { startUpgradeRedirect } from '../startUpgradeRedirect';
5
+ export { consumeUpgradeRedirect, type ConsumeUpgradeRedirectParams, } from '../consumeUpgradeRedirect';
6
+ export { subscribeToUpgradeCompletion } from '../subscribeToUpgradeCompletion';
7
+ export { openUpgradeIframe } from '../openUpgradeIframe';
8
+ export type { UpgradeIframeSession } from '../openUpgradeIframe';
9
+ export type { WalletUpgradeOutcome, WalletUpgradeStatus, } from '../upgradeAppContract';
4
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exports/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,sBAAsB,EACtB,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { useWalletsRequiringUpgrade } from '../react/useWalletsRequiringUpgrade';
2
+ export { useHasWalletsRequiringUpgrade } from '../react/useHasWalletsRequiringUpgrade';
3
+ export { useUpgradeRedirectResult, type UseUpgradeRedirectResultParams, } from '../react/useUpgradeRedirectResult';
4
+ export { useUpgradeIframe, type UseUpgradeIframeParams, type UseUpgradeIframeResult, } from '../react/useUpgradeIframe';
5
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/exports/react.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAC;AACvF,OAAO,EACL,wBAAwB,EACxB,KAAK,8BAA8B,GACpC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,2BAA2B,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,192 +1,151 @@
1
+ const require_subscribeToUpgradeCompletion = require('./subscribeToUpgradeCompletion-CfKOBwip.cjs');
1
2
  let _dynamic_labs_sdk_assert_package_version = require("@dynamic-labs-sdk/assert-package-version");
2
3
  let _dynamic_labs_sdk_client = require("@dynamic-labs-sdk/client");
3
4
  let _dynamic_labs_sdk_client_core = require("@dynamic-labs-sdk/client/core");
4
5
 
5
- //#region package.json
6
- var name = "@dynamic-labs-sdk/legacy-embedded-wallet-upgrade";
7
- var version = "1.21.2";
8
-
9
- //#endregion
10
- //#region src/errors/InvalidUpgradeBaseUrlError.ts
11
- var InvalidUpgradeBaseUrlError = class extends _dynamic_labs_sdk_client.BaseError {
12
- constructor(baseUrl) {
13
- super({
14
- cause: null,
15
- code: "invalid_upgrade_base_url_error",
16
- docsUrl: null,
17
- name: "InvalidUpgradeBaseUrlError",
18
- shortMessage: `Upgrade baseUrl must be an absolute https URL, received: ${baseUrl}`
19
- });
20
- }
21
- };
22
-
23
- //#endregion
24
- //#region src/errors/InvalidUpgradeRedirectUrlError.ts
25
- var InvalidUpgradeRedirectUrlError = class extends _dynamic_labs_sdk_client.BaseError {
26
- constructor(redirectUrl) {
27
- super({
28
- cause: null,
29
- code: "invalid_upgrade_redirect_url_error",
30
- docsUrl: null,
31
- name: "InvalidUpgradeRedirectUrlError",
32
- shortMessage: `Upgrade redirectUrl must be an absolute https URL, received: ${redirectUrl}`
33
- });
34
- }
35
- };
36
-
37
- //#endregion
38
- //#region src/upgradeAppContract.ts
39
- /**
40
- * Default base URL of the hosted WaaS upgrade app. Both upgrade paths point at
41
- * this origin and append `environmentId` + `redirectUrl` query params. Callers
42
- * can override it (e.g. to target a local or preview build during QA) via the
43
- * `baseUrl` option on the public functions.
44
- */
45
- const UPGRADE_APP_BASE_URL = "https://waas-migration-dynamic-xyz.vercel.app";
46
- /**
47
- * Query param the upgrade app requires: which Dynamic environment to
48
- * authenticate the user against. Derived from the Dynamic client so callers
49
- * never pass it explicitly.
50
- */
51
- const UPGRADE_ENVIRONMENT_ID_PARAM = "environmentId";
52
- /**
53
- * Query param the upgrade app requires: where to send the user (redirect flow)
54
- * or which origin it postMessages to (iframe flow) once the upgrade finishes.
55
- * The upgrade app rejects anything that is not an absolute https URL.
56
- */
57
- const UPGRADE_REDIRECT_URL_PARAM = "redirectUrl";
58
-
59
- //#endregion
60
- //#region src/buildUpgradeUrl/buildUpgradeUrl.ts
61
- const HTTPS_PROTOCOL = "https:";
6
+ //#region src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts
62
7
  /**
63
- * Builds the URL that drives the hosted upgrade app for the client's Dynamic
64
- * environment and a return target.
8
+ * Returns whether the current session has any legacy Dynamic embedded wallet
9
+ * that requires an upgrade to Dynamic WaaS.
65
10
  *
66
- * This is the low-level primitive behind every upgrade path: the redirect flow
67
- * navigates the top-level window to it, the iframe flow loads it as the iframe
68
- * `src`, and a React Native WebView can load it directly. The environment id is
69
- * read from the client, and `redirectUrl` defaults to the current page, so the
70
- * common call is zero-arg. Prefer {@link startUpgradeRedirect} or
71
- * {@link openUpgradeIframe} unless you are mounting the upgrade app yourself.
11
+ * A boolean convenience over {@link getWalletsRequiringUpgrade} for the common
12
+ * case where you only need to decide whether to surface the upgrade flow (e.g.
13
+ * show a banner or gate a wallet's actions) rather than act on the specific
14
+ * accounts.
72
15
  *
73
16
  * @example
74
17
  * ```ts
75
- * const src = buildUpgradeUrl();
76
- * // or target a local upgrade app during QA:
77
- * const localSrc = buildUpgradeUrl({ baseUrl: 'https://localhost:3000' });
18
+ * if (hasWalletsRequiringUpgrade()) {
19
+ * showUpgradeToWaasBanner();
20
+ * }
78
21
  * ```
79
- * @param [params] - Options for the generated URL.
80
- * @param [params.redirectUrl] - Absolute https return URL; defaults to `window.location.href`.
81
- * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.
82
22
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
83
- * @returns The fully-qualified upgrade app URL to load.
84
- * @throws {InvalidUpgradeRedirectUrlError} When `redirectUrl` is not an absolute https URL.
85
- * @throws {InvalidUpgradeBaseUrlError} When `baseUrl` is not an absolute https URL.
86
- * @throws {UnavailableInServerSideError} When called during SSR without an explicit `redirectUrl`.
23
+ * @returns True when at least one wallet account requires an upgrade to Dynamic WaaS, false otherwise.
24
+ * @see getWalletsRequiringUpgrade
87
25
  * @see startUpgradeRedirect
88
- * @see openUpgradeIframe
89
26
  */
90
- const buildUpgradeUrl = ({ redirectUrl, baseUrl = UPGRADE_APP_BASE_URL } = {}, client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => {
91
- if (redirectUrl === void 0 && typeof window === "undefined") throw new _dynamic_labs_sdk_client.UnavailableInServerSideError("buildUpgradeUrl");
92
- const resolvedRedirectUrl = redirectUrl ?? window.location.href;
93
- if (new URL(resolvedRedirectUrl).protocol !== HTTPS_PROTOCOL) throw new InvalidUpgradeRedirectUrlError(resolvedRedirectUrl);
94
- const url = new URL(baseUrl);
95
- if (url.protocol !== HTTPS_PROTOCOL) throw new InvalidUpgradeBaseUrlError(baseUrl);
96
- const { environmentId } = (0, _dynamic_labs_sdk_client_core.getCore)(client);
97
- url.searchParams.set(UPGRADE_ENVIRONMENT_ID_PARAM, environmentId);
98
- url.searchParams.set(UPGRADE_REDIRECT_URL_PARAM, resolvedRedirectUrl);
99
- return url.toString();
100
- };
27
+ const hasWalletsRequiringUpgrade = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => require_subscribeToUpgradeCompletion.getWalletsRequiringUpgrade(client).length > 0;
101
28
 
102
29
  //#endregion
103
- //#region src/walletAccountRequiresUpgrade/walletAccountRequiresUpgrade.ts
30
+ //#region src/startUpgradeRedirect/startUpgradeRedirect.ts
104
31
  /**
105
- * Provider-key substring shared by every Dynamic embedded wallet that predates
106
- * Dynamic WaaS and can therefore be upgraded to it. A wallet account's
107
- * `walletProviderKey` is a composite backend value (e.g. `<provider>evm` /
108
- * `<provider>hdsolana` suffixed with `:embeddedWallet`); both the standard and
109
- * HD variants contain this marker, so matching it as a substring identifies all
110
- * of them. This is an opaque backend value, matched verbatim — not a user-facing
111
- * concept.
112
- */
113
- const LEGACY_EMBEDDED_WALLET_PROVIDER_KEY = "turnkey";
114
- /**
115
- * Returns whether a wallet account is a legacy Dynamic embedded wallet that
116
- * requires an upgrade to Dynamic WaaS.
32
+ * Starts the redirect upgrade path by navigating the top-level window to the
33
+ * hosted upgrade app.
117
34
  *
118
- * Shared predicate behind both the imperative {@link getWalletsRequiringUpgrade}
119
- * getter and the reactive `useWalletsRequiringUpgrade` hook, so the definition
120
- * of "requires upgrade" lives in exactly one place.
35
+ * Call this from an "Upgrade" button. The upgrade app runs full-page and, once
36
+ * finished, returns the user to `redirectUrl` with the outcome encoded in the
37
+ * URL call {@link consumeUpgradeRedirect} on load to pick it up. The
38
+ * environment id and return URL are derived from the client and current page,
39
+ * so the common call is zero-arg.
121
40
  *
122
41
  * @example
123
42
  * ```ts
124
- * const upgradeable = walletAccounts.filter(walletAccountRequiresUpgrade);
43
+ * // on the "Upgrade via redirect" button
44
+ * await startUpgradeRedirect();
125
45
  * ```
126
- * @param walletAccount - The wallet account to test.
127
- * @returns True when the account is a legacy embedded wallet requiring an upgrade.
128
- * @see getWalletsRequiringUpgrade
129
- * @see hasWalletsRequiringUpgrade
46
+ * @param [params] - Options for the redirect.
47
+ * @param [params.redirectUrl] - Absolute https return URL; defaults to `window.location.href`.
48
+ * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.
49
+ * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
50
+ * @returns A promise that resolves once navigation has been initiated.
51
+ * @see consumeUpgradeRedirect
52
+ * @see buildUpgradeUrl
130
53
  */
131
- const walletAccountRequiresUpgrade = (walletAccount) => walletAccount.walletProviderKey.includes(LEGACY_EMBEDDED_WALLET_PROVIDER_KEY);
54
+ const startUpgradeRedirect = async (params = {}, client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => (0, _dynamic_labs_sdk_client_core.getCore)(client).navigate(require_subscribeToUpgradeCompletion.buildUpgradeUrl(params, client));
132
55
 
133
56
  //#endregion
134
- //#region src/getWalletsRequiringUpgrade/getWalletsRequiringUpgrade.ts
135
- /**
136
- * Returns the current session's wallet accounts that are legacy Dynamic
137
- * embedded wallets requiring an upgrade to Dynamic WaaS.
138
- *
139
- * These are earlier-generation Dynamic embedded wallets that predate Dynamic
140
- * WaaS (the current TSS-MPC embedded wallet) and can be upgraded to it. Use this
141
- * when you need the accounts themselves — for example to render only the
142
- * upgrade entry points on those wallets. Already-upgraded Dynamic WaaS accounts
143
- * are never returned. For a simple boolean check, use
144
- * {@link hasWalletsRequiringUpgrade}.
145
- *
146
- * @example
147
- * ```ts
148
- * const walletsRequiringUpgrade = getWalletsRequiringUpgrade();
149
- * if (walletsRequiringUpgrade.length > 0) {
150
- * promptUpgrade(walletsRequiringUpgrade);
151
- * }
152
- * ```
153
- * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
154
- * @returns The wallet accounts requiring an upgrade to Dynamic WaaS (empty when none).
155
- * @see hasWalletsRequiringUpgrade
156
- * @see startUpgradeRedirect
157
- */
158
- const getWalletsRequiringUpgrade = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => (0, _dynamic_labs_sdk_client.getWalletAccounts)(client).filter(walletAccountRequiresUpgrade);
57
+ //#region src/errors/UpgradeIframeClosedError.ts
58
+ var UpgradeIframeClosedError = class extends _dynamic_labs_sdk_client.BaseError {
59
+ constructor() {
60
+ super({
61
+ cause: null,
62
+ code: "upgrade_iframe_closed_error",
63
+ docsUrl: null,
64
+ name: "UpgradeIframeClosedError",
65
+ shortMessage: "Upgrade iframe was closed before the upgrade completed"
66
+ });
67
+ }
68
+ };
159
69
 
160
70
  //#endregion
161
- //#region src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts
71
+ //#region src/openUpgradeIframe/openUpgradeIframe.ts
72
+ const UPGRADE_IFRAME_ALLOW = "clipboard-write; publickey-credentials-get *; publickey-credentials-create *";
73
+ const UPGRADE_IFRAME_TITLE = "Dynamic embedded wallet upgrade";
162
74
  /**
163
- * Returns whether the current session has any legacy Dynamic embedded wallet
164
- * that requires an upgrade to Dynamic WaaS.
75
+ * Runs the embedded upgrade path by mounting the hosted upgrade app in an
76
+ * iframe inside a container you provide.
165
77
  *
166
- * A boolean convenience over {@link getWalletsRequiringUpgrade} for the common
167
- * case where you only need to decide whether to surface the upgrade flow (e.g.
168
- * show a banner or gate a wallet's actions) rather than act on the specific
169
- * accounts.
78
+ * The package renders no UI of its own: pass the element of your modal/sheet
79
+ * and it appends the iframe, wires the origin-checked completion handshake, and
80
+ * refreshes the session on success. `completed` resolves with the outcome once
81
+ * the app reports back; call `close()` when the user dismisses the surface (or
82
+ * after completion) to remove the iframe and detach the listener. Closing
83
+ * before completion rejects `completed` with {@link UpgradeIframeClosedError}
84
+ * so awaiters don't hang — wrap `await session.completed` in try/catch if you
85
+ * allow early dismissal. For React Native or custom mounts, use
86
+ * {@link subscribeToUpgradeCompletion} with {@link buildUpgradeUrl} instead.
170
87
  *
171
88
  * @example
172
89
  * ```ts
173
- * if (hasWalletsRequiringUpgrade()) {
174
- * showUpgradeToWaasBanner();
175
- * }
90
+ * const session = openUpgradeIframe({ container: sheetBodyEl });
91
+ * const { status } = await session.completed;
92
+ * session.close();
176
93
  * ```
94
+ * @param params - Iframe options.
95
+ * @param params.container - Element the upgrade iframe is appended into.
96
+ * @param [params.redirectUrl] - Absolute https completion URL; defaults to `window.location.href`.
97
+ * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.
177
98
  * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
178
- * @returns True when at least one wallet account requires an upgrade to Dynamic WaaS, false otherwise.
179
- * @see getWalletsRequiringUpgrade
180
- * @see startUpgradeRedirect
99
+ * @returns A session handle exposing the `iframe`, a `close` function, and the `completed` promise.
100
+ * @see subscribeToUpgradeCompletion
101
+ * @see buildUpgradeUrl
181
102
  */
182
- const hasWalletsRequiringUpgrade = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => getWalletsRequiringUpgrade(client).length > 0;
103
+ const openUpgradeIframe = ({ container, redirectUrl, baseUrl }, client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => {
104
+ const iframe = document.createElement("iframe");
105
+ iframe.src = require_subscribeToUpgradeCompletion.buildUpgradeUrl({
106
+ baseUrl,
107
+ redirectUrl
108
+ }, client);
109
+ iframe.title = UPGRADE_IFRAME_TITLE;
110
+ iframe.setAttribute("allow", UPGRADE_IFRAME_ALLOW);
111
+ container.appendChild(iframe);
112
+ let resolveCompleted;
113
+ let rejectCompleted;
114
+ const completed = new Promise((resolve, reject) => {
115
+ resolveCompleted = resolve;
116
+ rejectCompleted = reject;
117
+ });
118
+ completed.catch(() => void 0);
119
+ let hasReceivedCompletion = false;
120
+ const unsubscribe = require_subscribeToUpgradeCompletion.subscribeToUpgradeCompletion({
121
+ baseUrl,
122
+ onComplete: (outcome) => resolveCompleted?.(outcome),
123
+ onReceived: () => {
124
+ hasReceivedCompletion = true;
125
+ }
126
+ }, client);
127
+ const close = () => {
128
+ unsubscribe();
129
+ iframe.remove();
130
+ if (!hasReceivedCompletion) rejectCompleted?.(new UpgradeIframeClosedError());
131
+ };
132
+ return {
133
+ close,
134
+ completed,
135
+ iframe
136
+ };
137
+ };
183
138
 
184
139
  //#endregion
185
140
  //#region src/exports/index.ts
186
- (0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(name, version);
141
+ (0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(require_subscribeToUpgradeCompletion.name, require_subscribeToUpgradeCompletion.version);
187
142
 
188
143
  //#endregion
189
- exports.buildUpgradeUrl = buildUpgradeUrl;
190
- exports.getWalletsRequiringUpgrade = getWalletsRequiringUpgrade;
144
+ exports.buildUpgradeUrl = require_subscribeToUpgradeCompletion.buildUpgradeUrl;
145
+ exports.consumeUpgradeRedirect = require_subscribeToUpgradeCompletion.consumeUpgradeRedirect;
146
+ exports.getWalletsRequiringUpgrade = require_subscribeToUpgradeCompletion.getWalletsRequiringUpgrade;
191
147
  exports.hasWalletsRequiringUpgrade = hasWalletsRequiringUpgrade;
148
+ exports.openUpgradeIframe = openUpgradeIframe;
149
+ exports.startUpgradeRedirect = startUpgradeRedirect;
150
+ exports.subscribeToUpgradeCompletion = require_subscribeToUpgradeCompletion.subscribeToUpgradeCompletion;
192
151
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseError","BaseError","UnavailableInServerSideError","packageName","packageVersion"],"sources":["../package.json","../src/errors/InvalidUpgradeBaseUrlError.ts","../src/errors/InvalidUpgradeRedirectUrlError.ts","../src/upgradeAppContract.ts","../src/buildUpgradeUrl/buildUpgradeUrl.ts","../src/walletAccountRequiresUpgrade/walletAccountRequiresUpgrade.ts","../src/getWalletsRequiringUpgrade/getWalletsRequiringUpgrade.ts","../src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts","../src/exports/index.ts"],"sourcesContent":["","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class InvalidUpgradeBaseUrlError extends BaseError {\n // eslint-disable-next-line custom-rules/require-single-object-param\n constructor(baseUrl: string) {\n super({\n cause: null,\n code: 'invalid_upgrade_base_url_error',\n docsUrl: null,\n name: 'InvalidUpgradeBaseUrlError',\n shortMessage: `Upgrade baseUrl must be an absolute https URL, received: ${baseUrl}`,\n });\n }\n}\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class InvalidUpgradeRedirectUrlError extends BaseError {\n // eslint-disable-next-line custom-rules/require-single-object-param\n constructor(redirectUrl: string) {\n super({\n cause: null,\n code: 'invalid_upgrade_redirect_url_error',\n docsUrl: null,\n name: 'InvalidUpgradeRedirectUrlError',\n shortMessage: `Upgrade redirectUrl must be an absolute https URL, received: ${redirectUrl}`,\n });\n }\n}\n","// Contract shared with the standalone WaaS upgrade app\n// (dynamic-labs-oss/waas-migration). Every identifier below MUST stay\n// byte-for-byte identical to the ones the upgrade app reads/emits in its\n// `migrationConfig.ts`, otherwise the redirect round-trip and the iframe\n// postMessage handshake break silently.\n\n/**\n * Default base URL of the hosted WaaS upgrade app. Both upgrade paths point at\n * this origin and append `environmentId` + `redirectUrl` query params. Callers\n * can override it (e.g. to target a local or preview build during QA) via the\n * `baseUrl` option on the public functions.\n */\nexport const UPGRADE_APP_BASE_URL =\n 'https://waas-migration-dynamic-xyz.vercel.app';\n\n/**\n * Query param the upgrade app requires: which Dynamic environment to\n * authenticate the user against. Derived from the Dynamic client so callers\n * never pass it explicitly.\n */\nexport const UPGRADE_ENVIRONMENT_ID_PARAM = 'environmentId';\n\n/**\n * Query param the upgrade app requires: where to send the user (redirect flow)\n * or which origin it postMessages to (iframe flow) once the upgrade finishes.\n * The upgrade app rejects anything that is not an absolute https URL.\n */\nexport const UPGRADE_REDIRECT_URL_PARAM = 'redirectUrl';\n\n/**\n * postMessage `type` the upgrade app emits to its iframe parent on completion.\n */\nexport const UPGRADE_COMPLETE_MESSAGE_TYPE = 'dynamic-waas-migration:complete';\n\n/**\n * Query param the upgrade app appends to `redirectUrl` when it runs top-level\n * (redirect flow), carrying the outcome back to the app after navigation.\n */\nexport const UPGRADE_STATUS_PARAM = 'dynamicWaasMigrationStatus';\n\n/** Outcome value the upgrade app reports when the upgrade succeeded. */\nexport const UPGRADE_STATUS_SUCCESS = 'success';\n\n/** Outcome value the upgrade app reports when the upgrade failed. */\nexport const UPGRADE_STATUS_ERROR = 'error';\n\n/**\n * The outcome of a legacy embedded wallet upgrade attempt: `success` when the\n * wallet was upgraded to Dynamic WaaS, `error` when it failed. These are the\n * only two values the upgrade app ever reports, on both the redirect and the\n * iframe paths.\n *\n * @example\n * ```ts\n * const isSuccess = (status: WalletUpgradeStatus) => status === 'success';\n * ```\n * @see WalletUpgradeOutcome\n * @see consumeUpgradeRedirect\n */\nexport type WalletUpgradeStatus =\n | typeof UPGRADE_STATUS_SUCCESS\n | typeof UPGRADE_STATUS_ERROR;\n\n/**\n * The resolved result of an upgrade flow, carrying the reported\n * {@link WalletUpgradeStatus}. Returned by the redirect-result consumer and\n * handed to the iframe completion callback so callers can react (toast,\n * refetch, close a sheet, etc.).\n *\n * @example\n * ```ts\n * const onComplete = (outcome: WalletUpgradeOutcome) => {\n * if (outcome.status === 'success') showSuccessToast();\n * };\n * ```\n * @see WalletUpgradeStatus\n * @see subscribeToUpgradeCompletion\n */\nexport type WalletUpgradeOutcome = {\n status: WalletUpgradeStatus;\n};\n\n/**\n * Shape of the completion message the upgrade app posts to its parent window\n * in the iframe flow. Internal to the message handshake — consumers receive the\n * parsed {@link WalletUpgradeOutcome} instead.\n */\nexport type UpgradeCompleteMessage = {\n status: WalletUpgradeStatus;\n type: typeof UPGRADE_COMPLETE_MESSAGE_TYPE;\n};\n","/* eslint-disable no-restricted-globals */\n\nimport {\n UnavailableInServerSideError,\n getDefaultClient,\n} from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\nimport { InvalidUpgradeBaseUrlError } from '../errors/InvalidUpgradeBaseUrlError';\nimport { InvalidUpgradeRedirectUrlError } from '../errors/InvalidUpgradeRedirectUrlError';\nimport {\n UPGRADE_APP_BASE_URL,\n UPGRADE_ENVIRONMENT_ID_PARAM,\n UPGRADE_REDIRECT_URL_PARAM,\n} from '../upgradeAppContract';\n\nconst HTTPS_PROTOCOL = 'https:';\n\ntype BuildUpgradeUrlParams = {\n /**\n * Base URL of the hosted upgrade app. Defaults to the production upgrade app;\n * override it to target a local or preview build (e.g. during QA).\n */\n baseUrl?: string;\n /**\n * Absolute https URL the upgrade app returns to (redirect flow) or\n * postMessages (iframe flow) on completion. Defaults to the current page\n * (`window.location.href`). The upgrade app rejects any non-https URL.\n */\n redirectUrl?: string;\n};\n\n/**\n * Builds the URL that drives the hosted upgrade app for the client's Dynamic\n * environment and a return target.\n *\n * This is the low-level primitive behind every upgrade path: the redirect flow\n * navigates the top-level window to it, the iframe flow loads it as the iframe\n * `src`, and a React Native WebView can load it directly. The environment id is\n * read from the client, and `redirectUrl` defaults to the current page, so the\n * common call is zero-arg. Prefer {@link startUpgradeRedirect} or\n * {@link openUpgradeIframe} unless you are mounting the upgrade app yourself.\n *\n * @example\n * ```ts\n * const src = buildUpgradeUrl();\n * // or target a local upgrade app during QA:\n * const localSrc = buildUpgradeUrl({ baseUrl: 'https://localhost:3000' });\n * ```\n * @param [params] - Options for the generated URL.\n * @param [params.redirectUrl] - Absolute https return URL; defaults to `window.location.href`.\n * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns The fully-qualified upgrade app URL to load.\n * @throws {InvalidUpgradeRedirectUrlError} When `redirectUrl` is not an absolute https URL.\n * @throws {InvalidUpgradeBaseUrlError} When `baseUrl` is not an absolute https URL.\n * @throws {UnavailableInServerSideError} When called during SSR without an explicit `redirectUrl`.\n * @see startUpgradeRedirect\n * @see openUpgradeIframe\n */\nexport const buildUpgradeUrl = (\n { redirectUrl, baseUrl = UPGRADE_APP_BASE_URL }: BuildUpgradeUrlParams = {},\n client = getDefaultClient()\n): string => {\n // The default return target is the current page, which only exists in the\n // browser; fail loudly during SSR rather than dereferencing an absent window.\n if (redirectUrl === undefined && typeof window === 'undefined') {\n throw new UnavailableInServerSideError('buildUpgradeUrl');\n }\n\n const resolvedRedirectUrl = redirectUrl ?? window.location.href;\n\n // Validate the return target up front: the upgrade app only accepts an\n // absolute https URL, so reject anything else (relative, http, other schemes)\n // here rather than letting it be silently refused after navigation. `new URL`\n // throws on non-absolute input, so the explicit check only guards the scheme.\n const parsedRedirectUrl = new URL(resolvedRedirectUrl);\n\n if (parsedRedirectUrl.protocol !== HTTPS_PROTOCOL) {\n throw new InvalidUpgradeRedirectUrlError(resolvedRedirectUrl);\n }\n\n // Validate the upgrade app origin before we ever load it in an iframe or\n // navigate to it. The default is a trusted https app, but `baseUrl` is an\n // override (custom deployments, forks, local QA), so enforce the https scheme\n // to reject non-secure or dangerous schemes (`http:`, `javascript:`, `data:`)\n // rather than mounting an untrusted origin. Any https host is allowed on\n // purpose — customers self-host the upgrade app on their own domains.\n const url = new URL(baseUrl);\n\n if (url.protocol !== HTTPS_PROTOCOL) {\n throw new InvalidUpgradeBaseUrlError(baseUrl);\n }\n\n const { environmentId } = getCore(client);\n\n url.searchParams.set(UPGRADE_ENVIRONMENT_ID_PARAM, environmentId);\n url.searchParams.set(UPGRADE_REDIRECT_URL_PARAM, resolvedRedirectUrl);\n\n return url.toString();\n};\n","import type { WalletAccount } from '@dynamic-labs-sdk/client';\n\n/**\n * Provider-key substring shared by every Dynamic embedded wallet that predates\n * Dynamic WaaS and can therefore be upgraded to it. A wallet account's\n * `walletProviderKey` is a composite backend value (e.g. `<provider>evm` /\n * `<provider>hdsolana` suffixed with `:embeddedWallet`); both the standard and\n * HD variants contain this marker, so matching it as a substring identifies all\n * of them. This is an opaque backend value, matched verbatim — not a user-facing\n * concept.\n */\nconst LEGACY_EMBEDDED_WALLET_PROVIDER_KEY = 'turnkey';\n\n/**\n * Returns whether a wallet account is a legacy Dynamic embedded wallet that\n * requires an upgrade to Dynamic WaaS.\n *\n * Shared predicate behind both the imperative {@link getWalletsRequiringUpgrade}\n * getter and the reactive `useWalletsRequiringUpgrade` hook, so the definition\n * of \"requires upgrade\" lives in exactly one place.\n *\n * @example\n * ```ts\n * const upgradeable = walletAccounts.filter(walletAccountRequiresUpgrade);\n * ```\n * @param walletAccount - The wallet account to test.\n * @returns True when the account is a legacy embedded wallet requiring an upgrade.\n * @see getWalletsRequiringUpgrade\n * @see hasWalletsRequiringUpgrade\n */\nexport const walletAccountRequiresUpgrade = (\n walletAccount: WalletAccount\n): boolean =>\n walletAccount.walletProviderKey.includes(\n LEGACY_EMBEDDED_WALLET_PROVIDER_KEY\n );\n","import {\n type WalletAccount,\n getDefaultClient,\n getWalletAccounts,\n} from '@dynamic-labs-sdk/client';\n\nimport { walletAccountRequiresUpgrade } from '../walletAccountRequiresUpgrade';\n\n/**\n * Returns the current session's wallet accounts that are legacy Dynamic\n * embedded wallets requiring an upgrade to Dynamic WaaS.\n *\n * These are earlier-generation Dynamic embedded wallets that predate Dynamic\n * WaaS (the current TSS-MPC embedded wallet) and can be upgraded to it. Use this\n * when you need the accounts themselves — for example to render only the\n * upgrade entry points on those wallets. Already-upgraded Dynamic WaaS accounts\n * are never returned. For a simple boolean check, use\n * {@link hasWalletsRequiringUpgrade}.\n *\n * @example\n * ```ts\n * const walletsRequiringUpgrade = getWalletsRequiringUpgrade();\n * if (walletsRequiringUpgrade.length > 0) {\n * promptUpgrade(walletsRequiringUpgrade);\n * }\n * ```\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns The wallet accounts requiring an upgrade to Dynamic WaaS (empty when none).\n * @see hasWalletsRequiringUpgrade\n * @see startUpgradeRedirect\n */\nexport const getWalletsRequiringUpgrade = (\n client = getDefaultClient()\n): WalletAccount[] =>\n getWalletAccounts(client).filter(walletAccountRequiresUpgrade);\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\n\nimport { getWalletsRequiringUpgrade } from '../getWalletsRequiringUpgrade';\n\n/**\n * Returns whether the current session has any legacy Dynamic embedded wallet\n * that requires an upgrade to Dynamic WaaS.\n *\n * A boolean convenience over {@link getWalletsRequiringUpgrade} for the common\n * case where you only need to decide whether to surface the upgrade flow (e.g.\n * show a banner or gate a wallet's actions) rather than act on the specific\n * accounts.\n *\n * @example\n * ```ts\n * if (hasWalletsRequiringUpgrade()) {\n * showUpgradeToWaasBanner();\n * }\n * ```\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True when at least one wallet account requires an upgrade to Dynamic WaaS, false otherwise.\n * @see getWalletsRequiringUpgrade\n * @see startUpgradeRedirect\n */\nexport const hasWalletsRequiringUpgrade = (\n client = getDefaultClient()\n): boolean => getWalletsRequiringUpgrade(client).length > 0;\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\n\nassertPackageVersion(packageName, packageVersion);\n\nexport { buildUpgradeUrl } from '../buildUpgradeUrl';\nexport { getWalletsRequiringUpgrade } from '../getWalletsRequiringUpgrade';\nexport { hasWalletsRequiringUpgrade } from '../hasWalletsRequiringUpgrade';\n"],"mappings":";;;;;;;;;;ACEA,IAAa,6BAAb,cAAgDA,mCAAU;CAExD,YAAY,SAAiB;AAC3B,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cAAc,4DAA4D;GAC3E,CAAC;;;;;;ACTN,IAAa,iCAAb,cAAoDC,mCAAU;CAE5D,YAAY,aAAqB;AAC/B,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cAAc,gEAAgE;GAC/E,CAAC;;;;;;;;;;;;ACCN,MAAa,uBACX;;;;;;AAOF,MAAa,+BAA+B;;;;;;AAO5C,MAAa,6BAA6B;;;;ACX1C,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CvB,MAAa,mBACX,EAAE,aAAa,UAAU,yBAAgD,EAAE,EAC3E,yDAA2B,KAChB;AAGX,KAAI,gBAAgB,UAAa,OAAO,WAAW,YACjD,OAAM,IAAIC,sDAA6B,kBAAkB;CAG3D,MAAM,sBAAsB,eAAe,OAAO,SAAS;AAQ3D,KAF0B,IAAI,IAAI,oBAAoB,CAEhC,aAAa,eACjC,OAAM,IAAI,+BAA+B,oBAAoB;CAS/D,MAAM,MAAM,IAAI,IAAI,QAAQ;AAE5B,KAAI,IAAI,aAAa,eACnB,OAAM,IAAI,2BAA2B,QAAQ;CAG/C,MAAM,EAAE,6DAA0B,OAAO;AAEzC,KAAI,aAAa,IAAI,8BAA8B,cAAc;AACjE,KAAI,aAAa,IAAI,4BAA4B,oBAAoB;AAErE,QAAO,IAAI,UAAU;;;;;;;;;;;;;;ACxFvB,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;AAmB5C,MAAa,gCACX,kBAEA,cAAc,kBAAkB,SAC9B,oCACD;;;;;;;;;;;;;;;;;;;;;;;;;;;ACJH,MAAa,8BACX,yDAA2B,qDAET,OAAO,CAAC,OAAO,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;ACVhE,MAAa,8BACX,yDAA2B,KACf,2BAA2B,OAAO,CAAC,SAAS;;;;mECnBrCC,MAAaC,QAAe"}
1
+ {"version":3,"file":"index.cjs","names":["getWalletsRequiringUpgrade","buildUpgradeUrl","BaseError","buildUpgradeUrl","resolveCompleted: ((outcome: WalletUpgradeOutcome) => void) | undefined","rejectCompleted: ((reason: UpgradeIframeClosedError) => void) | undefined","subscribeToUpgradeCompletion","packageName","packageVersion"],"sources":["../src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts","../src/startUpgradeRedirect/startUpgradeRedirect.ts","../src/errors/UpgradeIframeClosedError.ts","../src/openUpgradeIframe/openUpgradeIframe.ts","../src/exports/index.ts"],"sourcesContent":["import { getDefaultClient } from '@dynamic-labs-sdk/client';\n\nimport { getWalletsRequiringUpgrade } from '../getWalletsRequiringUpgrade';\n\n/**\n * Returns whether the current session has any legacy Dynamic embedded wallet\n * that requires an upgrade to Dynamic WaaS.\n *\n * A boolean convenience over {@link getWalletsRequiringUpgrade} for the common\n * case where you only need to decide whether to surface the upgrade flow (e.g.\n * show a banner or gate a wallet's actions) rather than act on the specific\n * accounts.\n *\n * @example\n * ```ts\n * if (hasWalletsRequiringUpgrade()) {\n * showUpgradeToWaasBanner();\n * }\n * ```\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns True when at least one wallet account requires an upgrade to Dynamic WaaS, false otherwise.\n * @see getWalletsRequiringUpgrade\n * @see startUpgradeRedirect\n */\nexport const hasWalletsRequiringUpgrade = (\n client = getDefaultClient()\n): boolean => getWalletsRequiringUpgrade(client).length > 0;\n","import { getDefaultClient } from '@dynamic-labs-sdk/client';\nimport { getCore } from '@dynamic-labs-sdk/client/core';\n\nimport { buildUpgradeUrl } from '../buildUpgradeUrl';\n\ntype StartUpgradeRedirectParams = {\n /**\n * Base URL of the hosted upgrade app. Defaults to the production upgrade app;\n * override it to target a local or preview build (e.g. during QA).\n */\n baseUrl?: string;\n /**\n * Absolute https URL the upgrade app returns to on completion. Defaults to\n * the current page (`window.location.href`), so the outcome can be picked up\n * by {@link consumeUpgradeRedirect} when the user lands back.\n */\n redirectUrl?: string;\n};\n\n/**\n * Starts the redirect upgrade path by navigating the top-level window to the\n * hosted upgrade app.\n *\n * Call this from an \"Upgrade\" button. The upgrade app runs full-page and, once\n * finished, returns the user to `redirectUrl` with the outcome encoded in the\n * URL — call {@link consumeUpgradeRedirect} on load to pick it up. The\n * environment id and return URL are derived from the client and current page,\n * so the common call is zero-arg.\n *\n * @example\n * ```ts\n * // on the \"Upgrade via redirect\" button\n * await startUpgradeRedirect();\n * ```\n * @param [params] - Options for the redirect.\n * @param [params.redirectUrl] - Absolute https return URL; defaults to `window.location.href`.\n * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns A promise that resolves once navigation has been initiated.\n * @see consumeUpgradeRedirect\n * @see buildUpgradeUrl\n */\nexport const startUpgradeRedirect = async (\n params: StartUpgradeRedirectParams = {},\n client = getDefaultClient()\n): Promise<void> =>\n getCore(client).navigate(buildUpgradeUrl(params, client));\n","import { BaseError } from '@dynamic-labs-sdk/client';\n\nexport class UpgradeIframeClosedError extends BaseError {\n constructor() {\n super({\n cause: null,\n code: 'upgrade_iframe_closed_error',\n docsUrl: null,\n name: 'UpgradeIframeClosedError',\n shortMessage: 'Upgrade iframe was closed before the upgrade completed',\n });\n }\n}\n","/* eslint-disable no-restricted-globals */\n\nimport { getDefaultClient } from '@dynamic-labs-sdk/client';\n\nimport { buildUpgradeUrl } from '../buildUpgradeUrl';\nimport { UpgradeIframeClosedError } from '../errors/UpgradeIframeClosedError';\nimport { subscribeToUpgradeCompletion } from '../subscribeToUpgradeCompletion';\nimport type { WalletUpgradeOutcome } from '../upgradeAppContract';\nimport type {\n OpenUpgradeIframeParams,\n UpgradeIframeSession,\n} from './openUpgradeIframe.types';\n\nexport type { UpgradeIframeSession } from './openUpgradeIframe.types';\n\n// Permissions the upgrade app needs inside the iframe: clipboard writes plus\n// passkey (WebAuthn) get/create, which the embedded wallet upgrade relies on.\nconst UPGRADE_IFRAME_ALLOW =\n 'clipboard-write; publickey-credentials-get *; publickey-credentials-create *';\n\nconst UPGRADE_IFRAME_TITLE = 'Dynamic embedded wallet upgrade';\n\n/**\n * Runs the embedded upgrade path by mounting the hosted upgrade app in an\n * iframe inside a container you provide.\n *\n * The package renders no UI of its own: pass the element of your modal/sheet\n * and it appends the iframe, wires the origin-checked completion handshake, and\n * refreshes the session on success. `completed` resolves with the outcome once\n * the app reports back; call `close()` when the user dismisses the surface (or\n * after completion) to remove the iframe and detach the listener. Closing\n * before completion rejects `completed` with {@link UpgradeIframeClosedError}\n * so awaiters don't hang — wrap `await session.completed` in try/catch if you\n * allow early dismissal. For React Native or custom mounts, use\n * {@link subscribeToUpgradeCompletion} with {@link buildUpgradeUrl} instead.\n *\n * @example\n * ```ts\n * const session = openUpgradeIframe({ container: sheetBodyEl });\n * const { status } = await session.completed;\n * session.close();\n * ```\n * @param params - Iframe options.\n * @param params.container - Element the upgrade iframe is appended into.\n * @param [params.redirectUrl] - Absolute https completion URL; defaults to `window.location.href`.\n * @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.\n * @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.\n * @returns A session handle exposing the `iframe`, a `close` function, and the `completed` promise.\n * @see subscribeToUpgradeCompletion\n * @see buildUpgradeUrl\n */\nexport const openUpgradeIframe = (\n { container, redirectUrl, baseUrl }: OpenUpgradeIframeParams,\n client = getDefaultClient()\n): UpgradeIframeSession => {\n const iframe = document.createElement('iframe');\n iframe.src = buildUpgradeUrl({ baseUrl, redirectUrl }, client);\n iframe.title = UPGRADE_IFRAME_TITLE;\n iframe.setAttribute('allow', UPGRADE_IFRAME_ALLOW);\n\n container.appendChild(iframe);\n\n // Executor runs synchronously, so both settlers are assigned before the\n // subscription below (or `close`) can ever fire.\n let resolveCompleted: ((outcome: WalletUpgradeOutcome) => void) | undefined;\n let rejectCompleted: ((reason: UpgradeIframeClosedError) => void) | undefined;\n const completed = new Promise<WalletUpgradeOutcome>((resolve, reject) => {\n resolveCompleted = resolve;\n rejectCompleted = reject;\n });\n\n // Callers may use `close()` purely for teardown and never await `completed`.\n // Attach a no-op catch so an early-close rejection is treated as handled\n // globally (no unhandled-rejection noise); a caller that does await\n // `completed` still receives the rejection in its own context.\n completed.catch(() => undefined);\n\n // Set the instant a valid completion message arrives — before the async\n // session refresh resolves `completed` via `onComplete`. `close()` checks\n // this so dismissing the surface during that refresh window does not reject a\n // promise for an upgrade that already succeeded.\n let hasReceivedCompletion = false;\n\n const unsubscribe = subscribeToUpgradeCompletion(\n {\n baseUrl,\n onComplete: (outcome) => resolveCompleted?.(outcome),\n onReceived: () => {\n hasReceivedCompletion = true;\n },\n },\n client\n );\n\n const close = () => {\n unsubscribe();\n iframe.remove();\n // Reject `completed` only as a genuine cancellation — i.e. no completion\n // has been received yet — so anything awaiting it doesn't hang forever. If\n // a completion already arrived, `onComplete` (after the refresh) resolves\n // `completed` with the real outcome, so we must not reject here.\n if (!hasReceivedCompletion) {\n rejectCompleted?.(new UpgradeIframeClosedError());\n }\n };\n\n return { close, completed, iframe };\n};\n","import { assertPackageVersion } from '@dynamic-labs-sdk/assert-package-version';\n\nimport {\n name as packageName,\n version as packageVersion,\n} from '../../package.json';\n\nassertPackageVersion(packageName, packageVersion);\n\nexport { buildUpgradeUrl } from '../buildUpgradeUrl';\nexport { getWalletsRequiringUpgrade } from '../getWalletsRequiringUpgrade';\nexport { hasWalletsRequiringUpgrade } from '../hasWalletsRequiringUpgrade';\nexport { startUpgradeRedirect } from '../startUpgradeRedirect';\nexport {\n consumeUpgradeRedirect,\n type ConsumeUpgradeRedirectParams,\n} from '../consumeUpgradeRedirect';\nexport { subscribeToUpgradeCompletion } from '../subscribeToUpgradeCompletion';\nexport { openUpgradeIframe } from '../openUpgradeIframe';\nexport type { UpgradeIframeSession } from '../openUpgradeIframe';\nexport type {\n WalletUpgradeOutcome,\n WalletUpgradeStatus,\n} from '../upgradeAppContract';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,8BACX,yDAA2B,KACfA,gEAA2B,OAAO,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;ACgB1D,MAAa,uBAAuB,OAClC,SAAqC,EAAE,EACvC,yDAA2B,gDAEnB,OAAO,CAAC,SAASC,qDAAgB,QAAQ,OAAO,CAAC;;;;AC5C3D,IAAa,2BAAb,cAA8CC,mCAAU;CACtD,cAAc;AACZ,QAAM;GACJ,OAAO;GACP,MAAM;GACN,SAAS;GACT,MAAM;GACN,cAAc;GACf,CAAC;;;;;;ACON,MAAM,uBACJ;AAEF,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+B7B,MAAa,qBACX,EAAE,WAAW,aAAa,WAC1B,yDAA2B,KACF;CACzB,MAAM,SAAS,SAAS,cAAc,SAAS;AAC/C,QAAO,MAAMC,qDAAgB;EAAE;EAAS;EAAa,EAAE,OAAO;AAC9D,QAAO,QAAQ;AACf,QAAO,aAAa,SAAS,qBAAqB;AAElD,WAAU,YAAY,OAAO;CAI7B,IAAIC;CACJ,IAAIC;CACJ,MAAM,YAAY,IAAI,SAA+B,SAAS,WAAW;AACvE,qBAAmB;AACnB,oBAAkB;GAClB;AAMF,WAAU,YAAY,OAAU;CAMhC,IAAI,wBAAwB;CAE5B,MAAM,cAAcC,kEAClB;EACE;EACA,aAAa,YAAY,mBAAmB,QAAQ;EACpD,kBAAkB;AAChB,2BAAwB;;EAE3B,EACD,OACD;CAED,MAAM,cAAc;AAClB,eAAa;AACb,SAAO,QAAQ;AAKf,MAAI,CAAC,sBACH,mBAAkB,IAAI,0BAA0B,CAAC;;AAIrD,QAAO;EAAE;EAAO;EAAW;EAAQ;;;;;mECnGhBC,2CAAaC,6CAAe"}