@dynamic-labs-sdk/legacy-embedded-wallet-upgrade 0.0.0 → 1.21.2
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.
- package/README.md +103 -0
- package/dist/buildUpgradeUrl/buildUpgradeUrl.d.ts +44 -0
- package/dist/buildUpgradeUrl/buildUpgradeUrl.d.ts.map +1 -0
- package/dist/buildUpgradeUrl/index.d.ts +2 -0
- package/dist/buildUpgradeUrl/index.d.ts.map +1 -0
- package/dist/errors/InvalidUpgradeBaseUrlError.d.ts +5 -0
- package/dist/errors/InvalidUpgradeBaseUrlError.d.ts.map +1 -0
- package/dist/errors/InvalidUpgradeRedirectUrlError.d.ts +5 -0
- package/dist/errors/InvalidUpgradeRedirectUrlError.d.ts.map +1 -0
- package/dist/exports/index.d.ts +4 -0
- package/dist/exports/index.d.ts.map +1 -0
- package/dist/getWalletsRequiringUpgrade/getWalletsRequiringUpgrade.d.ts +26 -0
- package/dist/getWalletsRequiringUpgrade/getWalletsRequiringUpgrade.d.ts.map +1 -0
- package/dist/getWalletsRequiringUpgrade/index.d.ts +2 -0
- package/dist/getWalletsRequiringUpgrade/index.d.ts.map +1 -0
- package/dist/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.d.ts +22 -0
- package/dist/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.d.ts.map +1 -0
- package/dist/hasWalletsRequiringUpgrade/index.d.ts +2 -0
- package/dist/hasWalletsRequiringUpgrade/index.d.ts.map +1 -0
- package/dist/index.cjs +192 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.esm.js +190 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/upgradeAppContract.d.ts +74 -0
- package/dist/upgradeAppContract.d.ts.map +1 -0
- package/dist/walletAccountRequiresUpgrade/index.d.ts +2 -0
- package/dist/walletAccountRequiresUpgrade/index.d.ts.map +1 -0
- package/dist/walletAccountRequiresUpgrade/walletAccountRequiresUpgrade.d.ts +20 -0
- package/dist/walletAccountRequiresUpgrade/walletAccountRequiresUpgrade.d.ts.map +1 -0
- package/package.json +38 -1
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @dynamic-labs-sdk/legacy-embedded-wallet-upgrade
|
|
2
|
+
|
|
3
|
+
Helpers to upgrade a user's legacy Dynamic embedded wallets to Dynamic WaaS. Wraps the URL contract, the redirect round-trip, the iframe/WebView completion handshake, and the session refresh behind a small set of functions, so you only call functions — you never assemble the flow yourself.
|
|
4
|
+
|
|
5
|
+
The core entry point is framework-agnostic (no React). React hooks live in a separate `/react` subpath so non-React consumers never load them.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @dynamic-labs-sdk/legacy-embedded-wallet-upgrade @dynamic-labs-sdk/client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Detecting wallets that require an upgrade
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import {
|
|
17
|
+
getWalletsRequiringUpgrade,
|
|
18
|
+
hasWalletsRequiringUpgrade,
|
|
19
|
+
} from '@dynamic-labs-sdk/legacy-embedded-wallet-upgrade';
|
|
20
|
+
|
|
21
|
+
if (hasWalletsRequiringUpgrade()) {
|
|
22
|
+
const wallets = getWalletsRequiringUpgrade();
|
|
23
|
+
// show an upgrade entry point for these wallets
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Redirect path
|
|
28
|
+
|
|
29
|
+
Navigate the top-level window to the hosted upgrade app, then consume the result when it returns. The environment id is read from the client and the return URL defaults to the current page, so both calls are zero-arg.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import {
|
|
33
|
+
startUpgradeRedirect,
|
|
34
|
+
consumeUpgradeRedirect,
|
|
35
|
+
} from '@dynamic-labs-sdk/legacy-embedded-wallet-upgrade';
|
|
36
|
+
|
|
37
|
+
// on the "Upgrade via redirect" button
|
|
38
|
+
startUpgradeRedirect();
|
|
39
|
+
|
|
40
|
+
// once, on app load — reads and strips the status param, refreshes the
|
|
41
|
+
// session on success, and returns the outcome (null if we didn't just return)
|
|
42
|
+
const result = await consumeUpgradeRedirect();
|
|
43
|
+
if (result?.status === 'error') {
|
|
44
|
+
showErrorToast();
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Iframe path
|
|
49
|
+
|
|
50
|
+
The package renders no UI of its own — you own the container (e.g. a bottom sheet). `openUpgradeIframe` appends the iframe into your container, listens for the origin-checked completion message, refreshes the session on success, and resolves.
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { openUpgradeIframe } from '@dynamic-labs-sdk/legacy-embedded-wallet-upgrade';
|
|
54
|
+
|
|
55
|
+
const session = openUpgradeIframe({ container: sheetBodyElement });
|
|
56
|
+
const { status } = await session.completed;
|
|
57
|
+
closeSheet();
|
|
58
|
+
|
|
59
|
+
// if the user dismisses the sheet first:
|
|
60
|
+
session.close();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### React Native / custom mounts
|
|
64
|
+
|
|
65
|
+
Use the DOM-agnostic primitives when you mount the upgrade app yourself (e.g. a React Native `WebView`):
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import {
|
|
69
|
+
buildUpgradeUrl,
|
|
70
|
+
subscribeToUpgradeCompletion,
|
|
71
|
+
} from '@dynamic-labs-sdk/legacy-embedded-wallet-upgrade';
|
|
72
|
+
|
|
73
|
+
const src = buildUpgradeUrl();
|
|
74
|
+
const unsubscribe = subscribeToUpgradeCompletion({
|
|
75
|
+
onComplete: ({ status }) => handleOutcome(status),
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## React
|
|
80
|
+
|
|
81
|
+
React hooks are exported from the `/react` subpath, with `react` as an optional peer dependency:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import {
|
|
85
|
+
useWalletsRequiringUpgrade,
|
|
86
|
+
useHasWalletsRequiringUpgrade,
|
|
87
|
+
useUpgradeRedirectResult,
|
|
88
|
+
useUpgradeIframe,
|
|
89
|
+
} from '@dynamic-labs-sdk/legacy-embedded-wallet-upgrade/react';
|
|
90
|
+
|
|
91
|
+
const needsUpgrade = useHasWalletsRequiringUpgrade();
|
|
92
|
+
|
|
93
|
+
useUpgradeRedirectResult({ onComplete: ({ status }) => handleOutcome(status) });
|
|
94
|
+
|
|
95
|
+
const { upgradeUrl } = useUpgradeIframe({
|
|
96
|
+
active: isSheetOpen,
|
|
97
|
+
onComplete: ({ status }) => closeSheet(status),
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Multiple clients
|
|
102
|
+
|
|
103
|
+
Every function accepts the Dynamic client as an optional second argument and defaults to `getDefaultClient()`; pass it explicitly only when you use more than one client.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
type BuildUpgradeUrlParams = {
|
|
2
|
+
/**
|
|
3
|
+
* Base URL of the hosted upgrade app. Defaults to the production upgrade app;
|
|
4
|
+
* override it to target a local or preview build (e.g. during QA).
|
|
5
|
+
*/
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Absolute https URL the upgrade app returns to (redirect flow) or
|
|
9
|
+
* postMessages (iframe flow) on completion. Defaults to the current page
|
|
10
|
+
* (`window.location.href`). The upgrade app rejects any non-https URL.
|
|
11
|
+
*/
|
|
12
|
+
redirectUrl?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Builds the URL that drives the hosted upgrade app for the client's Dynamic
|
|
16
|
+
* environment and a return target.
|
|
17
|
+
*
|
|
18
|
+
* This is the low-level primitive behind every upgrade path: the redirect flow
|
|
19
|
+
* navigates the top-level window to it, the iframe flow loads it as the iframe
|
|
20
|
+
* `src`, and a React Native WebView can load it directly. The environment id is
|
|
21
|
+
* read from the client, and `redirectUrl` defaults to the current page, so the
|
|
22
|
+
* common call is zero-arg. Prefer {@link startUpgradeRedirect} or
|
|
23
|
+
* {@link openUpgradeIframe} unless you are mounting the upgrade app yourself.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const src = buildUpgradeUrl();
|
|
28
|
+
* // or target a local upgrade app during QA:
|
|
29
|
+
* const localSrc = buildUpgradeUrl({ baseUrl: 'https://localhost:3000' });
|
|
30
|
+
* ```
|
|
31
|
+
* @param [params] - Options for the generated URL.
|
|
32
|
+
* @param [params.redirectUrl] - Absolute https return URL; defaults to `window.location.href`.
|
|
33
|
+
* @param [params.baseUrl] - Upgrade app base URL; defaults to the production app.
|
|
34
|
+
* @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
|
|
35
|
+
* @returns The fully-qualified upgrade app URL to load.
|
|
36
|
+
* @throws {InvalidUpgradeRedirectUrlError} When `redirectUrl` is not an absolute https URL.
|
|
37
|
+
* @throws {InvalidUpgradeBaseUrlError} When `baseUrl` is not an absolute https URL.
|
|
38
|
+
* @throws {UnavailableInServerSideError} When called during SSR without an explicit `redirectUrl`.
|
|
39
|
+
* @see startUpgradeRedirect
|
|
40
|
+
* @see openUpgradeIframe
|
|
41
|
+
*/
|
|
42
|
+
export declare const buildUpgradeUrl: ({ redirectUrl, baseUrl }?: BuildUpgradeUrlParams, client?: import("@dynamic-labs-sdk/client").DynamicClient) => string;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=buildUpgradeUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildUpgradeUrl.d.ts","sourceRoot":"","sources":["../../src/buildUpgradeUrl/buildUpgradeUrl.ts"],"names":[],"mappings":"AAkBA,KAAK,qBAAqB,GAAG;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,eAAe,8BACuB,qBAAqB,gEAErE,MAqCF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/buildUpgradeUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvalidUpgradeBaseUrlError.d.ts","sourceRoot":"","sources":["../../src/errors/InvalidUpgradeBaseUrlError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,0BAA2B,SAAQ,SAAS;gBAE3C,OAAO,EAAE,MAAM;CAS5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvalidUpgradeRedirectUrlError.d.ts","sourceRoot":"","sources":["../../src/errors/InvalidUpgradeRedirectUrlError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,qBAAa,8BAA+B,SAAQ,SAAS;gBAE/C,WAAW,EAAE,MAAM;CAShC"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type WalletAccount } from '@dynamic-labs-sdk/client';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the current session's wallet accounts that are legacy Dynamic
|
|
4
|
+
* embedded wallets requiring an upgrade to Dynamic WaaS.
|
|
5
|
+
*
|
|
6
|
+
* These are earlier-generation Dynamic embedded wallets that predate Dynamic
|
|
7
|
+
* WaaS (the current TSS-MPC embedded wallet) and can be upgraded to it. Use this
|
|
8
|
+
* when you need the accounts themselves — for example to render only the
|
|
9
|
+
* upgrade entry points on those wallets. Already-upgraded Dynamic WaaS accounts
|
|
10
|
+
* are never returned. For a simple boolean check, use
|
|
11
|
+
* {@link hasWalletsRequiringUpgrade}.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const walletsRequiringUpgrade = getWalletsRequiringUpgrade();
|
|
16
|
+
* if (walletsRequiringUpgrade.length > 0) {
|
|
17
|
+
* promptUpgrade(walletsRequiringUpgrade);
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
* @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
|
|
21
|
+
* @returns The wallet accounts requiring an upgrade to Dynamic WaaS (empty when none).
|
|
22
|
+
* @see hasWalletsRequiringUpgrade
|
|
23
|
+
* @see startUpgradeRedirect
|
|
24
|
+
*/
|
|
25
|
+
export declare const getWalletsRequiringUpgrade: (client?: import("@dynamic-labs-sdk/client").DynamicClient) => WalletAccount[];
|
|
26
|
+
//# sourceMappingURL=getWalletsRequiringUpgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getWalletsRequiringUpgrade.d.ts","sourceRoot":"","sources":["../../src/getWalletsRequiringUpgrade/getWalletsRequiringUpgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAGnB,MAAM,0BAA0B,CAAC;AAIlC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,0BAA0B,iEAEpC,aAAa,EACgD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/getWalletsRequiringUpgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns whether the current session has any legacy Dynamic embedded wallet
|
|
3
|
+
* that requires an upgrade to Dynamic WaaS.
|
|
4
|
+
*
|
|
5
|
+
* A boolean convenience over {@link getWalletsRequiringUpgrade} for the common
|
|
6
|
+
* case where you only need to decide whether to surface the upgrade flow (e.g.
|
|
7
|
+
* show a banner or gate a wallet's actions) rather than act on the specific
|
|
8
|
+
* accounts.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* if (hasWalletsRequiringUpgrade()) {
|
|
13
|
+
* showUpgradeToWaasBanner();
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
* @param [client] - The Dynamic client instance. Only required when using multiple Dynamic clients.
|
|
17
|
+
* @returns True when at least one wallet account requires an upgrade to Dynamic WaaS, false otherwise.
|
|
18
|
+
* @see getWalletsRequiringUpgrade
|
|
19
|
+
* @see startUpgradeRedirect
|
|
20
|
+
*/
|
|
21
|
+
export declare const hasWalletsRequiringUpgrade: (client?: import("@dynamic-labs-sdk/client").DynamicClient) => boolean;
|
|
22
|
+
//# sourceMappingURL=hasWalletsRequiringUpgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hasWalletsRequiringUpgrade.d.ts","sourceRoot":"","sources":["../../src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,0BAA0B,iEAEpC,OAAwD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hasWalletsRequiringUpgrade/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
let _dynamic_labs_sdk_assert_package_version = require("@dynamic-labs-sdk/assert-package-version");
|
|
2
|
+
let _dynamic_labs_sdk_client = require("@dynamic-labs-sdk/client");
|
|
3
|
+
let _dynamic_labs_sdk_client_core = require("@dynamic-labs-sdk/client/core");
|
|
4
|
+
|
|
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:";
|
|
62
|
+
/**
|
|
63
|
+
* Builds the URL that drives the hosted upgrade app for the client's Dynamic
|
|
64
|
+
* environment and a return target.
|
|
65
|
+
*
|
|
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.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const src = buildUpgradeUrl();
|
|
76
|
+
* // or target a local upgrade app during QA:
|
|
77
|
+
* const localSrc = buildUpgradeUrl({ baseUrl: 'https://localhost:3000' });
|
|
78
|
+
* ```
|
|
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
|
+
* @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`.
|
|
87
|
+
* @see startUpgradeRedirect
|
|
88
|
+
* @see openUpgradeIframe
|
|
89
|
+
*/
|
|
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
|
+
};
|
|
101
|
+
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/walletAccountRequiresUpgrade/walletAccountRequiresUpgrade.ts
|
|
104
|
+
/**
|
|
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.
|
|
117
|
+
*
|
|
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.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const upgradeable = walletAccounts.filter(walletAccountRequiresUpgrade);
|
|
125
|
+
* ```
|
|
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
|
|
130
|
+
*/
|
|
131
|
+
const walletAccountRequiresUpgrade = (walletAccount) => walletAccount.walletProviderKey.includes(LEGACY_EMBEDDED_WALLET_PROVIDER_KEY);
|
|
132
|
+
|
|
133
|
+
//#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);
|
|
159
|
+
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/hasWalletsRequiringUpgrade/hasWalletsRequiringUpgrade.ts
|
|
162
|
+
/**
|
|
163
|
+
* Returns whether the current session has any legacy Dynamic embedded wallet
|
|
164
|
+
* that requires an upgrade to Dynamic WaaS.
|
|
165
|
+
*
|
|
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.
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```ts
|
|
173
|
+
* if (hasWalletsRequiringUpgrade()) {
|
|
174
|
+
* showUpgradeToWaasBanner();
|
|
175
|
+
* }
|
|
176
|
+
* ```
|
|
177
|
+
* @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
|
|
181
|
+
*/
|
|
182
|
+
const hasWalletsRequiringUpgrade = (client = (0, _dynamic_labs_sdk_client.getDefaultClient)()) => getWalletsRequiringUpgrade(client).length > 0;
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/exports/index.ts
|
|
186
|
+
(0, _dynamic_labs_sdk_assert_package_version.assertPackageVersion)(name, version);
|
|
187
|
+
|
|
188
|
+
//#endregion
|
|
189
|
+
exports.buildUpgradeUrl = buildUpgradeUrl;
|
|
190
|
+
exports.getWalletsRequiringUpgrade = getWalletsRequiringUpgrade;
|
|
191
|
+
exports.hasWalletsRequiringUpgrade = hasWalletsRequiringUpgrade;
|
|
192
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +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"}
|