diff --git a/.eslintrc.base.json b/.eslintrc.base.json deleted file mode 100644 index f52734fb..00000000 --- a/.eslintrc.base.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true, - "node": true - }, - "extends": ["plugin:jsx-a11y/recommended", "@lidofinance", "prettier"], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module" - }, - "plugins": ["@typescript-eslint", "react", "react-hooks"], - "rules": { - "@typescript-eslint/require-await": "off", - "react/display-name": "off", - "@typescript-eslint/no-shadow": "off", - "jsx-a11y/no-autofocus": "off", - "jsx-a11y/anchor-is-valid": "off", - "@next/next/no-img-element": "off", - "eslint-plugin-unicorn": "off", - "no-console": ["warn", { "allow": ["warn", "error", "info", "debug"] }], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "ignoreRestSiblings": true, - "argsIgnorePattern": "^_" - } - ], - "promise/param-names": [ - "warn", - { - "resolvePattern": "^_?(resolve)$|^_$", - "rejectPattern": "^_?(reject)$|^_$" - } - ], - "func-style": ["error", "expression"], - "@typescript-eslint/no-misused-promises": [ - "error", - { - "checksVoidReturn": false - } - ], - "import/no-cycle": ["error", { "maxDepth": 1 }], - "unicorn/expiring-todo-comments": "off", - "jest/expect-expect": [ - "error", - { "assertFunctionNames": ["expect", "expect*"] } - ], - "jest/no-standalone-expect": [ - "error", - { - "additionalTestBlockFunctions": [ - "testSpending", - "testSpending.concurrent", - "testSpending.skip", - "testSpending.only", - "testSpending.todo" - ] - } - ], - "react/react-in-jsx-scope": "off" - }, - "settings": { - "react": { - "version": "detect" - } - } -} diff --git a/.github/workflows/demo-deploy.yml b/.github/workflows/demo-deploy.yml index bef7eef0..8339495c 100644 --- a/.github/workflows/demo-deploy.yml +++ b/.github/workflows/demo-deploy.yml @@ -48,7 +48,6 @@ jobs: ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} WALLETCONNECT_PROJECT_ID: ${{ vars.WALLETCONNECT_PROJECT_ID }} RPC_PROVIDER_URL_1: ${{ vars.RPC_PROVIDER_URL_1 }} - RPC_PROVIDER_URL_17000: ${{ vars.RPC_PROVIDER_URL_17000 }} RPC_PROVIDER_URL_560048: ${{ vars.RPC_PROVIDER_URL_560048 }} SUPPORTED_CHAINS: ${{ vars.SUPPORTED_CHAINS }} DEFAULT_CHAIN: ${{ vars.DEFAULT_CHAIN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 8154f832..483e627f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ # Changelog -The actual changelog is located at [`packages/reef-knot/CHANGELOG.md`](packages/reef-knot/CHANGELOG.md). +For the main package, see [`packages/reef-knot/CHANGELOG.md`](packages/reef-knot/CHANGELOG.md). + +The UI packages, wallet adapters, Ledger connector and shared helpers have their own `CHANGELOG.md` files. diff --git a/README.md b/README.md index 8a1c2131..b9085734 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ Web3 Wallets Connection Library ## Documentation - [How to add a wallet](docs/how-to-add-a-wallet.md) -- [Migration guide](docs/migration-guide.md) +- [Migration guide: 0.x → latest](docs/migration-guide-0.x-to-latest.md) +- [Migration guide: 8.x → 9](docs/migration-guide-8.x-to-9.md) --- @@ -20,13 +21,13 @@ Web3 Wallets Connection Library #### Using NPM ```bash -npm install reef-knot +npm install reef-knot @reef-knot/ui-lido-legacy ``` #### Using Yarn ```bash -yarn add reef-knot +yarn add reef-knot @reef-knot/ui-lido-legacy ``` ### Wagmi and Viem @@ -42,12 +43,13 @@ For an example of Reef Knot setup and configuration, check out [this demo app](h To set up Reef Knot, you’ll need the following imports: ```typescript -import { ReefKnotProvider, getDefaultConfig } from 'reef-knot/core-react'; import { - ReefKnotWalletsModal, + ReefKnotProvider, + WalletsListEthereum, + getDefaultConfig, getDefaultWalletsModalConfig, -} from 'reef-knot/connect-wallet-modal'; -import { WalletsListEthereum } from 'reef-knot/wallets'; +} from 'reef-knot'; +import { ReefKnotWalletsModal } from '@reef-knot/ui-lido-legacy'; ``` ### Setting Up Providers @@ -81,7 +83,7 @@ The `getDefaultWalletsModalConfig` function provides default configuration optio - The wallets to display or pin - Links to the terms of service and privacy policy -For more details, refer to the `connect-wallet-modal` package's [README](packages/connect-wallet-modal/README.md) +Providers, headless hooks, configuration types and the default wallet list are exported from `reef-knot`. UI components are exported from `@reef-knot/ui-lido-legacy` or `@reef-knot/ui-lido`. See [headless UI and migration](docs/headless-ui.md). ### WalletsListEthereum @@ -105,29 +107,29 @@ The `walletsShown` prop is an array of wallet IDs. Simply remove the desired wal #### Dark Theme -To enable a dark theme for the Wallet Connection Modal, use the `darkThemeEnabled` prop on the `` component. +The legacy UI skin accepts `darkThemeEnabled`. The Lido App UI skin accepts `theme="light"` or `theme="dark"`. -### Triggering the Wallet Connection Modal +### Starting the Wallet Connection Flow -To open the Wallet Connection Modal, use the `useConnect` hook provided by Reef Knot. +To start eager connection or open the wallet picker, use the `useConnectionFlow` hook provided by Reef Knot. #### Import the Hook ```typescript -import { useConnect } from 'reef-knot/core-react'; +import { useConnectionFlow } from 'reef-knot'; ``` #### Use the Hook -Call the `useConnect` hook to get the `connect` callback: +Call the `useConnectionFlow` hook to get the `startConnection` callback: ```typescript -const { connect } = useConnect(); +const { startConnection } = useConnectionFlow(); ``` -#### How `connect` Works +#### How `startConnection` Works -The `connect` callback determines the current environment (e.g., desktop browser, mobile wallet app, iframe) and behaves accordingly: +The `startConnection` callback determines the current environment (e.g., desktop browser, mobile wallet app, iframe) and behaves accordingly: - If the dApp is opened inside a wallet's dApp browser, it attempts an automatic connection with this specific wallet. - Otherwise, it opens the Wallet Connection Modal for manual wallet selection. @@ -169,16 +171,26 @@ It is a known issue, and we are working on removing the need for such wrapping. ### Initial setup -Install the dependencies, build everything: +Use Node.js 24.11 or later within the 24.x line (or Node.js 26+) and the pinned Yarn 4.17.1 through Corepack. Install the dependencies and build everything: +```bash +yarn install --immutable && yarn build ``` -yarn install & yarn build -``` + +### TypeScript and bundling + +Packages and the separate `playwright-tests/` project use the native TypeScript 7.0.2 compiler (`tsc`). The `@typescript/native` dependency aliases the stable `typescript` package. The `typescript` dependency aliases `@typescript/typescript6`, preserving the TypeScript 6 JS Compiler API for ESLint and Next.js and providing `tsc6` without a binary-name collision. + +The Next.js 12 demo uses `tsc6` for its CLI check and TypeScript 6 for `next build`. Its `ignoreDeprecations: "6.0"` is local: Next.js 12 requires legacy module resolution, and the demo still uses `baseUrl` imports. Packages use `bundler` resolution; Playwright uses `NodeNext` with its existing CommonJS package scope. `types: ["*"]` preserves the global types loaded before TypeScript 6 changed the default. + +tsdown 0.23.1 builds ES2020 ESM with external dependencies and unbundled output. Its built-in `tsgo` generator emits declarations and declaration maps through native TypeScript 7. The compiler path is resolved explicitly from `@typescript/native` because `typescript` supplies the TS 6 API. Declaration-generation failures fail the build; `yarn typecheck` remains the type-error gate. Legacy UI checks map `@lidofinance/lido-ui` to its existing declarations because that dependency's exports omit its types. tslib remains at 2.8.1. + +Validation covered a clean build of all 18 packages, package type/lint/test gates, UI/configuration type checks, the Next.js demo build, watch rebuilding, and Playwright type/lint/test discovery (28 tests; no transactions executed). All 18 declaration entrypoints compile with TypeScript 5.9.3 using both `node10` and `bundler` resolution; the latter needs the same legacy Lido UI type mapping. Declaration maps, default exports, SVG output and UI CSS/assets were checked. The built-in generator preserves public entrypoint exports and default exports. Re-export-only declaration files do not require maps; concrete declarations retain source maps. OKX uses an explicit `rootDir: "src"` to preserve its declaration entrypoint. This development-tool upgrade does not raise the consumer TypeScript minimum (5.9.3). ### Commands - `yarn dev` runs the `dev` script for all apps and packages. - Usually apps are launched using `next dev` and packages are built using rollup with `--watch` flag, which rebuilds the bundle when its source files change on disk. + Usually apps are launched using `next dev` and packages are built using tsdown with `--watch`, which rebuilds the bundle when its source files change on disk. - `yarn build` - Build all apps and packages. - `yarn build-apps` - Build apps only. - `yarn build-packages` - Build packages only. diff --git a/apps/demo-react/.env.example b/apps/demo-react/.env.example index 86650f4b..830a8fc2 100644 --- a/apps/demo-react/.env.example +++ b/apps/demo-react/.env.example @@ -1,10 +1,9 @@ # Public rpc urls RPC_PROVIDER_URL_1=https://rpc.ankr.com/eth -RPC_PROVIDER_URL_17000=https://1rpc.io/holesky RPC_PROVIDER_URL_560048= # supported networks for connecting wallet -SUPPORTED_CHAINS=1,17000,560048 +SUPPORTED_CHAINS=1,560048 # this chain uses when a wallet is not connected DEFAULT_CHAIN=560048 diff --git a/apps/demo-react/.eslintignore b/apps/demo-react/.eslintignore deleted file mode 100644 index 8b036ffa..00000000 --- a/apps/demo-react/.eslintignore +++ /dev/null @@ -1,17 +0,0 @@ -# dependencies -/node_modules -/.pnp - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build -/public - -*.mjs -*.js \ No newline at end of file diff --git a/apps/demo-react/.eslintrc.cjs b/apps/demo-react/.eslintrc.cjs deleted file mode 100644 index 0a4790c3..00000000 --- a/apps/demo-react/.eslintrc.cjs +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.base.json'], - parserOptions: { - project: ['./tsconfig.json'], - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - ecmaVersion: 12, - }, - rules: { - 'import/no-unresolved': 'off', - 'react-hooks/exhaustive-deps': 'error', - }, - // This tells ESLint not to apply the TypeScript type checking to cjs files - overrides: [ - { - files: ['*.cjs', '.eslintrc.cjs'], - parserOptions: { - project: null, - }, - }, - ], -}; diff --git a/apps/demo-react/components/action-item/action-item.tsx b/apps/demo-react/components/action-item/action-item.tsx index cdfa3586..37738206 100644 --- a/apps/demo-react/components/action-item/action-item.tsx +++ b/apps/demo-react/components/action-item/action-item.tsx @@ -12,7 +12,12 @@ export const ActionItem: FC> = (props) => { return ( - + {children} diff --git a/apps/demo-react/components/action/action.tsx b/apps/demo-react/components/action/action.tsx index e51a6597..e1ff035b 100644 --- a/apps/demo-react/components/action/action.tsx +++ b/apps/demo-react/components/action/action.tsx @@ -4,7 +4,8 @@ import { Button } from '@lidofinance/lido-ui'; import { PropsWithChildren, useReducer } from 'react'; import { type SDKError } from '@lidofinance/lido-ethereum-sdk'; -import { useWeb3 } from 'reef-knot/web3-react'; +import { useConnection } from 'wagmi'; +import { useSupportedChains } from 'hooks/useSupportedChains'; import { Accordion } from 'components'; import { ActionBlock, @@ -101,7 +102,8 @@ const defaultRenderError = (error: SDKError) => { const defaultRenderResult = (result: TResult) => { const stringfyed = JSON.stringify( result, - (_, value) => (typeof value === 'bigint' ? value.toString() : value), + (_, value: unknown) => + typeof value === 'bigint' ? value.toString() : value, 2, ); @@ -114,7 +116,7 @@ const defaultRenderResult = (result: TResult) => { theme="pop" name={null} displayDataTypes={false} - src={JSON.parse(stringfyed)} + src={JSON.parse(stringfyed) as object} collapseStringsAfterLength={30} /> @@ -130,7 +132,9 @@ export const Action = ({ children, ...rest }: ActionProps) => { - const { active } = useWeb3(); + const { isConnected } = useConnection(); + const { isUnsupported } = useSupportedChains(); + const active = isConnected && !isUnsupported; const [{ result, error, loading }, dispatch] = useReducer( reducer, { @@ -144,10 +148,9 @@ export const Action = ({ const startLoading = async () => { try { dispatch({ type: 'loading' }); - const result = await action(); + const actionResult = await action(); - dispatch({ type: 'success', result }); - // eslint-disable-next-line @typescript-eslint/no-shadow + dispatch({ type: 'success', result: actionResult }); } catch (error) { console.error(error); dispatch({ type: 'error', error: error as SDKError }); @@ -162,7 +165,9 @@ export const Action = ({ + ); +}; + +const EIP712Panel = () => { + const { address, chainId, chain, connector, isConnected } = useConnection(); + const publicClient = usePublicClient({ chainId }); + const { mutateAsync: signTypedData } = useSignTypedData(); + const { isUnsupported } = useSupportedChains(); + const [status, setStatus] = useState('idle'); + const [report, setReport] = useState(); + const [walletOrDevice, setWalletOrDevice] = useState(''); + const [version, setVersion] = useState(''); + const busy = useRef(false); + const mounted = useRef(true); + useEffect(() => { + mounted.current = true; + return () => { + mounted.current = false; + }; + }, []); + + const pending = status === 'signing' || status === 'verifying'; + const connected = isConnected && !!address && !!chainId && !!connector; + const typedData = createTypedData(address ?? zeroAddress, chainId); + const payload = JSON.stringify(typedData, null, 2); + + const runTest = async () => { + if (!connected || isUnsupported || !publicClient || busy.current) return; + busy.current = true; + const attempt: Report = { + timestamp: new Date().toISOString(), + wallet: connector.name, + connectorId: connector.id, + account: address, + chainId, + typedData, + digest: hashTypedData(typedData), + }; + setReport(undefined); + setStatus('signing'); + let nextStatus: Status = 'success'; + try { + attempt.signature = await signTypedData({ + ...typedData, + account: address, + connector, + }); + if (!mounted.current) return; + setStatus('verifying'); + attempt.verified = await publicClient.verifyTypedData({ + ...typedData, + address, + signature: attempt.signature, + }); + if (!attempt.verified) + throw new Error(`The signature is not valid for account ${address}.`); + } catch (error) { + const cause = + error instanceof BaseError ? error.walk(isUserRejection) : error; + nextStatus = isUserRejection(cause) ? 'cancelled' : 'error'; + attempt.error = + error instanceof Error + ? `${error.name}: ${error.message}` + : String(error); + } finally { + busy.current = false; + } + if (mounted.current) { + setReport(attempt); + setStatus(nextStatus); + } + }; + + const reportText = JSON.stringify( + { + ...report, + status, + environment: { + walletOrDevice: walletOrDevice.trim() || 'Not provided', + version: version.trim() || 'Not provided', + source: 'Manually entered', + }, + }, + null, + 2, + ); + + return ( + + +

EIP-712 signing test

+ Message signing +
+ + Sign a demo message and check the signature. No transaction or token + approval. + + + + {connected ? ( + <> + + {connector.name} + {chain?.name ?? `Chain ${chainId}`} + + + {shorten(address)} + + + + ) : ( + Connect a wallet to begin + )} + + + + Message you will sign +

{typedData.message.message}

+ {connected && ( +
+ View typed data + + {payload} +
+ )} +
+ + <> + + {connected && isUnsupported && ( + Switch to a supported network to run the test. + )} + {connected && !isUnsupported && !publicClient && ( + Signature verification is unavailable on this network. + )} + + +
+ {pending && ( + + {status === 'signing' + ? 'Review and confirm the message in your wallet.' + : 'Checking that the signature is valid for your connected account.'} + + )} + {report && ( + + + {status === 'success' + ? '✓ Signature verified' + : status === 'cancelled' + ? 'Request cancelled' + : 'Test failed'} + +

+ {status === 'success' + ? 'The signature is valid for your connected account.' + : status === 'cancelled' + ? 'The request was declined. You can run the test again.' + : report.signature + ? 'The signature could not be verified. See technical details below.' + : 'The wallet did not return a signature. See technical details below.'} +

+
+ )} +
+ + {report && ( + <> +
+ Technical details & test report + + This test checks signature validity for the connected account. It + does not check how your wallet displays the message. + + + + + + + {reportText} +
+ + )} +
+ ); +}; + +export const EIP712Test = () => { + const { address, chainId, connector } = useConnection(); + // A result belongs to one connection. Discard it when the account changes. + return ; +}; diff --git a/apps/demo-react/features/eip712/styles.ts b/apps/demo-react/features/eip712/styles.ts new file mode 100644 index 00000000..553ce32b --- /dev/null +++ b/apps/demo-react/features/eip712/styles.ts @@ -0,0 +1,161 @@ +import styled from 'styled-components'; + +export const Card = styled.section` + width: 100%; + min-width: 0; + margin-top: 24px; + padding: 24px; + border: 1px solid ${({ theme }) => theme.colors.border}; + border-radius: 20px; + color: ${({ theme }) => theme.colors.text}; + font-size: 14px; + line-height: 1.6; + overflow-wrap: anywhere; + + h2 { + margin: 0; + font-size: 20px; + line-height: 1.4; + letter-spacing: -0.3px; + } + + p { + margin: 6px 0 0; + } + + @media (max-width: 480px) { + padding: 16px; + border-radius: 16px; + } +`; + +export const Row = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 12px; +`; + +export const Muted = styled.p` + color: ${({ theme }) => theme.colors.textSecondary}; + font-size: 13px; +`; + +export const Badge = styled.span` + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 10px; + border-radius: 8px; + background: ${({ theme }) => theme.colors.background}; + color: ${({ theme }) => theme.colors.textSecondary}; + font-size: 12px; + font-weight: 600; +`; + +export const Connection = styled.div` + margin: 20px 0; + padding: 14px 16px; + background: ${({ theme }) => theme.colors.background}; + border-radius: 12px; + + strong { + font-weight: 600; + } + + code { + font-size: 13px; + } +`; + +export const Message = styled.div` + padding-left: 14px; + margin: 20px 0; + border-left: 3px solid ${({ theme }) => theme.colors.primary}; +`; + +export const Eyebrow = styled.div` + font-size: 11px; + font-weight: 600; + letter-spacing: 0.8px; + text-transform: uppercase; + color: ${({ theme }) => theme.colors.textSecondary}; +`; + +export const Details = styled.details` + margin-top: 16px; + + summary { + width: fit-content; + cursor: pointer; + color: ${({ theme }) => theme.colors.textSecondary}; + font-size: 13px; + } + + summary:hover { + color: ${({ theme }) => theme.colors.text}; + } + + &[open] > summary { + margin-bottom: 12px; + } +`; + +export const Code = styled.pre` + margin: 12px 0; + padding: 14px; + border-radius: 10px; + background: ${({ theme }) => theme.colors.background}; + white-space: pre-wrap; + overflow-wrap: anywhere; + max-height: 320px; + overflow: auto; + font-size: 12px; + line-height: 1.6; +`; + +export const Result = styled.div<{ + $tone: 'success' | 'error' | 'neutral'; +}>` + margin-top: 20px; + padding: 16px; + border: 1px solid + ${({ theme, $tone }) => + $tone === 'neutral' ? theme.colors.border : theme.colors[$tone]}; + border-radius: 12px; + + strong { + display: block; + font-size: 15px; + } +`; + +export const EnvironmentFields = styled.div` + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; + margin: 12px 0; + + label { + display: grid; + gap: 6px; + font-size: 12px; + color: ${({ theme }) => theme.colors.textSecondary}; + } + + input { + width: 100%; + min-width: 0; + border: 1px solid ${({ theme }) => theme.colors.border}; + border-radius: 8px; + padding: 10px 12px; + color: ${({ theme }) => theme.colors.text}; + background: ${({ theme }) => theme.colors.background}; + font: inherit; + } + + @media (max-width: 480px) { + grid-template-columns: 1fr; + } +`; diff --git a/apps/demo-react/features/index.ts b/apps/demo-react/features/index.ts index 6a181013..6585346e 100644 --- a/apps/demo-react/features/index.ts +++ b/apps/demo-react/features/index.ts @@ -5,3 +5,4 @@ export * from './withdrawals'; export * from './permit'; export * from './stats'; export * from './claim'; +export * from './eip712/eip712'; diff --git a/apps/demo-react/features/permit/permit.tsx b/apps/demo-react/features/permit/permit.tsx index 3ccfb0ac..4d90662a 100644 --- a/apps/demo-react/features/permit/permit.tsx +++ b/apps/demo-react/features/permit/permit.tsx @@ -1,7 +1,7 @@ import { FC, useCallback, useState } from 'react'; import { Select, Option } from '@lidofinance/lido-ui'; import { useLidoSDK } from 'providers/sdk'; -import { useWeb3 } from 'reef-knot/web3-react'; +import { useConnection } from 'wagmi'; import { LIDO_CONTRACT_NAMES } from '@lidofinance/lido-ethereum-sdk/common'; import { ActionItem } from 'components'; @@ -16,8 +16,8 @@ export const Permit: FC = () => { const { inputValue } = useInputValueSDK(); const [token, setType] = useState(TokenType.stETH); - const { account: web3account = '0x0' } = useWeb3(); - const account = web3account as `0x{string}`; + const { address = '0x0' } = useConnection(); + const account = address as `0x{string}`; const { core } = useLidoSDK(); diff --git a/apps/demo-react/features/stake/stake.tsx b/apps/demo-react/features/stake/stake.tsx index 96461871..df101f70 100644 --- a/apps/demo-react/features/stake/stake.tsx +++ b/apps/demo-react/features/stake/stake.tsx @@ -1,7 +1,7 @@ import { FC, useCallback, useState } from 'react'; import { Input } from '@lidofinance/lido-ui'; import { useLidoSDK } from 'providers/sdk'; -import { useWeb3 } from 'reef-knot/web3-react'; +import { useConnection } from 'wagmi'; import { transactionToast } from 'utils/transaction-toast'; import { ActionItem } from 'components'; @@ -14,8 +14,8 @@ export const Stake: FC = () => { const referralAddress = referralAddressState ? (referralAddressState as `0x{string}`) : undefined; - const { account: web3account = '0x0' } = useWeb3(); - const account = web3account as `0x{string}`; + const { address = '0x0' } = useConnection(); + const account = address as `0x{string}`; const { stake } = useLidoSDK(); diff --git a/apps/demo-react/features/stats/stats.tsx b/apps/demo-react/features/stats/stats.tsx index 51a34dc2..b87b009b 100644 --- a/apps/demo-react/features/stats/stats.tsx +++ b/apps/demo-react/features/stats/stats.tsx @@ -1,13 +1,14 @@ import { memo } from 'react'; import { formatEther } from 'viem'; import { ThemeProvider, themeLight } from '@lidofinance/lido-ui'; -import { useWeb3 } from 'reef-knot/web3-react'; -import { useConnectorInfo } from 'reef-knot/core-react'; +import { useConnection } from 'wagmi'; +import { useConnectorInfo } from 'reef-knot'; import { StatsItem, TokenInput } from 'components'; import { useETHBalance } from 'hooks/ethBalance'; import { useStETHBalance } from 'hooks/stethBalance'; import { useWstETHBalance } from 'hooks/wstethBalance'; +import { useSupportedChains } from 'hooks/useSupportedChains'; import { WalletFallback } from 'components/wallet-fallback'; import { useInputValueSDK } from 'providers'; @@ -29,7 +30,7 @@ const StatsComponent = () => { const wstethBalance = useWstETHBalance(); const { connectorName } = useConnectorInfo(); - const web3Info = useWeb3(); + const { chainId } = useConnection(); const ethAmount = ethBalance.error ? 'N/A' @@ -60,11 +61,15 @@ const StatsComponent = () => {
Provider: - {connectorName} + + {connectorName} +
Network: - {web3Info.chainId} + + {chainId} +
@@ -90,7 +95,9 @@ const StatsComponent = () => { }; export const Stats = memo((props) => { - const { active } = useWeb3(); + const { isConnected } = useConnection(); + const { isUnsupported } = useSupportedChains(); + const active = isConnected && !isUnsupported; return active ? : ; }); diff --git a/apps/demo-react/features/wallet-testing/wallet-testing.tsx b/apps/demo-react/features/wallet-testing/wallet-testing.tsx index 9b38aca6..5905c1d0 100644 --- a/apps/demo-react/features/wallet-testing/wallet-testing.tsx +++ b/apps/demo-react/features/wallet-testing/wallet-testing.tsx @@ -1,4 +1,11 @@ -import { Stake, WrapUnwrap, Withdrawals, Permit, Claim } from 'features'; +import { + Stake, + WrapUnwrap, + Withdrawals, + Permit, + Claim, + EIP712Test, +} from 'features'; import { WrapperStyle, ActionsBlockStyle } from './wallet-testing-styles'; @@ -12,6 +19,7 @@ export const WalletTesting = () => { + ); }; diff --git a/apps/demo-react/features/wallet-ui/custom-modal.tsx b/apps/demo-react/features/wallet-ui/custom-modal.tsx new file mode 100644 index 00000000..585a4a07 --- /dev/null +++ b/apps/demo-react/features/wallet-ui/custom-modal.tsx @@ -0,0 +1,378 @@ +import { useId, useState, useEffect, type PropsWithChildren } from 'react'; +import { createPortal } from 'react-dom'; +import { + ReefKnotUIProvider, + ReefKnotLedgerProvider, + useWalletPicker, + useWalletConnection, + useTerms, + useEagerConnectScreen, + useEIP6963Picker, + useLedgerFlow, + useReefKnotModal, + useModalFocus, + useModalClose, + useEscape, + useLockScroll, + type ReefKnotWalletsModalConfig, + type ReefKnotTheme, +} from 'reef-knot'; +import styles from './wallet-ui.module.css'; + +const ErrorMessage = ({ error }: { error?: Error | null }) => + error ? ( +

+ {error.message} +

+ ) : null; + +const Terms = () => { + const { checked, setChecked, linkTerms, linkPrivacyNotice } = useTerms(); + return ( + + ); +}; + +const Wallet = ({ walletId }: { walletId: string }) => { + const { wallet, isVisible, disabled, isLoading, connect } = + useWalletConnection(walletId); + if (!wallet || !isVisible) return null; + return ( + + ); +}; + +const WalletPicker = () => { + const picker = useWalletPicker(); + return ( + <> + + + {picker.search && ( + + )} + {picker.isDiscovering &&

Discovering wallets…

} + {!picker.isDiscovering && picker.wallets.length === 0 && ( +

No wallets found

+ )} +
+ {picker.wallets.map((wallet) => ( + + ))} +
+ + {picker.showToggle && ( + + )} + + ); +}; + +const EagerConnect = () => { + const state = useEagerConnectScreen(); + return ( + <> + + {state.errorMessage && ( +

+ {state.errorMessage} +

+ )} + + + ); +}; + +const EIP6963Picker = () => { + const state = useEIP6963Picker(); + return ( + <> + +

Select browser wallet

+
+ {state.providers.map((provider) => ( + + ))} +
+ + + ); +}; + +export const HeadlessLedgerScreen = () => { + const state = useLedgerFlow(); + if (state.screen === 'error') + return ( + <> + + + + ); + if (state.screen === 'connection') + return ( + <> +

+ {state.isLoadingLedgerLibs + ? 'Loading connector…' + : 'Connect your Ledger and open the Ethereum app on the device.'} +

+ {state.isUserActivationRequired && ( + + )} + + ); + return ( + <> +
+ Select HD derivation path + {state.derivationPaths.map((path) => ( + + ))} +
+ {state.accounts.length < state.accountsPerPage ? ( +

Loading accounts…

+ ) : ( +
+ {state.accounts.map((account) => ( + + ))} +
+ )} + + + ); +}; + +const ModalContainer = ({ + title, + theme, + onClose, + onBack, + children, +}: PropsWithChildren<{ + title: string; + theme: ReefKnotTheme; + onClose?: () => void; + onBack?: () => void; +}>) => { + const titleId = useId(); + const focusRef = useModalFocus(); + const { ref: closeRef, handleClick } = useModalClose(onClose); + useEscape(onClose); + useLockScroll(); + return ( +
+
{ + (focusRef as React.MutableRefObject).current = + node; + (closeRef as React.MutableRefObject).current = + node; + }} + role="dialog" + aria-modal="true" + aria-labelledby={titleId} + tabIndex={-1} + className={styles.dialog} + > +
+ {onBack && ( + + )} +

{title}

+ {onClose && ( + + )} +
+
{children}
+
+
+ ); +}; + +const CustomContent = ({ theme }: { theme: ReefKnotTheme }) => { + const { currentModal, goBack, forceCloseAllModals } = useReefKnotModal(); + const [root, setRoot] = useState(null); + useEffect(() => { + const element = document.createElement('div'); + document.body.append(element); + setRoot(element); + return () => element.remove(); + }, []); + if (!currentModal || !root) return null; + const onClose = + currentModal.type === 'eager' ? undefined : forceCloseAllModals; + const onBack = + currentModal.type === 'wallet' || currentModal.type === 'eager' + ? undefined + : goBack; + const title = + currentModal.type === 'eager' + ? 'Confirm connection' + : currentModal.type === 'ledger' + ? 'Ledger connect' + : currentModal.type === 'requirements' + ? (currentModal.props.title ?? + (currentModal.props.kind === 'no-wallets' + ? 'No browser wallet detected' + : 'Wallet requirements')) + : 'Connect wallet'; + const body = + currentModal.type === 'wallet' ? ( + + ) : currentModal.type === 'eager' ? ( + + ) : currentModal.type === 'eip6963' ? ( + + ) : currentModal.type === 'ledger' ? ( + + + + ) : ( + <> + {currentModal.props?.kind === 'no-wallets' && ( +

Install a browser wallet to connect.

+ )} + {currentModal.props?.text} + + ); + return createPortal( + + {body} + , + root, + ); +}; + +export const CustomWalletsModal = ({ + config, + theme, +}: { + config: ReefKnotWalletsModalConfig; + theme: ReefKnotTheme; +}) => ( + + + +); diff --git a/apps/demo-react/features/wallet-ui/wallet-ui.module.css b/apps/demo-react/features/wallet-ui/wallet-ui.module.css new file mode 100644 index 00000000..f12d3719 --- /dev/null +++ b/apps/demo-react/features/wallet-ui/wallet-ui.module.css @@ -0,0 +1,169 @@ +.selector { + margin: 24px 0; +} +.selector fieldset { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 20px; + margin: 0; + padding: 0; + min-width: 0; + border: 0; +} +.selector .selectorTitle { + font-size: 18px; + white-space: nowrap; +} +.options { + display: flex; + flex-wrap: wrap; + gap: 20px; +} +.description { + margin-top: 12px; +} +.overlay { + --background: #fff; + --text: #20232a; + --border: #758091; + --error: #b42318; + position: fixed; + inset: 0; + z-index: 300; + display: flex; + padding: 24px; + overflow-y: auto; + box-sizing: border-box; + background: rgb(0 0 0 / 45%); + color: var(--text); + font: + 16px/1.5 system-ui, + sans-serif; + color-scheme: light; +} +.overlay[data-theme='dark'] { + --background: #181b22; + --text: #f4f5f7; + --border: #9aa4b2; + --error: #ff9d94; + color-scheme: dark; +} +.dialog { + width: 100%; + max-width: 660px; + margin: auto; + padding: 24px; + box-sizing: border-box; + border: 1px solid var(--border); + border-radius: 12px; + background: var(--background); + outline: none; +} +.header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 24px; +} +.header h2 { + flex: 1; + font-size: 22px; +} +.body { + display: flex; + flex-direction: column; + gap: 16px; +} +.dialog button, +.dialog input[type='search'] { + font: inherit; + padding: 10px 14px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--background); + color: var(--text); +} +.dialog button { + cursor: pointer; +} +.dialog button:disabled { + opacity: 0.5; + cursor: default; +} +.dialog button:focus-visible, +.dialog input:focus-visible, +.dialog a:focus-visible { + outline: 3px solid #008cff; + outline-offset: 3px; +} +.dialog input[type='radio'], +.dialog input[type='checkbox'] { + width: 18px; + height: 18px; + flex-shrink: 0; +} +.terms { + display: flex; + align-items: flex-start; + gap: 12px; +} +.search { + display: flex; + flex-direction: column; + gap: 8px; +} +.list { + display: flex; + flex-direction: column; + gap: 10px; +} +.list button { + display: flex; + flex-direction: column; + align-items: flex-start; + overflow-wrap: anywhere; + text-align: left; +} +.list code { + max-width: 100%; + overflow-wrap: anywhere; + font-size: 14px; +} +.error { + color: var(--error); + overflow-wrap: anywhere; +} +.paths { + padding: 12px; + border: 1px solid var(--border); +} +.paths label { + display: flex; + align-items: center; + gap: 8px; + margin: 8px 0; +} +.pages { + display: flex; + flex-wrap: wrap; + gap: 8px; +} +.pages [aria-current='page'] { + border-width: 2px; + font-weight: 700; +} +@media (max-width: 600px) { + .overlay { + padding: 12px; + } + .dialog { + padding: 16px; + } + .header { + flex-wrap: wrap; + } + .header h2 { + font-size: 18px; + } +} diff --git a/apps/demo-react/features/wallet-ui/wallet-ui.tsx b/apps/demo-react/features/wallet-ui/wallet-ui.tsx new file mode 100644 index 00000000..5dedf740 --- /dev/null +++ b/apps/demo-react/features/wallet-ui/wallet-ui.tsx @@ -0,0 +1,141 @@ +import { + createContext, + useCallback, + useContext, + useId, + useMemo, + useState, + type PropsWithChildren, +} from 'react'; +import { useConnection } from 'wagmi'; +import { + useReefKnotContext, + useReefKnotModal, + type ReefKnotWalletsModalConfig, + type ReefKnotTheme, +} from 'reef-knot'; +import { ReefKnotWalletsModal as LegacyModal } from '@reef-knot/ui-lido-legacy'; +import { ReefKnotWalletsModal as LidoModal } from '@reef-knot/ui-lido'; +import { Card, RadioButton, Typography } from '@lidofinance/lido-app-ui'; +import { CustomWalletsModal } from './custom-modal'; +import styles from './wallet-ui.module.css'; + +type WalletUIMode = 'legacy' | 'lido-app-ui' | 'custom'; +const WalletUIContext = createContext<{ + mode: WalletUIMode; + theme: ReefKnotTheme; + disabled: boolean; + setMode: (mode: WalletUIMode) => void; +} | null>(null); + +export const WalletUIProvider = ({ + config, + theme, + children, +}: PropsWithChildren<{ + config: ReefKnotWalletsModalConfig; + theme: ReefKnotTheme; +}>) => { + const [mode, updateMode] = useState('legacy'); + const { currentModal } = useReefKnotModal(); + const { loadingWalletId } = useReefKnotContext(); + const { status } = useConnection(); + const disabled = + !!currentModal || + loadingWalletId !== null || + status === 'connecting' || + status === 'reconnecting'; + const setMode = useCallback( + (next: WalletUIMode) => { + if (!disabled) updateMode(next); + }, + [disabled], + ); + const value = useMemo( + () => ({ mode, theme, disabled, setMode }), + [mode, theme, disabled, setMode], + ); + return ( + + {mode === 'legacy' ? ( + + ) : mode === 'lido-app-ui' ? ( + + ) : ( + + )} + {children} + + ); +}; + +const MODES = [ + { + value: 'legacy', + label: 'Legacy', + description: 'The original Lido wallet interface.', + }, + { + value: 'lido-app-ui', + label: 'Lido App UI', + description: 'The wallet interface built with Lido App UI.', + }, + { + value: 'custom', + label: 'Custom', + description: 'Custom HTML screens using the public Reef Knot hooks.', + }, +] as const; + +export const WalletUISelector = () => { + const state = useContext(WalletUIContext); + const titleId = useId(); + if (!state) throw new Error('WalletUISelector requires WalletUIProvider.'); + return ( + +
+
+ + Wallet UI: + +
+ {MODES.map(({ value, label }) => ( + state.setMode(value)} + label={ + + {label} + + } + /> + ))} +
+
+ + {MODES.find(({ value }) => value === state.mode)?.description} + + {state.disabled && ( + + Close the wallet dialog and wait for connection to finish before + switching UI. + + )} +
+
+ ); +}; diff --git a/apps/demo-react/features/withdrawals/withdrawals.tsx b/apps/demo-react/features/withdrawals/withdrawals.tsx index b8761c08..66bfd2b8 100644 --- a/apps/demo-react/features/withdrawals/withdrawals.tsx +++ b/apps/demo-react/features/withdrawals/withdrawals.tsx @@ -1,6 +1,6 @@ import { FC, useCallback, useState } from 'react'; import { Select, Option } from '@lidofinance/lido-ui'; -import { useWeb3 } from 'reef-knot/web3-react'; +import { useConnection } from 'wagmi'; import { useLidoSDK } from 'providers/sdk'; import { transactionToast } from 'utils/transaction-toast'; @@ -16,8 +16,8 @@ export const Withdrawals: FC = () => { const { inputValue } = useInputValueSDK(); const [token, setType] = useState(TokenType.stETH); - const { account: web3account = '0x0' } = useWeb3(); - const account = web3account as `0x{string}`; + const { address = '0x0' } = useConnection(); + const account = address as `0x{string}`; const { withdraw } = useLidoSDK(); diff --git a/apps/demo-react/features/wrap-unwrap/wrap-unwrap.tsx b/apps/demo-react/features/wrap-unwrap/wrap-unwrap.tsx index e424a9bf..bb7f1ce6 100644 --- a/apps/demo-react/features/wrap-unwrap/wrap-unwrap.tsx +++ b/apps/demo-react/features/wrap-unwrap/wrap-unwrap.tsx @@ -2,7 +2,7 @@ import { FC, useCallback, useState } from 'react'; import { Select, Option } from '@lidofinance/lido-ui'; import { WrapProps } from '@lidofinance/lido-ethereum-sdk'; import { useLidoSDK } from 'providers/sdk'; -import { useWeb3 } from 'reef-knot/web3-react'; +import { useConnection } from 'wagmi'; import { transactionToast } from 'utils/transaction-toast'; import { ActionItem } from 'components'; @@ -18,8 +18,8 @@ export const WrapUnwrap: FC = () => { const { inputValue } = useInputValueSDK(); const [type, setType] = useState(CallType.wrapEth); - const { account: web3account = '0x0' } = useWeb3(); - const account = web3account as `0x{string}`; + const { address = '0x0' } = useConnection(); + const account = address as `0x{string}`; const { wrap } = useLidoSDK(); const isWrapTx = type === CallType.wrapEth || type === CallType.wrapSteth; diff --git a/apps/demo-react/global.d.ts b/apps/demo-react/global.d.ts index 16ac579e..ac2f3e03 100644 --- a/apps/demo-react/global.d.ts +++ b/apps/demo-react/global.d.ts @@ -1,14 +1,10 @@ interface Window { ethereum?: Record; + lido_sdk?: import('@lidofinance/lido-ethereum-sdk').LidoSDK; } declare module '*.svg' { - /** - * Use `any` to avoid conflicts with - * `@svgr/webpack` plugin or - * `babel-plugin-inline-react-svg` plugin. - */ - const content: any; + const content: string; export const ReactComponent: React.FunctionComponent< React.ComponentProps<'svg'> >; diff --git a/apps/demo-react/hooks/useSupportedChains.ts b/apps/demo-react/hooks/useSupportedChains.ts new file mode 100644 index 00000000..d1bbbac2 --- /dev/null +++ b/apps/demo-react/hooks/useSupportedChains.ts @@ -0,0 +1,19 @@ +import { useMemo } from 'react'; +import { useConnection, useConfig } from 'wagmi'; + +export const useSupportedChains = () => { + const { chainId } = useConnection(); + const { chains } = useConfig(); + + const isUnsupported = useMemo( + () => !chainId || !chains.some((chain) => chain.id === chainId), + [chainId, chains], + ); + + const supportedChains = useMemo( + () => chains.map((chain) => ({ chainId: chain.id, name: chain.name })), + [chains], + ); + + return { isUnsupported, supportedChains }; +}; diff --git a/apps/demo-react/ledger_live_example_manifest.json b/apps/demo-react/ledger_live_example_manifest.json index f52bd155..c90a42b1 100644 --- a/apps/demo-react/ledger_live_example_manifest.json +++ b/apps/demo-react/ledger_live_example_manifest.json @@ -12,10 +12,10 @@ "chainID": 1, "nodeURL": "https://rpc.ankr.com/eth" }, - { - "currency": "ethereum_holesky", - "chainID": 17000, - "nodeURL": "https://ethereum-holesky-rpc.publicnode.com" + { + "currency": "ethereum_hoodi", + "chainID": 560048, + "nodeURL": "https://0xrpc.io/hoodi" } ] }, @@ -36,6 +36,9 @@ } }, "permissions": [], - "domains": ["https://dapp-browser.apps.ledger.com", "https://lidofinance.github.io/"], + "domains": [ + "https://dapp-browser.apps.ledger.com", + "https://lidofinance.github.io/" + ], "visibility": "complete" } diff --git a/apps/demo-react/next.config.js b/apps/demo-react/next.config.js index bbbcac6c..c4806c47 100644 --- a/apps/demo-react/next.config.js +++ b/apps/demo-react/next.config.js @@ -16,11 +16,10 @@ const withBundleAnalyzer = NextBundleAnalyzer({ // Next's webpack graph, so package rebuilds invalidate Fast Refresh/HMR. const withReefKnotPackages = nextTranspileModules([ 'reef-knot', - '@reef-knot/connect-wallet-modal', - '@reef-knot/core-react', + '@reef-knot/ui-lido-legacy', + '@reef-knot/ui-lido', + '@lidofinance/lido-app-ui', '@reef-knot/ledger-connector', - '@reef-knot/types', - '@reef-knot/ui-react', '@reef-knot/wallet-adapter-ambire', '@reef-knot/wallet-adapter-anchorage-digital', '@reef-knot/wallet-adapter-bitkeep', @@ -35,13 +34,12 @@ const withReefKnotPackages = nextTranspileModules([ '@reef-knot/wallet-adapter-safe', '@reef-knot/wallet-adapter-walletconnect', '@reef-knot/wallets-helpers', - '@reef-knot/wallets-icons', - '@reef-knot/wallets-list', - '@reef-knot/web3-react', ]); export default withReefKnotPackages( withBundleAnalyzer({ + // Next 12 uses the removed legacy API. + eslint: { ignoreDuringBuilds: true }, reactStrictMode: true, basePath, experimental: { @@ -92,6 +90,10 @@ export default withReefKnotPackages( }, async headers() { return [ + { + source: '/runtime/window-env.js', + headers: [{ key: 'Cache-Control', value: 'no-store' }], + }, { // required for Gnosis Safe apps source: '/manifest.json', diff --git a/apps/demo-react/package.json b/apps/demo-react/package.json index da85130c..c499d924 100644 --- a/apps/demo-react/package.json +++ b/apps/demo-react/package.json @@ -8,18 +8,21 @@ "build": "next build", "build:analyze": "ANALYZE_BUNDLE=true next build", "start": "next start", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc6 --noEmit" }, "dependencies": { "@coinbase/wallet-sdk": "^4.3.6", + "@lidofinance/lido-app-ui": "1.4.0", "@lidofinance/lido-ethereum-sdk": "4.7.0", "@lidofinance/lido-ui": "^3.18.0", "@metamask/connect-evm": "^2.1.0", + "@reef-knot/ui-lido": "*", + "@reef-knot/ui-lido-legacy": "*", "@safe-global/safe-apps-provider": "^0.18.6", "@safe-global/safe-apps-sdk": "^9.1.0", "@svgr/webpack": "^8.0.1", - "@tanstack/react-query": "^5.29.0", + "@tanstack/react-query": "^5.51.1", "@walletconnect/ethereum-provider": "^2.21.1", "copy-to-clipboard": "^3.3.3", "fs-extra": "^11.2.0", @@ -47,6 +50,6 @@ "string-replace-loader": "^3.3.0", "tsconfig": "*", "typechain": "^8.3.0", - "typescript": "~5.9" + "typescript": "npm:@typescript/typescript6@6.0.2" } } diff --git a/apps/demo-react/pages/_app.tsx b/apps/demo-react/pages/_app.tsx index 7a8b2a33..38cbbee4 100644 --- a/apps/demo-react/pages/_app.tsx +++ b/apps/demo-react/pages/_app.tsx @@ -1,3 +1,5 @@ +import '@lidofinance/lido-app-ui/index.css'; +import '@reef-knot/ui-lido/styles.css'; import { memo } from 'react'; import { AppProps } from 'next/app'; import { ToastContainer, CookiesTooltip } from '@lidofinance/lido-ui'; diff --git a/apps/demo-react/pages/index.tsx b/apps/demo-react/pages/index.tsx index 60bfcea0..3851079b 100644 --- a/apps/demo-react/pages/index.tsx +++ b/apps/demo-react/pages/index.tsx @@ -4,6 +4,7 @@ import dynamic from 'next/dynamic'; import { WalletInfo } from 'components'; import Layout from 'components/layout'; import { WalletTesting, Stats } from 'features'; +import { WalletUISelector } from '../features/wallet-ui/wallet-ui'; export const Web = () => { return ( @@ -14,6 +15,7 @@ export const Web = () => { Lido | Reef Knot demo app + diff --git a/apps/demo-react/providers/sdk.tsx b/apps/demo-react/providers/sdk.tsx index 1cdff71f..8fc1a6bb 100644 --- a/apps/demo-react/providers/sdk.tsx +++ b/apps/demo-react/providers/sdk.tsx @@ -50,15 +50,14 @@ export const LidoSDKProvider: React.FC = ({ children }) => { }, [isConnected]); const contextValue = useMemo(() => { - // @ts-expect-error: typing (viem + LidoSDK) const sdk = new LidoSDK({ - chainId: publicClient?.chain.id as any, + chainId: publicClient?.chain.id, logMode: 'none', rpcProvider: publicClient, web3Provider: walletClient, - }); + } as unknown as ConstructorParameters[0]); // inject lido_sdk for console access - if (typeof window !== 'undefined') (window as any).lido_sdk = sdk; + if (typeof window !== 'undefined') window.lido_sdk = sdk; return sdk; }, [publicClient, walletClient]); diff --git a/apps/demo-react/providers/web3.tsx b/apps/demo-react/providers/web3.tsx index f94947d5..550ccd52 100644 --- a/apps/demo-react/providers/web3.tsx +++ b/apps/demo-react/providers/web3.tsx @@ -1,15 +1,16 @@ import { FC, PropsWithChildren, useMemo } from 'react'; -import { useThemeToggle } from '@lidofinance/lido-ui'; -import { ReefKnotProvider, getDefaultConfig } from 'reef-knot/core-react'; -import { WalletsListEthereum } from 'reef-knot/wallets'; +import { useThemeToggle, ThemeName } from '@lidofinance/lido-ui'; +import { + ReefKnotProvider, + WalletsListEthereum, + getDefaultConfig, + getDefaultWalletsModalConfig, +} from 'reef-knot'; +import { WalletUIProvider } from '../features/wallet-ui/wallet-ui'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { WagmiProvider, http } from 'wagmi'; import * as wagmiChains from 'wagmi/chains'; import type { Transport } from 'viem'; -import { - ReefKnotWalletsModal, - getDefaultWalletsModalConfig, -} from 'reef-knot/connect-wallet-modal'; import { metricProps } from 'utils/metrics'; import { useClientConfig } from 'providers/client-config'; @@ -17,7 +18,7 @@ import { useRpcUrls } from 'hooks/useRpcUrls'; type ChainsList = [wagmiChains.Chain, ...wagmiChains.Chain[]]; -const wagmiChainsArray = Object.values(wagmiChains) as any as ChainsList; +const wagmiChainsArray = Object.values(wagmiChains) as unknown as ChainsList; const queryClient = new QueryClient(); @@ -40,7 +41,11 @@ const Web3Provider: FC = ({ children }) => { supportedChains[0]; // first supported chain as fallback return { - supportedChains: supportedChains as ChainsList, + // Wagmi initializes its active chain from chains[0] when no state is saved. + supportedChains: [ + defaultChain, + ...supportedChains.filter((chain) => chain.id !== defaultChain.id), + ] as ChainsList, defaultChain, }; }, [defaultChainId, supportedChainIds]); @@ -72,7 +77,6 @@ const Web3Provider: FC = ({ children }) => { ssr: true, // Wallets config args - // TODO: We could call `getDefaultWalletsModalConfig` inside `getDefaultConfig`, but it cause package dependency cycle rn ...getDefaultWalletsModalConfig(), ...metricProps, }); @@ -90,11 +94,12 @@ const Web3Provider: FC = ({ children }) => { - - {children} + theme={themeName === ThemeName.dark ? 'dark' : 'light'} + > + {children} + diff --git a/apps/demo-react/tsconfig.json b/apps/demo-react/tsconfig.json index 45617a87..8712ee9a 100644 --- a/apps/demo-react/tsconfig.json +++ b/apps/demo-react/tsconfig.json @@ -15,7 +15,9 @@ "jsx": "preserve", "baseUrl": ".", "incremental": true, + "types": ["*"], + "ignoreDeprecations": "6.0" }, "include": ["next-env.d.ts", "additional.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"], + "exclude": ["node_modules"] } diff --git a/apps/demo-react/types/ReactProps.ts b/apps/demo-react/types/ReactProps.ts index 97c0fdef..8c4321c8 100644 --- a/apps/demo-react/types/ReactProps.ts +++ b/apps/demo-react/types/ReactProps.ts @@ -2,10 +2,5 @@ import { ReactChild, ReactFragment, ReactPortal } from 'react'; export type ReactProps = { children: - | boolean - | ReactChild - | ReactFragment - | ReactPortal - | null - | undefined; + boolean | ReactChild | ReactFragment | ReactPortal | null | undefined; }; diff --git a/apps/demo-react/utils/fetcher.ts b/apps/demo-react/utils/fetcher.ts index 009a4014..b557e89a 100644 --- a/apps/demo-react/utils/fetcher.ts +++ b/apps/demo-react/utils/fetcher.ts @@ -26,14 +26,17 @@ const extractErrorMessage = (error: unknown): string => { const extractError = async (response: Response) => { try { - const error = await response.json(); + const error: unknown = await response.json(); return extractErrorMessage(error); - } catch (error) { + } catch { return 'An error occurred while fetching the data'; } }; -export const standardFetcher: StandardFetcher = async (url, params) => { +export const standardFetcher: StandardFetcher = async ( + url: string, + params?: RequestInit, +) => { const response = await fetch(url, { ...DEFAULT_PARAMS, ...params, @@ -43,5 +46,5 @@ export const standardFetcher: StandardFetcher = async (url, params) => { throw new FetcherError(await extractError(response), response.status); } - return await response.json(); + return (await response.json()) as T; }; diff --git a/apps/demo-react/utils/getChainColor.ts b/apps/demo-react/utils/getChainColor.ts index 3428e59e..27d6f3cc 100644 --- a/apps/demo-react/utils/getChainColor.ts +++ b/apps/demo-react/utils/getChainColor.ts @@ -4,7 +4,6 @@ export const CHAINS_COLORS: { [key in CHAINS]?: string; } = { [CHAINS.Mainnet]: '#29b6af', - [CHAINS.Holesky]: '#AA346A', [CHAINS.Hoodi]: '#AA346A', [CHAINS.Sepolia]: '#FFD700', [CHAINS.Optimism]: '#da3737', @@ -18,5 +17,6 @@ export const CHAINS_COLORS: { export const CHAIN_COLOR_FALLBACK = '#7a8aa0'; export const getChainColor = (chainId: number): string => { - return CHAINS_COLORS[chainId as CHAINS] || CHAIN_COLOR_FALLBACK; + const colors: Partial> = CHAINS_COLORS; + return colors[chainId] || CHAIN_COLOR_FALLBACK; }; diff --git a/apps/demo-react/utils/metrics.ts b/apps/demo-react/utils/metrics.ts index 1f7a99c9..a011da7d 100644 --- a/apps/demo-react/utils/metrics.ts +++ b/apps/demo-react/utils/metrics.ts @@ -1,9 +1,8 @@ -/* eslint-disable no-console */ import type { ReefKnotWalletsModalConfig, ReefKnotConfig, -} from '@reef-knot/types'; -import type { WalletIdsEthereum } from '@reef-knot/wallets-list'; + WalletIdsEthereum, +} from 'reef-knot'; type MetricProps = Pick< ReefKnotWalletsModalConfig, diff --git a/docs/headless-ui.md b/docs/headless-ui.md new file mode 100644 index 00000000..6f28b27d --- /dev/null +++ b/docs/headless-ui.md @@ -0,0 +1,137 @@ +# Headless connection API and Lido UI skins + +`reef-knot` provides React connection state and actions without a UI kit or CSS dependency. Install one UI skin for a ready-made interface, or build a custom interface with the same public hooks. + +A UI skin supplies the visual components for the connection screens. Wallet adapters describe individual wallets, their icons, detection and connectors. + +| Package | UI dependencies | +| --------------------------- | -------------------------------------------------- | +| `reef-knot` | None; React, wagmi, viem and React Query are peers | +| `@reef-knot/ui-lido-legacy` | lido-ui v3 and styled-components 5 | +| `@reef-knot/ui-lido` | lido-app-ui (React 18) | + +The `@reef-knot/ui-lido` UI skin is verified with `@lidofinance/lido-app-ui@1.4.0`, developed on the [app-ui branch](https://github.com/lidofinance/ui/tree/app-ui), and declares a `~1.4.0` peer range. The modal container uses the skin's own markup and classes, with App UI buttons and tokens. TokenSelector labels also use the skin's own classes; styles do not match the kit's generated CSS-module class names. Its React and React DOM peers match the UI kit: React 18. One application uses one UI skin. + +## Ready-made UI + +Providers and `useConnectionFlow()` stay in `reef-knot`. Import `ReefKnotWalletsModal` from your UI skin and mount it inside `ReefKnotProvider`. + +```tsx +import { + getDefaultConfig, + getDefaultWalletsModalConfig, + useConnectionFlow, +} from 'reef-knot'; +import { ReefKnotWalletsModal } from '@reef-knot/ui-lido'; +``` + +Load both stylesheets in the application's global stylesheet entry (for Next.js Pages Router, `_app.tsx`): + +```tsx +import '@lidofinance/lido-app-ui/index.css'; +import '@reef-knot/ui-lido/styles.css'; +``` + +```tsx + +``` + +Pass the current application theme to the UI skin. It applies `data-lido-theme` inside its portal and inherits the page's App UI CSS variables; a separate light palette is not generated for the modal. + +Start the connection flow from your connect button: + +```tsx +const { startConnection } = useConnectionFlow(); +const result = await startConnection(); // { connected: boolean } +``` + +The promise resolves when eager connection finishes or the picker is closed. The deprecated `useConnect().connect()` API remains available with the same behavior and result. + +## Custom UI + +Mount `ReefKnotUIProvider` inside `ReefKnotProvider`, with the modal configuration. It owns discovery, search, errors and connection actions. Multiple hook consumers share this owner; mounting separate owners for the same UI is unnecessary. + +```tsx + + + +``` + +Hooks read the provider configuration. Their optional `config` argument must be the same object passed to the provider. + +| API | Returned state and actions | +| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `useConnectionFlow()` | `startConnection()` starts eager connection or opens the picker | +| `useReefKnotModal()` | Current screen, stack, `openModal()`, `openModalAsync()`, `closeModal(result)`, `goBack()` and `forceCloseAllModals()` | +| `useWalletPicker(config?)` | Sorted wallets, search, expansion, discovery, errors and list actions | +| `useWalletConnection(walletId, config?)` | Wallet data, visibility, disabled/loading/error and `connect()` | +| `useTerms(config?)` | Consent, links and `setChecked(boolean)` | +| `useEagerConnectScreen(config?)` | Retry action, loading and mapped error message | +| `useEIP6963Picker(config?)` | Announced providers, loading, error and `select(provider)` | +| `useLedgerFlow()` | Device screen, accounts, pagination, derivation paths, retry and account selection | + +Render `ReefKnotLedgerProvider` only while displaying the Ledger flow, inside `ReefKnotUIProvider`. Its `isActive` prop defaults to true. It owns the transport and account discovery; view components never receive the transport itself. + +Connection actions enforce consent and serialize requests. They own reconnect persistence, callback delivery and completion of nested screens. Failed manual actions leave the screen open and expose an `error`; callers should render it and allow retry. Deeplink/install actions open the wallet and do not report a successful connection. + +When replacing a wallet, connection actions await the previous wallet's disconnect and storage cleanup. Before persisting the reconnect ID or reporting success, they verify that the selected connector instance is still active. `useDisconnect()` also exposes an optional `disconnectAsync()` for callers that need to await disconnection; `disconnect()` remains available for ordinary disconnect buttons. Both disconnect every wallet that wagmi still holds, not only the current one, so an earlier wallet cannot become active again. Both actions are unavailable when disconnecting does not make sense, such as for auto-connect-only wallets. + +For a custom dialog, reuse `useModalFocus`, `useEscape`, `useLockScroll` and `useModalClose`, or implement equivalent accessibility behavior. The API deliberately does not dictate DOM structure. `ReefKnotModalRenderer` is an optional composition helper; it requires a complete `ReefKnotUIComponents` map and has no default visuals. + +The `apps/demo-react` playground has a **Wallet UI** selector: **Legacy**, **Lido App UI**, and **Custom**. It changes only the wallet dialog, using one wallet catalog and one connection configuration. Legacy is the default; selection resets on reload. Switching is disabled while a wallet screen or connection is active and preserves an already connected account. + +The complete custom UI example is in `apps/demo-react/features/wallet-ui/custom-modal.tsx`. It uses public hooks for picker, Terms, eager, EIP-6963 and Ledger, native HTML controls and a CSS Module. Its dialog uses the public focus, Escape and scroll-lock hooks. + +Run `yarn build-packages`, then `yarn workspace demo-react dev`. The existing theme switch applies to all three dialogs. This demo intentionally loads both UI kits for comparison; normal applications still choose one UI skin. + +## Replace visual parts + +Both UI skins accept `components?: Partial`. Omitted components retain the UI skin defaults. Replace `ModalContainer`, `WalletButton`, `Terms`, `WalletPicker`, `EagerConnect`, `Requirements`, `ConnectionError`, `EIP6963Picker`, `LedgerConnection`, `LedgerAccounts` or `LedgerError`. + +```tsx + +``` + +The component receives prepared props such as `name`, `icon`, `disabled`, `isLoading` and `onConnect`. Screen props contain shared state/actions and prepared child parts. Standard screens honor child-part overrides. Replacing an entire screen gives the application ownership of its composition. + +## Migrate a legacy integration + +Version 9 removes visual exports from `reef-knot`. Follow the [8.x → 9 migration guide](migration-guide-8.x-to-9.md) for the full upgrade steps. Keep providers, hooks, configuration helpers and wallet catalogs imported from `reef-knot`; move the modal and UI primitives to `@reef-knot/ui-lido-legacy`. + +```tsx +import { getDefaultConfig, getDefaultWalletsModalConfig } from 'reef-knot'; +import { ReefKnotWalletsModal } from '@reef-knot/ui-lido-legacy'; +``` + +Existing `darkThemeEnabled`, `buttonsFullWidth` and modal props remain supported. The `buttonComponentsByConnectorId` registry and wallet-specific `Connect*` components have been removed. Replace custom buttons with `components.WalletButton`: it receives prepared data and `onConnect`, while the core handles connection rules, loading, reconnect storage and callbacks. + +The split does not migrate storage keys or invalidate Terms acceptance. Reconnect, provider selection and derivation paths retain their existing identities. + +## Validation + +Run `yarn check-packages` for package TypeScript, lint and scenario tests. The gate also checks the TypeScript of the headless/UI tests and build configurations. + +Connection failures in the wallet picker and EIP-6963 picker replace the current +view with `components.ConnectionError`. Its props contain the original `error`, a prepared `errorMessage`, and an +`onBack` action. The message never contains error text from wallets or libraries. +Only a fixed set of errors gets a specific message: a pending wallet request, +an unsupported chain, a missing wallet, an unauthorized site and a disconnected wallet. +Errors that reef-knot throws with text for the user (`UserFacingError`, including +mapped Ledger errors) keep their message. All other errors show +"Connection error. Please try again." The original error stays available in +`error`, for example for logging. The pickers and the Ledger flow expose the same +safe text as `errorMessage`; custom interfaces should render it instead of +`error.message`. When the user rejects the request in the wallet, no error is +shown and the picker stays open. + +The container receives `onBack` and `onClose`. Back dismisses the error and +returns to the previous list; search, expansion, consent and nested screens are +preserved. Close and Escape close all connection screens. The bundled skins show +Back in the header and do not add buttons to the error view. Custom interfaces can dismiss errors through +`useWalletPicker().dismissError()` or `useEIP6963Picker().dismissError()`. +Ledger retains its dedicated error screen, and eager connection retains its +inline error and retry action. diff --git a/docs/how-to-add-a-wallet.md b/docs/how-to-add-a-wallet.md index 96eb594e..ef56a091 100644 --- a/docs/how-to-add-a-wallet.md +++ b/docs/how-to-add-a-wallet.md @@ -30,10 +30,10 @@ where corresponds to the ID you've specified. ### 3. Add to Wallets List -1. Open the `package.json` file of the generated wallet adapter, located in `packages/wallets-list/`. +1. Open the `package.json` file of the generated wallet adapter, located in `packages/wallets/`. 2. Copy the name of the package. It should look like `@reef-knot/wallet-adapter-`. -3. Open `packages/wallets-list/package.json` and add the copied package name (from step 2) to the `dependencies` field, specifying version `1.0`. -4. Open `packages/wallets-list/src/ethereum.ts` and include the new adapter in the list. +3. Open `packages/reef-knot/package.json` and add the copied package name (from step 2) to the `dependencies` field, specifying version `1.0`. +4. Open `packages/reef-knot/src/wallets-list/ethereum.ts` and include the new adapter in the list. 5. Run `yarn install`. ### 4. Enable Wallet @@ -41,7 +41,7 @@ where corresponds to the ID you've specified. To display the wallet in the Wallet Connection Modal, its `id` must be included in the `walletsShown` prop of the `ReefKnotWalletsModal` component. This can be achieved by modifying the `walletsShown` prop at the application level. Additionally, you may consider editing the `WALLETS_MODAL_DISPLAY_CONFIG_DEFAULT` constant, located at: -`packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/getDefaultWalletsModalConfig.ts`. +`packages/reef-knot/src/headless/getDefaultWalletsModalConfig.ts`. ### 5. Configure the adapter diff --git a/docs/migration-guide-0.x-to-latest.md b/docs/migration-guide-0.x-to-latest.md new file mode 100644 index 00000000..cb2dbf19 --- /dev/null +++ b/docs/migration-guide-0.x-to-latest.md @@ -0,0 +1,104 @@ +# Migration guide: Reef Knot 0.x → latest + +This guide covers the migration from a 0.x integration to the current Reef Knot architecture. The headless/UI split described here is planned for v9; until v9 is published, the corresponding packages and API may require a prerelease. See the [changelog](../packages/reef-knot/CHANGELOG.md) for released versions. + +If your application already uses 8.x, follow [8.x → 9](migration-guide-8.x-to-9.md). For a new integration, use the [README](../README.md#installation). + +## 1. Update the connection dependencies + +The current integration uses: + +| Dependency | Requirement | +| ----------------------- | ----------------------------------------------------- | +| `wagmi` | Compatible 3.x release, at least 3.6 | +| `viem` | Compatible 2.x release, at least 2.50 | +| `@tanstack/react-query` | 5.x, at least 5.51.1 | +| React and React DOM | 18 for the Lido App UI skin; the core declares `>=18` | +| TypeScript | At least 5.9.3 for the current wagmi types | + +See [wagmi's TypeScript requirements](https://wagmi.sh/react/typescript). Pin and upgrade wagmi and TypeScript together when reproducible type checking is important. + +Migrating an old application's direct wagmi calls is separate from upgrading Reef Knot. Review the wagmi migration guides for the versions you cross: [0.x → 1.x](https://1.x.wagmi.sh/react/migration-guide), [1.x → 2.x](https://wagmi.sh/react/guides/migrate-from-v1-to-v2) and [2.x → 3.x](https://wagmi.sh/react/guides/migrate-from-v2-to-v3). + +Remove old Reef Knot packages such as `@reef-knot/web3-react`, `@reef-knot/core-react` and `@reef-knot/connect-wallet-modal` after migrating their imports. Remove web3-react or ethers dependencies only if no other part of the application uses them. Wallet adapter packages remain available for custom wallet catalogs. + +## 2. Choose a UI skin or build a custom interface + +In v9, `reef-knot` contains providers, wallet catalogs, configuration and headless hooks. It has no Lido UI or styled-components dependency. A ready-made modal requires one UI skin: + +| Choice | Package | Additional UI dependencies | +| ------------------------ | --------------------------- | ---------------------------------------------------------- | +| Previous Lido appearance | `@reef-knot/ui-lido-legacy` | `@lidofinance/lido-ui` 3.x and styled-components 5 | +| Lido App UI appearance | `@reef-knot/ui-lido` | `@lidofinance/lido-app-ui` (verified with 1.4.0), React 18 | +| Custom UI | None | Your own view components | + +The legacy skin is the simplest starting point for preserving the previous appearance. Custom components from a 0.x integration still need migration; choosing the legacy skin does not restore the old connection APIs. + +Use the [v9 migration guide](migration-guide-8.x-to-9.md) for installation, imports, CSS and configuration examples. Use the [headless API guide](headless-ui.md) for custom interfaces and component replacements. + +Version 9 removes all `reef-knot/*` subpath imports and the root namespace exports. If your integration uses intermediate releases with paths such as `reef-knot/core-react`, `reef-knot/wallets` or `reef-knot/web3-react`, follow the [old path → new path table](migration-guide-8.x-to-9.md#update-imports-and-configuration). + +## 3. Replace the old provider setup + +Remove the old `ProviderWeb3`, `WalletsModalForEth` and standalone auto-connect wiring where present. Integrations copied from intermediate v2–v5 releases may also contain the former `ReefKnot` provider and `AutoConnect` component. + +Configure the current integration through `getDefaultConfig` and `getDefaultWalletsModalConfig` from `reef-knot`. Keep one instance of each provider in this order: + +```tsx + + + + + {children} + + + +``` + +This example uses `ReefKnotWalletsModal` from the legacy skin. The Lido App UI skin requires an explicit `theme="light"` or `theme="dark"` prop. + +Set `autoConnect` in the Reef Knot config according to your application requirements. Keep wagmi's `reconnectOnMount={false}` because Reef Knot owns eager connection and reconnect. Keep the configuration and QueryClient stable across renders. + +## 4. Replace `useWeb3` by responsibility + +`useWeb3` is no longer exported. It previously combined state from multiple connection libraries; there is no single replacement for every field it returned. + +`useSupportedChains` is also removed. Use `useConfig().chains` and `useConnection().chainId` from wagmi, or keep a local helper. See [the replacement example and unsupported-chain behavior](migration-guide-8.x-to-9.md#replace-removed-web3-react-hooks). + +| Application task | Current API | +| -------------------------------------------- | ------------------------------------------------------- | +| Read address, chain and connection status | `useConnection` from `wagmi` | +| Read the wagmi configuration | `useConfig` from `wagmi` | +| Access a wallet client | `useWalletClient` from `wagmi` | +| Start the Reef Knot connection scenario | `useConnectionFlow` from `reef-knot` | +| Disconnect using Reef Knot's storage cleanup | `useDisconnect` / `useForceDisconnect` from `reef-knot` | + +```tsx +import { useConnection } from 'wagmi'; +import { useConnectionFlow } from 'reef-knot'; + +const { address, isConnected } = useConnection(); +const { startConnection } = useConnectionFlow(); +``` + +`startConnection()` attempts eager connection or opens the wallet picker. Its promise returns `{ connected: boolean }` when that scenario finishes. It does not provide connection state. Reef Knot's older `useConnect().connect()` remains available as a deprecated wrapper; wagmi's hook of the same name has a different contract. + +## 5. Review the wallet catalog and UI customizations + +Use `WalletsListEthereum` as the current default catalog or compose a custom catalog from supported wallet adapters. Old wallet IDs may no longer exist. Version 8.0 removed the `binanceWallet`, `coinbase`, `trust`, `exodus`, `brave`, `ctrl` and `coin98` adapters; review saved configuration and `walletsShown` / `walletsPinned` against the current catalog. + +The `buttonComponentsByConnectorId` registry and wallet-specific `Connect*` components are removed in v9. Use `components.WalletButton` or the public headless hooks, as described in [8.x → 9](migration-guide-8.x-to-9.md#replace-custom-connect-buttons). + +The modal configuration option `linkDontHaveWallet` is also removed, including its link in the legacy skin. Remove it from your configuration; keep `linkTerms` and `linkPrivacyNotice`. If you need a wallet help link, render it in your application or a custom `components.WalletPicker` view. + +## 6. Review SSR and unrelated legacy SDK code + +Do not assume that a `NoSSRWrapper` is required for every new integration. Server rendering of the Lido App UI skin has been verified with a bundled application. Browser interactions and wallet connection still run on the client. Keep any existing client-only boundary until you have checked your framework's SSR and hydration setup. + +A legacy Lido JS SDK integration is a separate migration. If the application still uses its `ProviderSDK` or ethers-based code, review those dependencies independently; removing Reef Knot's old web3-react layer does not prove that the rest of the application no longer needs them. + +## Verify the migration + +Run the application's TypeScript check and production build. Exercise consent, manual connection, cancellation, eager connection where applicable, reconnect, disconnect and any Ledger or EIP-6963 paths the application supports. Check that analytics callbacks fire once and that keyboard focus returns after closing the dialog. + +For the v9-specific changes and examples, continue with [8.x → 9](migration-guide-8.x-to-9.md). diff --git a/docs/migration-guide-8.x-to-9.md b/docs/migration-guide-8.x-to-9.md new file mode 100644 index 00000000..b26c2268 --- /dev/null +++ b/docs/migration-guide-8.x-to-9.md @@ -0,0 +1,213 @@ +# Migration guide: Reef Knot 8.x → 9 + +This guide describes the v9 changes implemented in this branch. Version 9 and the UI skin packages must be published before the stable installation commands below can be used; use the corresponding prerelease versions when testing before release. + +For older integrations, start with [0.x → latest](migration-guide-0.x-to-latest.md). See the [headless API guide](headless-ui.md) for the complete UI contract. + +## What changes + +| Area | 8.x | 9 | +| ------------------------- | -------------------------------------------- | --------------------------------------------------------------- | +| Ready-made UI | Exported by `reef-knot` | Supplied by a separate UI skin | +| Core UI dependencies | Legacy Lido UI and styled-components | No UI kit, styled-components or CSS dependency | +| Modal configuration | Includes `buttonComponentsByConnectorId` | Data, links and callbacks only | +| Custom connection buttons | Registry of wallet-specific React components | `components.WalletButton` or headless hooks | +| Connection entry point | `useConnect().connect()` | `useConnectionFlow().startConnection()`; old call is deprecated | +| Custom interface | Connection behavior mixed into UI components | Public headless hooks and view contracts | + +Wagmi v3 was already introduced in Reef Knot 8.0. The minimum wagmi 3.6 and viem 2.50 requirements were introduced in 8.3; they are not new v9 requirements. If you are upgrading from an earlier 8.x release, update these dependencies too. The current development setup uses wagmi 3.6.21 and viem 2.51.3. Current wagmi types require [TypeScript 5.9.3 or later](https://wagmi.sh/react/typescript). + +## Choose and install one UI skin + +### Preserve the legacy appearance + +After the v9 release: + +```sh +yarn add reef-knot@^9 @reef-knot/ui-lido-legacy @lidofinance/lido-ui@^3.18.0 styled-components@^5.3.5 +``` + +Keep the existing legacy Lido UI ThemeProvider and styled-components SSR setup. The modal still accepts `darkThemeEnabled`, `buttonsFullWidth` and legacy modal props. + +### Use Lido App UI + +After the v9 release: + +```sh +yarn add reef-knot@^9 @reef-knot/ui-lido @lidofinance/lido-app-ui@1.4.0 +``` + +The Lido App UI skin requires React and React DOM 18. It does not require legacy `@lidofinance/lido-ui` or styled-components. Remove those dependencies only if no other part of the application uses them. Load both CSS exports from your global stylesheet entry, such as `_app.tsx` in Next.js Pages Router: + +```tsx +import '@lidofinance/lido-app-ui/index.css'; +import '@reef-knot/ui-lido/styles.css'; +``` + +The UI skin packages have their own release versions. Install a skin release compatible with Reef Knot 9; do not assume that its major version is also 9. Choose one skin for a normal application. + +### Use a custom interface + +Install `reef-knot@^9` and its connection peers without either UI skin. Implement the interface with public hooks and mount `ReefKnotUIProvider` inside `ReefKnotProvider`. See [the custom UI example](../apps/demo-react/features/wallet-ui/custom-modal.tsx) and the [headless API guide](headless-ui.md#custom-ui). + +## Update imports and configuration + +Version 9 removes all `reef-knot/*` subpath exports. Imports such as `reef-knot/core-react`, `reef-knot/wallets` and `reef-knot/web3-react` no longer resolve. The root entry also changes from namespace exports (`CoreReact`, `WalletsList`, `ConnectWalletModal`, `UIReact`, `Web3React`, `Connectors`) to named exports. + +| Old import path in 8.x | New import path or replacement in 9 | +| -------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| `reef-knot/core-react` | `reef-knot` for providers, configuration and connection hooks | +| `reef-knot/wallets` | `reef-knot` for `WalletsListEthereum` | +| `reef-knot/connectors` | `reef-knot` or `@reef-knot/ledger-connector` for the Ledger connectors | +| `reef-knot/types` | `reef-knot` for retained core types; removed visual types have no direct replacement | +| `reef-knot/connect-wallet-modal` | `@reef-knot/ui-lido-legacy` or `@reef-knot/ui-lido` for `ReefKnotWalletsModal`; `reef-knot` for configuration helpers | +| `reef-knot/ui-react` | `@reef-knot/ui-lido-legacy` for retained legacy UI primitives | +| `reef-knot/web3-react` | Removed; replace individual hooks as described [below](#replace-removed-web3-react-hooks) | + +Apply the same migration to direct imports from the former `@reef-knot/core-react`, `@reef-knot/wallets-list`, `@reef-knot/types`, `@reef-knot/connect-wallet-modal`, `@reef-knot/ui-react` and `@reef-knot/web3-react` packages. These packages are not continued as part of v9. + +Before: + +```tsx +import { ReefKnotProvider, getDefaultConfig } from 'reef-knot/core-react'; +import { + ReefKnotWalletsModal, + getDefaultWalletsModalConfig, +} from 'reef-knot/connect-wallet-modal'; +``` + +After, for the legacy skin: + +```tsx +import { + ReefKnotProvider, + getDefaultConfig, + getDefaultWalletsModalConfig, +} from 'reef-knot'; +import { ReefKnotWalletsModal } from '@reef-knot/ui-lido-legacy'; +``` + +For the Lido App UI skin, import the modal from `@reef-knot/ui-lido` instead. UI primitives such as `Modal`, `Button` and `ConnectButtonBase`, and their visual prop types, move to the legacy skin if your application still uses them. `ButtonComponentsByConnectorId`, `ConnectWalletButtonProps`, `WALLETS_MODAL_BUTTON_COMPONENTS_DEFAULT` and wallet-specific `Connect*` components are removed. + +Configuration helpers remain in the core. Remove `buttonComponentsByConnectorId` from arguments passed to `getDefaultConfig` and from modal configuration; `getDefaultWalletsModalConfig()` no longer returns it. Keep your wallet catalog, list settings, `linkTerms`, `linkPrivacyNotice` and connection callbacks. + +`linkDontHaveWallet` is also removed from modal configuration in v9. The legacy skin no longer renders the configurable “Don't have a wallet?” link from 8.x, and neither skin provides a replacement configuration option. Remove this property from your configuration. If your application still needs the link, render it in your application or add it through a custom `components.WalletPicker` view. + +The root `reef-knot` entry point is the supported import path for core APIs. Update old package or deep imports instead of importing files from `reef-knot/dist` or `reef-knot/src`. + +## Keep one provider stack + +The provider structure remains the same: + +```tsx + + + + + {children} + + + +``` + +This example uses the legacy skin. A ready-made modal creates its own `ReefKnotUIProvider`; do not add a second UI provider around it. Keep `getDefaultConfig` results and the QueryClient stable, and retain `reconnectOnMount={false}` so wagmi does not duplicate Reef Knot's reconnect flow. + +With the Lido App UI skin, replace the modal props with: + +```tsx + +``` + +`theme` is required and should follow the current application theme. The skin applies `data-lido-theme` inside its portal and inherits the page's App UI CSS variables. Switching to this skin does not automatically restyle the rest of the application. + +## Update the connection entry point + +Before: + +```tsx +import { useConnect } from 'reef-knot/core-react'; +const { connect } = useConnect(); +const result = await connect(); // { success: boolean } +``` + +After: + +```tsx +import { useConnectionFlow } from 'reef-knot'; +const { startConnection } = useConnectionFlow(); +const result = await startConnection(); // { connected: boolean } +``` + +This starts eager connection or opens the picker and waits for the scenario's result. The result field is renamed from `success` to `connected`. The rename also applies to `useConnect().connect()`, `openModalAsync()` and `closeModal()`. `useConnect().connect()` remains available as a deprecated compatibility wrapper, so this rename can be migrated separately from the required UI import changes. Wagmi's `useConnect` is unchanged and does not replace the Reef Knot entry point. + +## Replace removed web3-react hooks + +`useWeb3` and `useSupportedChains` are removed in v9, including their exports from `reef-knot/web3-react` and `@reef-knot/web3-react`. Neither hook moves to the root entry point. + +Replace `useWeb3` by responsibility: read address, chain ID and connection status with `useConnection` from `wagmi`, access the wallet client with `useWalletClient` from `wagmi`, and use Reef Knot's `useConnectionFlow` and `useDisconnect` for its connection scenario and storage cleanup. See the [field-by-field migration guidance](migration-guide-0.x-to-latest.md#4-replace-useweb3-by-responsibility). The old shim reported `active: false` and `chainId: undefined` for unsupported chains; wagmi exposes the actual chain ID and connection status, so preserve that filtering explicitly if your application relies on it. + +Replace `useSupportedChains` with wagmi's `useConfig().chains` and `useConnection().chainId`: + +```tsx +import { useConfig, useConnection } from 'wagmi'; + +const { chains } = useConfig(); +const { chainId } = useConnection(); +const isUnsupported = !chainId || !chains.some((chain) => chain.id === chainId); +const supportedChains = chains.map((chain) => ({ + chainId: chain.id, + name: chain.name, +})); +``` + +This preserves the previous hook's result shape, including treating a missing chain ID as unsupported. If you need the helper in multiple components, keep it in your application; see [the demo's local implementation](../apps/demo-react/hooks/useSupportedChains.ts). + +## Replace custom connect buttons + +Remove the old registry and use `components.WalletButton`. The replacement receives `WalletButtonViewProps` from `reef-knot`: + +```tsx +import type { WalletButtonViewProps } from 'reef-knot'; + +function CustomWalletButton({ + walletId, + name, + disabled, + isLoading, + onConnect, +}: WalletButtonViewProps) { + return ( + + ); +} + +// Example with the Lido App UI skin: +; +``` + +Use `walletId` to choose wallet-specific visuals when necessary. Call the provided `onConnect` rather than reimplementing connector selection, consent checks, loading, reconnect persistence or connection callbacks. Legacy `onConnectStart` / `onConnectSuccess` button props are removed; application callbacks belong in the modal config. + +Other replaceable parts include `ModalContainer`, `Terms`, `WalletPicker`, `EagerConnect`, `Requirements`, `EIP6963Picker` and the three Ledger screens. Omitted parts keep the skin's defaults. Replacing a whole screen gives your application responsibility for composing that screen; see [component customization](headless-ui.md#replace-visual-parts). + +## Connection state and validation + +The storage keys for Terms acceptance, reconnect and Ledger derivation paths are unchanged. The migration does not intentionally clear accepted Terms or remembered wallets. Keep the existing `onConnectStart`, `onConnectSuccess`, `onAutoConnect` and `onReconnect` configuration callbacks as applicable. + +Run your application's TypeScript check and production build, then verify connection, cancellation, errors/retry, reconnect and disconnect. For custom views, also check Terms gating, nested screen navigation, Ledger/EIP-6963 where used, keyboard focus, mobile layout and both themes. Ensure there is only one mounted modal implementation and callbacks fire once. diff --git a/docs/migration-guide.md b/docs/migration-guide.md deleted file mode 100644 index 2d1a8f94..00000000 --- a/docs/migration-guide.md +++ /dev/null @@ -1,132 +0,0 @@ -# Migration guide from 0.x to the current version - -This guide provides detailed instructions and best practices for migrating your project from Reef Knot v0.x to the current version. -It covers breaking changes, updated dependencies, and new component implementations to ensure a smooth transition. -Use this guide to update your project efficiently while leveraging the latest features and improvements in Reef Knot. - -If you're looking for instructions to install Reef Knot from scratch, refer to the [README](README.md#installation). - -#### Note about wagmi library - -Before you begin, you may want to familiarize yourself with the following: - -- [wagmi library](https://wagmi.sh/) -- [viem library](https://viem.sh/) - -Historically, Reef Knot v0.x-v1.x utilized both `web3-react` v6 and `wagmi` v0.x at the same time. -Some wallets relied on the legacy `web3-react` code, while others were transitioned to `wagmi`. - -The current version of Reef Knot uses `wagmi` for all wallet connections. - -## Dependencies - -### 1. Update TS to v5 - -`wagmi` types require TypeScript >=5.0.4. For more details, refer to the [wagmi TypeScript documentation](https://wagmi.sh/react/typescript). - -Since Reef Knot also depends on TypeScript v5, you will need to upgrade your TypeScript version if your dApp is currently using TypeScript v4. - -### 2. Update wagmi to v2, add viem, @tanstack/react-query - -There is a chance, that your app is using wagmi v0.12.x, which is not maintained anymore. - -The current version of Reef Knot is built on wagmi v2.x. -There were a lot of [breaking changes between 0.x and 1.x versions](https://1.x.wagmi.sh/react/migration-guide), -and then [between 1.x and 2.x](https://wagmi.sh/react/guides/migrate-from-v1-to-v2). - -The good news is that most of this changes were handled inside reef-knot and doesn't require a lot of actions on a dApp side. - -Use [manual installation instructions](https://wagmi.sh/react/getting-started#manual-installation) from wagmi docs for details. - -Basically, you will need to: - -1. Update the `wagmi` dependency to the latest 2.x version -2. Add `viem` v2.x and `@tanstack/react-query` v5.x -3. Update config for `WagmiProvider` - -### 3. Remove web3-react dependency - -web3-react is a library similar to wagmi, previously used to manage wallet connections in reef-knot. - -At one point, Reef Knot partially used web3-react for some wallets and wagmi for others. -However, Reef Knot has since transitioned to using wagmi exclusively for all wallet connections. - -As a result, the web3-react dependency is no longer needed and should be completely removed from your project. - -### 4. React v18 - -Reef Knot v0.x was built using React v17. The current version of Reef Knot is now based on React v18. -If your app is using React v17, you will likely need to upgrade it to React v18. - -### 5. Update reef-knot package - -Use the latest available version – v7.x at the moment of writing. - -### 6. reef-knot subpackages - -Ensure that the project depends on 'reef-knot' package only and there are no dependencies on '@reef-knot/\*' subpackages. - -## Code changes - -### 1. reef-knot imports - -Ensure your code does not contain direct imports from Reef Knot subpackages. If found, simply remove the `@` sign to correct the import. - -**BAD:** - -```ts -import { useWeb3 } from '@reef-knot/web3-react'; -``` - -**GOOD:** - -```ts -import { useWeb3 } from 'reef-knot/web3-react'; -``` - -### 2. Remove deprecated code - -1. Search your project's code for the `WalletsModalForEth` component and remove it completely, as the Wallet Connection Modal has been updated. -2. Search your project's code for the `ProviderWeb3` React Context Provider and remove it if it exists. -3. If your app depends on reef-knot v2-v5, then remove the `ReefKnot` React Context Provider and the `AutoConnect` component. - -### 3. Set Up Reef Knot - -Follow the latest [installation instructions](https://github.com/lidofinance/reef-knot/blob/main/README.md#installation) to properly set up the updated version of Reef Knot in your project. - -## Other Notes - -### Legacy Lido JS SDK - -The Lido JS SDK is a deprecated legacy web3 development kit for Lido projects. - -If your app still relies on it, you will need to configure its `ProviderSDK` React Context Provider. -This configuration may require adjustments due to the update to wagmi v2. - -For an example of how to configure `ProviderSDK` in combination with wagmi v2 and ethers.js, -refer to the Lido ETH Stake Widget: [ProviderSDK Configuration Example](https://github.com/lidofinance/ethereum-staking-widget/blob/c5bac490f92826abe9c12a34e751b004eca679ee/modules/web3/web3-provider/sdk-legacy.tsx). - -### NoSSRWrapper - -If you are using reef-knot v0.x, then, most likely, your code already has some NoSSRWrapper usage. -This is still needed. For the additional info, see the [NoSSRWrapper paragraph in README](README.md#nossrwrapper). - -### useWeb3 hook deprecation - -The `useWeb3` hook provides various details about the connected wallet. -There is a high chance that it is used extensively throughout your application. - -Previously, it played a crucial role by returning information from either the web3-react or wagmi libraries, -depending on the connected wallet. However, since the web3-react library has been removed from Reef Knot, -the current version is based solely on wagmi. - -As a result, the useWeb3 hook now acts as a redundant proxy for wagmi hooks. While it will continue to function, -it is recommended to replace it with standard wagmi hooks to avoid unnecessary abstractions. - -### Additional references - -The most significant changes were introduced during the v2 and v6 updates. -You can use these PRs as references for updating Reef Knot versions: - -- [Update to v2](https://github.com/lidofinance/ethereum-staking-widget/pull/265/files) -- [Update to v6](https://github.com/lidofinance/reef-knot/pull/183/files) diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..479734a4 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,212 @@ +import { fixupPluginRules } from '@eslint/compat'; +import js from '@eslint/js'; +import comments from 'eslint-plugin-eslint-comments'; +import react from 'eslint-plugin-react'; +import vitest from '@vitest/eslint-plugin'; +import { defineConfig, globalIgnores } from 'eslint/config'; +import turbo from 'eslint-config-turbo/flat'; +import imports from 'eslint-plugin-import'; +import a11y from 'eslint-plugin-jsx-a11y'; +import prettier from 'eslint-plugin-prettier/recommended'; +import promise from 'eslint-plugin-promise'; +import hooks from 'eslint-plugin-react-hooks'; +import sonar from 'eslint-plugin-sonarjs'; +import unicorn from 'eslint-plugin-unicorn'; +import globals from 'globals'; +import { globSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import ts from 'typescript-eslint'; + +const sourceFiles = ['packages/**/*.{ts,tsx}', 'apps/demo-react/**/*.{ts,tsx}']; +const testFiles = [ + 'packages/**/*.test.{ts,tsx}', + 'packages/**/test-ui/**/*.{ts,tsx}', +]; +const projects = [ + 'packages/*/tsconfig.json', + 'packages/wallets/*/tsconfig.json', + 'packages/connectors/*/tsconfig.json', + 'apps/demo-react/tsconfig.json', + 'tsconfig.eslint.json', +]; +const configPackageDirs = [ + import.meta.dirname, + ...globSync( + [ + 'packages/*/package.json', + 'packages/wallets/*/package.json', + 'packages/connectors/*/package.json', + ], + { cwd: import.meta.dirname }, + ).map((file) => dirname(resolve(import.meta.dirname, file))), +]; + +export default defineConfig( + globalIgnores([ + '**/node_modules/**', + '**/dist/**', + '**/coverage/**', + '**/.next/**', + '**/out/**', + '**/build/**', + '**/.turbo/**', + '**/.yarn/**', + '**/.pnp.*', + 'apps/demo-react/public/**', + 'apps/demo-react/next-env.d.ts', + 'playwright-tests/**', + 'turbo/generators/wallet/templates/**', + ]), + { + files: ['**/*.{js,mjs,cjs,ts,tsx}'], + extends: [js.configs.recommended], + languageOptions: { globals: globals.node }, + plugins: { + 'eslint-comments': fixupPluginRules(comments), + promise, + sonarjs: sonar, + unicorn, + }, + rules: { + ...comments.configs.recommended.rules, + 'promise/no-return-wrap': 'error', + 'promise/param-names': [ + 'warn', + { + resolvePattern: '^_?(resolve)$|^_$', + rejectPattern: '^_?(reject)$|^_$', + }, + ], + 'sonarjs/no-all-duplicated-branches': 'error', + 'sonarjs/no-collection-size-mischeck': 'error', + 'sonarjs/no-duplicated-branches': 'error', + 'sonarjs/no-element-overwrite': 'error', + 'sonarjs/no-empty-collection': 'error', + 'sonarjs/no-extra-arguments': 'error', + 'sonarjs/no-gratuitous-expressions': 'error', + 'sonarjs/no-identical-conditions': 'error', + 'sonarjs/no-identical-expressions': 'error', + 'sonarjs/no-ignored-return': 'error', + 'no-unreachable-loop': 'error', + 'sonarjs/no-unused-collection': 'error', + 'sonarjs/no-use-of-empty-return-value': 'error', + 'unicorn/no-document-cookie': 'error', + 'unicorn/no-invalid-remove-event-listener': 'error', + 'unicorn/no-new-buffer': 'error', + 'unicorn/no-object-as-default-parameter': 'error', + 'unicorn/no-thenable': 'error', + 'unicorn/require-array-join-separator': 'error', + 'unicorn/require-number-to-fixed-digits-argument': 'error', + 'unicorn/throw-new-error': 'error', + }, + }, + { + files: sourceFiles, + extends: [ts.configs.recommendedTypeChecked], + languageOptions: { + globals: { ...globals.node, ...globals.browser }, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + plugins: { import: imports }, + settings: { + 'import/resolver': { + typescript: { + project: projects.map( + (project) => `${import.meta.dirname}/${project}`, + ), + alwaysTryTypes: true, + noWarnOnMultipleProjects: true, + }, + }, + }, + rules: { + ...imports.flatConfigs.recommended.rules, + ...imports.flatConfigs.typescript.rules, + 'import/no-extraneous-dependencies': 'error', + 'import/no-cycle': ['error', { maxDepth: 1 }], + 'import/no-named-as-default': 'off', + 'import/no-named-as-default-member': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, + ], + '@typescript-eslint/no-shadow': [ + 'error', + { ignoreOnInitialization: true }, + ], + '@typescript-eslint/switch-exhaustiveness-check': 'error', + // Wagmi connector contracts require async methods even for synchronous implementations. + '@typescript-eslint/require-await': 'off', + }, + }, + { + files: ['apps/demo-react/**/*.{ts,tsx}'], + rules: { + // Preserve the demo's original override and its intentionally shadowed input values. + '@typescript-eslint/no-shadow': 'off', + }, + }, + { + files: sourceFiles, + plugins: { react, 'react-hooks': hooks }, + settings: { react: { version: '18.2.0' } }, + rules: { + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + // TypeScript checks props and ESLint 10 tracks JSX references itself. + 'react/prop-types': 'off', + // Preserve existing anonymous render helpers; display names are a naming policy. + 'react/display-name': 'off', + 'react/jsx-uses-react': 'off', + 'react/jsx-uses-vars': 'off', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'error', + }, + }, + { + files: ['packages/**/*.tsx', 'apps/demo-react/**/*.tsx'], + plugins: { 'jsx-a11y': a11y }, + rules: a11y.configs.recommended.rules, + settings: { 'jsx-a11y': { polymorphicPropName: 'as' } }, + }, + { + files: testFiles, + languageOptions: { + parserOptions: { + projectService: false, + project: './tsconfig.eslint.json', + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + files: ['packages/**/*.test.{ts,tsx}'], + extends: [vitest.configs.recommended], + }, + { + files: ['**/*.config.ts', 'turbo/**/*.ts'], + extends: [ts.configs.recommended, ts.configs.disableTypeChecked], + plugins: { import: imports }, + rules: { + // Build tools are intentionally installed once at the workspace root. + 'import/no-extraneous-dependencies': [ + 'error', + { + packageDir: configPackageDirs, + }, + ], + }, + }, + { + files: ['packages/**/*.{ts,tsx}'], + extends: [turbo], + }, + prettier, +); diff --git a/package.json b/package.json index 53bdad85..f45b953b 100644 --- a/package.json +++ b/package.json @@ -17,39 +17,43 @@ "lint": "turbo run lint", "test": "turbo run test", "typecheck": "turbo run typecheck --continue", - "check-packages": "turbo run typecheck lint test --filter='./packages/**/*'", + "check-packages": "turbo run typecheck lint test --filter='./packages/**/*' && yarn check-ui-types", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "new-wallet": "turbo gen wallet" + "new-wallet": "turbo gen wallet", + "check-ui-types": "tsc -p tsconfig.ui-tests.json --noEmit" }, "devDependencies": { - "@lidofinance/eslint-config": "^0.63.0", + "@eslint/compat": "2.1.1", + "@eslint/js": "10.0.1", "@lidofinance/multi-semantic-release": "^1.0.2", - "@next/eslint-plugin-next": "^13.5.11", "@turbo/gen": "2.10.12", "@types/react": "18.2.45", "@types/react-dom": "18.2.17", "@types/styled-components": "5.1.12", - "eslint": "8.57.0", - "eslint-config-airbnb": "19.0.4", - "eslint-config-prettier": "9.1.2", - "eslint-config-turbo": "2.10.12", - "eslint-import-resolver-typescript": "3.10.1", + "@typescript-eslint/eslint-plugin": "8.71.1", + "@typescript-eslint/parser": "8.71.1", + "@typescript/native": "npm:typescript@7.0.2", + "@vitest/eslint-plugin": "1.6.27", + "eslint": "10.12.0", + "eslint-config-prettier": "10.1.8", + "eslint-config-turbo": "2.11.7", + "eslint-import-resolver-typescript": "4.4.5", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.32.0", - "eslint-plugin-jest": "27.9.0", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-prettier": "5.5.6", - "eslint-plugin-promise": "6.6.0", + "eslint-plugin-promise": "7.3.0", "eslint-plugin-react": "7.37.5", - "eslint-plugin-react-hooks": "4.6.2", - "eslint-plugin-sonarjs": "0.25.1", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-react-hooks": "7.1.1", + "eslint-plugin-sonarjs": "4.2.2", + "eslint-plugin-unicorn": "77.0.0", + "globals": "17.13.0", "prettier": "^3.9.6", - "tsdown": "0.22.14", + "tsdown": "0.23.1", "tslib": "2.8.1", "turbo": "latest", - "typescript": "~5.9", - "typescript-eslint": "^7.9.0" + "typescript": "npm:@typescript/typescript6@6.0.2", + "typescript-eslint": "8.71.1" }, "release": { "branches": [ @@ -74,7 +78,12 @@ ] }, "multi-release": { - "sequentialInit": true + "sequentialInit": true, + "deps": { + "bump": "override", + "prefix": "", + "release": "patch" + } }, "resolutions": { "basic-ftp": "^5.3.1", @@ -90,7 +99,7 @@ "undici@^7.0.0": "^7.29.0" }, "engines": { - "node": ">=24.0.0" + "node": "^24.11.0 || >=26.0.0" }, "packageManager": "yarn@4.17.1" } diff --git a/packages/build-config/index.d.ts b/packages/build-config/index.d.ts index 0d8bcd8d..de71792d 100644 --- a/packages/build-config/index.d.ts +++ b/packages/build-config/index.d.ts @@ -1,6 +1,8 @@ import type { UserConfig } from 'tsdown'; -export declare function defineStandardConfig(overrides?: UserConfig): UserConfig; +export declare function defineStandardConfig( + overrides?: UserConfig, +): UserConfig; export declare function defineSvgConfig( svgrOptions?: Record, overrides?: UserConfig, diff --git a/packages/build-config/index.js b/packages/build-config/index.js index 502226fa..70685adb 100644 --- a/packages/build-config/index.js +++ b/packages/build-config/index.js @@ -1,9 +1,20 @@ // Using js instead of ts to avoid build step. Otherwise, build-config would need to build itself (circular dependency). // @ts-check -import { execSync } from 'node:child_process'; +import { createRequire } from 'node:module'; +import { dirname, join } from 'node:path'; import svgr from '@svgr/rollup'; +const require = createRequire(import.meta.url); +// `typescript` supplies the TS 6 API; explicitly select the native TS 7 alias. +const { default: getNativeCompilerPath } = require( + join( + dirname(require.resolve('@typescript/native/package.json')), + 'lib/getExePath.js', + ), +); +const nativeCompilerPath = getNativeCompilerPath(); + // In watch mode all packages start simultaneously, so dist/ must not be cleaned // on startup — doing so would create a race condition where tsc in one package // runs while another package's .d.ts files are temporarily deleted. @@ -21,34 +32,6 @@ function isExternal(id) { return !id.startsWith('.') && !id.startsWith('/') && !id.startsWith('\0'); } -/** - * Runs `tsc --emitDeclarationOnly` after each build via the `build:done` hook. - * - * rolldown-plugin-dts (used by tsdown's `dts: true`) has a known bug where it - * drops `export default` from generated `.d.ts` files, regardless of whether - * the oxc or tsc transformer is used. Running tsc directly as a CLI subprocess - * avoids this issue entirely. - * - * Type errors are intentionally swallowed here — `yarn typecheck` is the proper - * gate for type errors; the build step should always produce output. - * - * @returns {Partial} - */ -function tscDeclarationsHook() { - return { - 'build:done': () => { - try { - execSync( - 'tsc --noEmit false --emitDeclarationOnly --noEmitOnError false --declarationMap --outDir dist', - { stdio: 'inherit' }, - ); - } catch { - // tsc exits 1 on type errors; surfaced by `yarn typecheck` instead - } - }, - }; -} - /** * @param {Record} [overrides] * @returns {import('tsdown').UserConfig} @@ -61,12 +44,15 @@ export function defineStandardConfig(overrides = {}) { target: 'es2020', platform: 'browser', unbundle: true, - // rolldown-plugin-dts drops `export default` — use tsc for declarations instead, see hooks - dts: false, + tsconfig: 'tsconfig.json', + dts: { + generator: 'tsgo', + tsgo: { path: nativeCompilerPath }, + sourcemap: true, + }, clean: !isWatchMode, // treat all non-relative imports as external - external: isExternal, - hooks: tscDeclarationsHook(), + deps: { neverBundle: isExternal, resolveDepSubpath: true }, ...overrides, }; } diff --git a/packages/connect-wallet-modal/.eslintrc.json b/packages/connect-wallet-modal/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/connect-wallet-modal/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/connect-wallet-modal/CHANGELOG.md b/packages/connect-wallet-modal/CHANGELOG.md deleted file mode 100644 index 474a1995..00000000 --- a/packages/connect-wallet-modal/CHANGELOG.md +++ /dev/null @@ -1,705 +0,0 @@ -# @reef-knot/connect-wallet-modal - -## 8.4.0 - -- Updated @ledgerhq/hw-app-eth to 7.8.12, @ledgerhq/hw-transport to 6.35.7, @ledgerhq/hw-transport-webhid to 6.36.0, @ledgerhq/iframe-provider to 0.4.3 - -## 8.3.0 - -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update peerDependencies requirements: viem >=2.50, wagmi >=3.6 -- Update WalletConnect connector to support new provider API with providersStore - -## 8.2.0 - -- Add EIP-6963 browser wallet provider selection when multiple injected providers are detected. -- Add a browser wallet icon grid that reflects detected providers and falls back to known browser wallet icons. -- Update the browser wallet connection flow to connect to the selected EIP-6963 provider, with fallback to the legacy injected provider when no EIP-6963 providers are available. - -## 8.1.1 - -- Add noopener and noreferrer to WalletConnect redirect popup - -## 8.1.0 - -- Add Anchorage Digital wallet support - -## 8.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 -- Removed wallet adapters: binanceWallet, coinbase, trust, exodus, brave, ctrl, coin98 - -## 7.3.0 - -### Minor Changes - -- Adds ability to pass onAutoConnect and onReconnect callbacks to the reef-knot config -- Minor fixes and tech updates - -## 7.2.0 - -### Minor Changes - -- Update viem to v2.23 and wagmi to v2.14, so the @coinbase/wallet-sdk would be updated too, which fixes a dependabot issue - -### Patch Changes - -- @reef-knot/wallets-list@4.1.2 - -## 7.1.0 - -### Minor Changes - -- Add Ctrl wallet, rm XDEFI wallet (rebranded into Ctrl) - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@4.1.0 - -## 7.0.1 - -### Patch Changes - -- Ledger HID connection on slow network fixed - -## 7.0.0 - -### Major Changes - -- Metrics config refactored, replaced with certain actions callbacks - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@6.0.0 - - @reef-knot/types@4.0.0 - - @reef-knot/web3-react@6.0.0 - - @reef-knot/wallets-list@4.0.0 - -## 6.0.2 - -### Patch Changes - -- Ledger HID metrics fixed - -## 6.0.1 - -### Patch Changes - -- Coinbase Smart Wallet displayed by default - -## 6.0.0 - -### Major Changes - -- reef-knot setup rework - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@5.0.0 - - @reef-knot/types@3.0.0 - - @reef-knot/web3-react@5.0.0 - - @reef-knot/wallets-list@3.0.0 - -## 5.5.4 - -### Patch Changes - -- accbcde: viem and wagmi versions updated with flexible declarations - - @reef-knot/wallets-list@2.3.1 - -## 5.5.3 - -### Patch Changes - -- Hotfix: wallets metrics in WalletsModal - -## 5.5.2 - -### Patch Changes - -- 3bfcb7c: Fix modals props passing - -## 5.5.1 - -### Patch Changes - -- Fix the issue with paused loading animation for ConnectButtonLoader - -## 5.5.0 - -### Minor Changes - -- Add the "loading" state for WC and Binance wallet connection buttons; -- Fix the "retry" button for some cases in the Ledger HID connection modal; -- Show a loading spinner in the Ledger modal during ledger packages loading; -- Fix the issue with passing onClickWalletsLess, onClickWalletsMore props; - -## 5.4.0 - -### Minor Changes - -- Coinbase smart wallet connector - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@2.3.0 - -## 5.3.3 - -### Patch Changes - -- Fix the issue with multiple clicks on ConnectBinance button - -## 5.3.2 - -### Patch Changes - -- Binance Wallet: actually use explicitly passed deeplink on mobiles -- Reorder wallets - - @reef-knot/wallets-list@2.2.2 - -## 5.3.1 - -### Patch Changes - -- Binance wallet: move up in the wallets display order, add deeplink, add detector fn - - @reef-knot/wallets-list@2.2.1 - -## 5.3.0 - -### Minor Changes - -- Add Binance Web3 Wallet - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@2.2.0 - -## 5.2.2 - -### Patch Changes - -- Wallets modal: metrics props pass fixed - -## 5.2.1 - -### Patch Changes - -- Wallet modal show more/less wallets metrics added - -## 5.2.0 - -### Minor Changes - -- ad07297: Minor update of ledger libs - -## 5.1.1 - -### Patch Changes - -- Wagmi version updated - - @reef-knot/wallets-list@2.0.1 - -## 5.1.0 - -### Minor Changes - -- Remove WC warning banner - -## 5.0.2 - -### Patch Changes - -- Wallets modal metrics fixed - -## 5.0.1 - -### Patch Changes - -- Connect buttons type attribute fixed - -## 5.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -### Patch Changes - -- Updated dependencies - - @reef-knot/ledger-connector@4.0.0 - - @reef-knot/wallets-helpers@2.0.0 - - @reef-knot/wallets-list@2.0.0 - - @reef-knot/core-react@4.0.0 - - @reef-knot/web3-react@4.0.0 - - @reef-knot/ui-react@2.0.0 - - @reef-knot/types@2.0.0 - -## 4.2.0 - -### Minor Changes - -- a6ca608: Add deeplinks support - -### Patch Changes - -- @reef-knot/wallets-list@1.13.3 - -## 4.1.2 - -### Patch Changes - -- Updated dependencies - -## 4.1.1 - -### Patch Changes - -- connect wallet modal safari styles fixed - -## 4.1.0 - -### Minor Changes - -- Make it possible for wallet detectors to be async; -- Improve Safe wallet detection; - -### Patch Changes - -- @reef-knot/wallets-list@1.13.1 - -## 4.0.0 - -### Major Changes - -- connect-wallet-modal ui and config updated - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@1.13.0 - -## 3.0.2 - -### Patch Changes - -- 8873ffb: fixed leger modal not closing main modal - -## 3.0.1 - -### Patch Changes - -- fix Connect wallet button in EagerConnectModal - -## 3.0.0 - -### Major Changes - -- Rework modals interface, add useConnect hook for connection - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@3.0.0 - - @reef-knot/web3-react@3.0.0 - -## 2.1.0 - -### Minor Changes - -- 85b3f79: - - rework getUnsupportedChainError, hide mumbai network in the error - - (web3-react) fix logic of useConnectorError - - (web3-react) deprecate useConnectorInfo, useDisconnect - - (core-react) rework and add hooks: useConnectorInfo, useDisconnect, useEagerConnect - - (reef-knot) add connectors export as "Connectors" - -## 2.0.0 - -### Minor Changes - -- 1046886: Support autoConnectOnly wallet adapters - -### Patch Changes - -- Updated dependencies [1046886] - - @reef-knot/ledger-connector@3.0.0 - - @reef-knot/core-react@2.0.0 - - @reef-knot/web3-react@2.0.0 - -## 1.17.1 - -### Patch Changes - -- Update ledgerhq packages - -## 1.17.0 - -### Minor Changes - -- 253796d: Use MetaMask and generic browser extension wallet adapters. Do some refactoring. - -## 1.16.0 - -### Minor Changes - -- Use Ledger hid wallet adapter, based on wagmi - -## 1.15.0 - -### Minor Changes - -- lido-ui version as peer dependency - -## 1.14.0 - -### Minor Changes - -- lido-ui and react versions updated - -## 1.13.0 - -### Minor Changes - -- Rework Coinbase to use Wallet Adapter - -## 1.12.0 - -### Minor Changes - -- Rework XDEFI, Trust, imToken to use Wallet Adapters and wagmi - -## 1.11.1 - -### Patch Changes - -- Add custom connectors for injected wallets, which fixes an issue with autoconnection after page reload. - -## 1.11.0 - -### Minor Changes - -- Remove MathWallet related code - -## 1.10.0 - -### Minor Changes - -- Handle connection errors in AcceptTermsModal - -## 1.9.0 - -### Minor Changes - -- Remove Brave, Coin98, Opera, Gamestop wallets unneeded legacy code - -## 1.8.3 - -### Patch Changes - -- Remove 'themeOverride' deprecated prop from Select - -## 1.8.2 - -### Patch Changes - -- Remove lido-ui peer dependency - -## 1.8.1 - -### Patch Changes - -- Depend on @lidofinance/lido-ui v3.14.1 strictly. 3.14.1 has required "type: module" field, in 3.14.2 the field is removed. - -## 1.8.0 - -### Minor Changes - -- Rework direct Ledger hardware connection UI - -## 1.7.0 - -### Minor Changes - -- e2074ed: Make Coin98 wallet to use Wallet Adapter API - -## 1.6.2 - -### Patch Changes - -- fix: connection rejection logic during mobile browser autoconnect - -## 1.6.1 - -### Patch Changes - -- Move TERMS_ACCEPTANCE_LS_K const into core-react package - -## 1.6.0 - -### Minor Changes - -- e654dc5: Remove deprecated "icons" field from Wallet Adapater API -- 217c144: Show "Accept Terms" Modal for Ledger Live, Safe, dapp browsers - -### Patch Changes - -- 48d8c4b: Update wagmi to 0.12.19 - -## 1.5.1 - -### Patch Changes - -- e6e579e: wagmi 0.12.18 -- e6e579e: Rework and fix WalletConnect connection via pairing URI - -## 1.5.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/web3-react@1.3.0 - -## 1.4.3 - -### Patch Changes - -- Add a notification about WC v2 issues -- Updated dependencies - - @reef-knot/core-react@1.4.2 - - @reef-knot/ui-react@1.0.4 - -## 1.4.2 - -### Patch Changes - -- Fix: rework getWalletConnectConnector and its usage (reduce the amount of WC connectors), remove WC v1 imports and usage - -## 1.4.1 - -### Patch Changes - -- Update wagmi to v0.12.17 -- Updated dependencies - - @reef-knot/core-react@1.4.1 - - @reef-knot/types@1.2.1 - - @reef-knot/web3-react@1.2.1 - -## 1.4.0 - -### Minor Changes - -- Explicitly pass chains to wagmi connectors, update wagmi to v0.12.16 - -### Patch Changes - -- Updated dependencies - -## 1.3.1 - -### Patch Changes - -- Remove walletConnectProjectId prop from WalletsModal; Add display_uri handler for WalletConnect v2 (connection without qr modal) -- Remove circular deps -- Updated dependencies - - @reef-knot/types@1.1.1 - - @reef-knot/core-react@1.3.1 - - @reef-knot/web3-react@1.1.1 - -## 1.3.0 - -### Minor Changes - -- faa8815: Update wagmi to v0.12 -- faa8815: Update Wallet Adapter API for WalletConnect - -### Patch Changes - -- Updated dependencies [faa8815] - -## 1.2.0 - -### Patch Changes - -- @reef-knot/core-react@1.2.0 - -## 1.1.1 - -### Patch Changes - -- Improve the selection of the OKX wallet position - -## 1.1.0 - -### Patch Changes - -- Improve ConnectButtonIconStyle: height, radius -- Move OKX wallet to the second place in the wallet connection buttons list -- Updated dependencies - - @reef-knot/core-react@1.1.0 - -## 1.0.8 - -### Patch Changes - -- Tally => Taho in conflict checks -- Reset the Terms acceptance for all users -- Updated dependencies - - @reef-knot/web3-react@1.0.6 - -## 1.0.7 - -### Patch Changes - -- Update Terms text -- Updated dependencies - - @reef-knot/ui-react@1.0.3 - -## 1.0.6 - -### Patch Changes - -- Replace Tally legacy connector with Taho wallet adapter -- Fix: duplicated "Injected" react element key for wallet connection buttons -- Updated dependencies - - @reef-knot/web3-react@1.0.5 - -## 1.0.5 - -### Patch Changes - -- Support custom connectors for wallet adapters. Improve getWalletsButtons(). -- Updated dependencies - - @reef-knot/core-react@1.0.1 - - @reef-knot/web3-react@1.0.4 - - @reef-knot/ui-react@1.0.2 - -## 1.0.4 - -### Patch Changes - -- Remove wagmiChains props, make walletConnectProjectId optional -- Updated dependencies - - @reef-knot/web3-react@1.0.3 - -## 1.0.3 - -### Patch Changes - -- Add checks that `window` is defined - -## 1.0.2 - -### Patch Changes - -- Set typescript compilerOptions.jsx = "react" -- Updated dependencies - - @reef-knot/ui-react@1.0.1 - - @reef-knot/web3-react@1.0.2 - -## 1.0.1 - -### Patch Changes - -- Fix error with useLocalStorage hook - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes - -### Patch Changes - -- Updated dependencies - - @reef-knot/web3-react@1.0.0 - - @reef-knot/core-react@1.0.0 - - @reef-knot/ui-react@1.0.0 - - @reef-knot/wallets-icons@1.0.0 - - @reef-knot/wallets-list@1.0.0 - -## 0.5.2 - -### Patch Changes - -- Fix scrollbar padding and margin -- Support dark color theme -- ua-parser-js 1.0.33 - -## 0.5.1 - -### Patch Changes - -- Improve the modal's scrollbar - -## 0.5.0 - -### Minor Changes - -- Improve the modal's styles, rework scroll behavior - -### Patch Changes - -- Updated dependencies - - @reef-knot/ui-react@0.2.0 - -## 0.4.0 - -### Minor Changes - -- Add Zerion wallet - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-icons@0.2.0 - -## 0.3.0 - -### Minor Changes - -- Add Metrics Events for clicks on wallets connection buttons - -## 0.2.0 - -### Minor Changes - -- Add Metrics Events support - -### Patch Changes - -- Updated dependencies - - @reef-knot/web3-react@0.2.0 - -## 0.1.1 - -### Patch Changes - -- Add explanation for Ledger direct connection error - -## 0.1.0 - -### Minor Changes - -- Support Trust Wallet browser extension - -### Patch Changes - -- Updated dependencies - - @reef-knot/web3-react@0.1.0 diff --git a/packages/connect-wallet-modal/README.md b/packages/connect-wallet-modal/README.md deleted file mode 100644 index cc9904be..00000000 --- a/packages/connect-wallet-modal/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Connect Wallet Modal - -Provides a modal window with buttons for connection with various crypto wallets. - -Import the basic ReefKnotWalletsModal component, default config getter, and the union type of connector identifiers: -```ts -import { ReefKnotWalletsModal, getDefaultWalletsModalConfig } from '@reef-knot/connect-wallet-modal' -import type { WalletIdsEthereum } from '@reef-knot/wallets-list'; -``` - -Use it like this: -```tsx -const walletsModalDefaultConfig = getDefaultWalletsModalConfig(); - - - {...walletsModalDefaultConfig} - darkThemeEnabled={false} - walletsShown={[ - 'metaMask', - 'walletconnect', - 'brave', - 'dappBrowserInjected', - ]} - walletsPinned={['dappBrowserInjected']} -/> -``` - -> **Note:** The `WalletIdsEthereum` type being passed as a generic to the component will affect the type safety constrain of `walletsShown`, `walletsPinned` and `metrics` props. - -#### Props configuration list - -| Prop | Description | -|------|-------------| -| `darkThemeEnabled?` | Set to true for the dark color theme.
***Default**: `false`* | -| `buttonsFullWidth?` | Specify connector buttons to render one per row. It could be handy if you are planning to use only few wallets in your dapp. | -| `config` | *A config object, see the fields below.* | -| `config.buttonComponentsByConnectorId` | A map of `ConnectButton`s associated with a certain connector id or type.
***Default**: Get with `getDefaultWalletsModalConfig()`* | -| `config.walletsShown` | Controls displayed wallet connection buttons from the list of wallets in the modal. Wallets will be displayed in the specified sequence.
***Default**: Get with `getDefaultWalletsModalConfig()`* | -| `config.walletsPinned` | Pins certain wallets to display it at the top of the list.
***Default**: Get with `getDefaultWalletsModalConfig()`* | -| `config.walletsDisplayInitialCount?` | Connection buttons count to render before the "More wallets" button.
***Default**: `6`* | -| `config.onClickTermsAccept({ isAccepted })`
`config.onClickWalletsMore()`
`config.onClickWalletsLess()`
`config.onConnectStart({ walletId })`
`config.onConnectSuccess({ walletId })` | Event callbacks. | -| `config.linkTerms?`
`config.linkPrivacyNotice?`
`config.linkDontHaveWallet?` | UI links. | diff --git a/packages/connect-wallet-modal/package.json b/packages/connect-wallet-modal/package.json deleted file mode 100644 index 30ee342b..00000000 --- a/packages/connect-wallet-modal/package.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "name": "@reef-knot/connect-wallet-modal", - "version": "0.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "exports": { - ".": "./dist/index.js" - }, - "typesVersions": { - "*": { - ".": [ - "dist/index.d.ts" - ] - } - }, - "type": "module", - "files": [ - "dist" - ], - "license": "MIT", - "homepage": "https://github.com/lidofinance/reef-knot", - "repository": { - "type": "git", - "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/connect-wallet-modal" - }, - "bugs": { - "url": "https://github.com/lidofinance/reef-knot/issues" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public" - }, - "scripts": { - "build": "yarn run -T tsdown", - "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" - }, - "dependencies": { - "@ledgerhq/hw-app-eth": "7.8.12", - "@ledgerhq/hw-transport": "6.35.7", - "@ledgerhq/hw-transport-webhid": "6.36.0", - "@lidofinance/lido-ui": "^3.18.0", - "@reef-knot/wallets-list": "*", - "@types/react": "18.2.45", - "@types/react-dom": "18.2.17" - }, - "devDependencies": { - "@reef-knot/core-react": "*", - "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", - "@reef-knot/ui-react": "*", - "@reef-knot/wallets-helpers": "*", - "@reef-knot/web3-react": "*", - "build-config": "*", - "eslint-config-custom": "*", - "react": "18.2.0", - "react-dom": "^18.2.0", - "viem": ">=2.50", - "wagmi": ">=3.6" - }, - "peerDependencies": { - "@lidofinance/lido-ui": "^3.18.0", - "@reef-knot/core-react": "*", - "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", - "@reef-knot/ui-react": "*", - "@reef-knot/wallets-helpers": "*", - "@reef-knot/web3-react": "*", - "@tanstack/react-query": "^5.29.0", - "react": ">=18", - "viem": ">=2.50", - "wagmi": ">=3.6" - } -} diff --git a/packages/connect-wallet-modal/src/components/ConnectWalletModal/ConnectWalletModal.tsx b/packages/connect-wallet-modal/src/components/ConnectWalletModal/ConnectWalletModal.tsx deleted file mode 100644 index 26cc75c5..00000000 --- a/packages/connect-wallet-modal/src/components/ConnectWalletModal/ConnectWalletModal.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { useConfig } from 'wagmi'; -import { - LS_KEY_RECONNECT_WALLET_ID, - useReefKnotContext, - useReefKnotModal, -} from '@reef-knot/core-react'; -import type { - WalletAdapterData, - ReefKnotWalletsModalProps, -} from '@reef-knot/types'; - -import { ConnectWalletModalLayout } from '../ConnectWalletModalLayout'; - -import { sortWalletsList } from '../../helpers/sortWalletsList'; - -type ConnectWalletModalProps = ReefKnotWalletsModalProps & { - onCloseSuccess?: () => void; - onCloseReject?: () => void; -}; - -export const ConnectWalletModal = ({ - onCloseSuccess, - ...passedDownProps -}: ConnectWalletModalProps) => { - const { config: modalConfig, darkThemeEnabled = false } = passedDownProps; - const { - buttonComponentsByConnectorId, - walletsShown, - walletsPinned, - walletsDisplayInitialCount = 6, - onConnectStart, - onConnectSuccess, - onClickWalletsMore, - onClickWalletsLess, - } = modalConfig; - - const config = useConfig(); - const { walletDataList, loadingWalletId } = useReefKnotContext(); - const { termsChecked } = useReefKnotModal(); - - const [inputValue, setInputValue] = useState(''); - const [isShownOtherWallets, setShowOtherWallets] = useState(false); - - const handleInputChange = useCallback( - (e: React.ChangeEvent) => { - setInputValue(e.currentTarget.value); - }, - [], - ); - - const handleInputClear = useCallback(() => { - setInputValue(''); - }, []); - - const handleToggleWalletsList = useCallback(() => { - const nextShownState = !isShownOtherWallets; - setShowOtherWallets(nextShownState); - if (nextShownState) { - onClickWalletsMore?.(); - } else { - onClickWalletsLess?.(); - } - }, [isShownOtherWallets, onClickWalletsMore, onClickWalletsLess]); - - const [walletsListFull, setWalletsListFull] = useState( - [], - ); - - const handleConnectSuccess = useCallback( - (walletId: string, rdns?: string) => { - void config.storage?.setItem( - LS_KEY_RECONNECT_WALLET_ID, - rdns ?? walletId, - ); - onCloseSuccess?.(); - onConnectSuccess?.({ walletId, rdns }); - }, - [onCloseSuccess, onConnectSuccess, config.storage], - ); - - useEffect(() => { - let isActive = true; - const fetch = async () => { - // Asynchronously filling wallets list because there is an async wallet detection during wallets sorting. - // Actually, almost all wallets can be detected synchronously, so this process is expected to be fast, - // and a loading indicator is not required for now. - const _walletsListFull = await sortWalletsList({ - walletDataList, - walletsShown, - walletsPinned, - }); - if (isActive) setWalletsListFull(_walletsListFull); - }; - void fetch(); - return () => { - isActive = false; - }; - }, [config, walletDataList, walletsPinned, walletsShown]); - - const walletsList = useMemo(() => { - let _walletsList = walletsListFull; - - if (!isShownOtherWallets) { - _walletsList = walletsListFull.slice(0, walletsDisplayInitialCount); - } - - if (inputValue) { - _walletsList = walletsListFull.filter((wallet) => - wallet.walletName.toLowerCase().includes(inputValue.toLowerCase()), - ); - } - - return _walletsList; - }, [ - inputValue, - isShownOtherWallets, - walletsDisplayInitialCount, - walletsListFull, - ]); - - const isWalletsToggleButtonShown = - walletsListFull.length > walletsList.length || isShownOtherWallets; - - const someWalletIsLoading = - loadingWalletId != null && loadingWalletId.length > 0; - - return ( - - {walletsList.map(({ type, walletId, ...walletData }) => { - const WalletComponent = - buttonComponentsByConnectorId[walletId] ?? - buttonComponentsByConnectorId[type] ?? - buttonComponentsByConnectorId.default; - if (!WalletComponent) return null; - return ( - onConnectStart?.({ walletId })} - onConnectSuccess={(args) => - // reconnectId is set by EIP-6963 buttons to the provider rdns; - // falls back to the static adapter walletId for legacy connectors - handleConnectSuccess(args?.reconnectId ?? walletId, args?.rdns) - } - /> - ); - })} - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/ConnectWalletModal/index.ts b/packages/connect-wallet-modal/src/components/ConnectWalletModal/index.ts deleted file mode 100644 index 423a5eae..00000000 --- a/packages/connect-wallet-modal/src/components/ConnectWalletModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ConnectWalletModal'; diff --git a/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx b/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx deleted file mode 100644 index 15708478..00000000 --- a/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; - -import { Modal } from '@reef-knot/ui-react'; -import type { ReefKnotWalletsModalProps } from '@reef-knot/types'; -import { EmptyWalletsList } from '../EmptyWalletsList'; -import { - ContentWrapper, - ContentWrapperInner, - WalletsButtonsScrollBox, - WalletsButtonsContainer, - Subtitle, - ContentHeader, - NoWalletLink, - MoreWalletsToggleButton, - MoreWalletsText, - IconMoreWallets, - MEDIA_MOBILE_HEIGHT, -} from './styles'; -import { Terms } from '../Terms'; - -import { isMobileOrTablet, isIOS, isIPad } from '@reef-knot/wallets-helpers'; -import { WalletModalInput } from '../WalletModalInput'; - -// Additional check because `@supports selector(::-webkit-scrollbar)` -// passes as true on iOS/iPad devices, but styles will not really apply -const isSupportedCustomScrollbar = !isIOS && !isIPad; - -type ConnectWalletModalLayoutProps = ReefKnotWalletsModalProps & { - inputValue: string; - isEmptyWalletsList: boolean; - isShownOtherWallets: boolean; - isShownWalletsToggleButton: boolean; - onCloseReject?: () => void; - onToggleWalletsList: () => void; - onInputChange: React.ChangeEventHandler; - onInputClear: () => void; -}; - -export const ConnectWalletModalLayout = ({ - config, - inputValue, - onInputChange, - onInputClear, - onCloseReject, - onToggleWalletsList, - isEmptyWalletsList, - isShownOtherWallets, - isShownWalletsToggleButton, - children, - ...passedDownProps -}: ConnectWalletModalLayoutProps) => { - const { linkDontHaveWallet } = config; - const { buttonsFullWidth = false, darkThemeEnabled } = passedDownProps; - - const inputRef = useRef(null); - const [isMobileHeight, setIsMobileHeight] = useState(false); - - useEffect(() => { - if (isShownOtherWallets) { - if (!isMobileOrTablet) inputRef.current?.focus(); - } else { - onInputClear(); - } - }, [isShownOtherWallets, onInputClear]); - - useEffect(() => { - // Screen height media query - const mediaQuery = window.matchMedia(MEDIA_MOBILE_HEIGHT); - setIsMobileHeight(mediaQuery.matches); - const onMediaChange = (e: MediaQueryListEvent) => { - setIsMobileHeight(e.matches); - }; - mediaQuery.addEventListener('change', onMediaChange); - return () => { - mediaQuery.removeEventListener('change', onMediaChange); - }; - }, []); - - return ( - - - - - - - Choose wallet - {linkDontHaveWallet && ( - - I don't have a wallet - - )} - - {isShownOtherWallets && ( - - )} - - - - {isEmptyWalletsList && ( - - )} - - {!isEmptyWalletsList && ( - - {children} - - )} - - - {isShownWalletsToggleButton && ( - - - - {isShownOtherWallets ? 'Less wallets' : 'More wallets'} - - - )} - - - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/EIP6963WalletsList.tsx b/packages/connect-wallet-modal/src/components/EIP6963WalletsList/EIP6963WalletsList.tsx deleted file mode 100644 index 98cf583a..00000000 --- a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/EIP6963WalletsList.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { useMemo, ElementType } from 'react'; -import { useReefKnotContext, useReefKnotModal } from '@reef-knot/core-react'; -import type { EIP6963ProviderDetail } from '@reef-knot/core-react'; -import type { ReefKnotWalletsModalConfig } from '@reef-knot/types'; -import { isIOS, isIPad } from '@reef-knot/wallets-helpers'; -import { Terms } from '../Terms'; -import { - ContentHeader, - Subtitle, - WalletsButtonsContainer, - WalletsButtonsScrollBox, -} from '../ConnectWalletModalLayout/styles'; -import { WalletIconImg } from './styles'; -import { ConnectButtonBase } from '../ConnectButtonBase'; -import { validateIcon, FALLBACK_WALLET_ICON } from '../../helpers/validateIcon'; - -type EIP6963WalletsListProps = { - providers: readonly EIP6963ProviderDetail[]; - onSelect: (provider: EIP6963ProviderDetail) => void | Promise; - config: ReefKnotWalletsModalConfig; -}; - -// Additional check because `@supports selector(::-webkit-scrollbar)` -// passes as true on iOS/iPad devices, but styles will not really apply -const isSupportedCustomScrollbar = !isIOS && !isIPad; - -export const EIP6963WalletsList = ({ - providers, - onSelect, - config, -}: EIP6963WalletsListProps) => { - const { closeModal, termsChecked } = useReefKnotModal(); - const { loadingWalletId } = useReefKnotContext(); - - const someProviderIsLoading = loadingWalletId != null; - - const handleSelect = async (provider: EIP6963ProviderDetail) => { - if (!termsChecked || someProviderIsLoading) return; - try { - await onSelect(provider); - // onSelect calls onConnectSuccess → onCloseSuccess which closes the eip6963 modal; - // close the remaining wallet list modal here (both updates are batched by React 18) - closeModal({ success: true }); - } catch (error) { - // stay open on rejection so the user can retry, log error for debugging - console.warn('EIP6963WalletsList: wallet connection failed', error); - } - }; - - const providerIcons = useMemo( - () => - Object.fromEntries( - providers.map((p) => [ - p.info.uuid, - function ProviderIcon() { - return ( - { - e.currentTarget.src = FALLBACK_WALLET_ICON; - }} - /> - ); - }, - ]), - ) as Record, - [providers], - ); - - return ( - <> - - - - Select browser wallet - - - - - {providers.map((provider) => ( - void handleSelect(provider)} - > - {provider.info.name} - - ))} - - - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/index.ts b/packages/connect-wallet-modal/src/components/EIP6963WalletsList/index.ts deleted file mode 100644 index 7ad3f493..00000000 --- a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { EIP6963WalletsList } from './EIP6963WalletsList'; diff --git a/packages/connect-wallet-modal/src/components/EagerConnectModal/EagerConnectModal.tsx b/packages/connect-wallet-modal/src/components/EagerConnectModal/EagerConnectModal.tsx deleted file mode 100644 index abd8df5e..00000000 --- a/packages/connect-wallet-modal/src/components/EagerConnectModal/EagerConnectModal.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React, { useState } from 'react'; -import { useConfig } from 'wagmi'; -import { Button, Modal } from '@reef-knot/ui-react'; -import { - useReefKnotModal, - getUnsupportedChainError, -} from '@reef-knot/core-react'; -import { ReefKnotWalletsModalConfig } from '@reef-knot/types'; -import { Terms } from '../Terms'; -import { CommonButtonsContainer, ErrorBlock } from './styles'; - -type EagerConnectModalProps = { - config: ReefKnotWalletsModalConfig; - tryConnection: () => Promise; - initialError: Error | undefined; -}; - -export const EagerConnectModal = ({ - config, - tryConnection, - initialError, -}: EagerConnectModalProps) => { - const { termsChecked, closeModal } = useReefKnotModal(); - const { chains: supportedChains } = useConfig(); - - const [error, setError] = useState(initialError); - - const handleClick = async () => { - try { - await tryConnection(); - closeModal({ success: true }); - } catch (e) { - setError(e as Error); - } - }; - - let errorMessage = error?.message; - if (error && error.name == 'UnsupportedChainIdError') { - errorMessage = getUnsupportedChainError(supportedChains).message; - } - - return ( - - - {error && {errorMessage} } - - - - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/EagerConnectModal/index.ts b/packages/connect-wallet-modal/src/components/EagerConnectModal/index.ts deleted file mode 100644 index 6a1cd2a9..00000000 --- a/packages/connect-wallet-modal/src/components/EagerConnectModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './EagerConnectModal'; diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerAccountScreen.tsx b/packages/connect-wallet-modal/src/components/Ledger/LedgerAccountScreen.tsx deleted file mode 100644 index 3a204504..00000000 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerAccountScreen.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import React, { FC, useCallback, useEffect, useState } from 'react'; -import styled from '@reef-knot/ui-react/styled-wrapper'; -import { helpers } from '@reef-knot/web3-react'; -import { useConnect } from 'wagmi'; -import { Pagination, Stack, StackItem } from '@lidofinance/lido-ui'; -import { AccountButton, AccountButtonSkeleton } from './LedgerAccountButton'; -import { useLedgerAccounts, useLedgerContext } from './hooks'; -import { getFirstIndexOnPage, saveLedgerDerivationPath } from './helpers'; -import { LedgerDerivationPathSelect } from './LedgerDerivationPathSelect'; -import { AccountRecord, AccountsStorage } from './types'; -import { DERIVATION_PATHS } from './constants'; -import { idLedgerHid } from '@reef-knot/ledger-connector'; -import { useReefKnotContext } from '@reef-knot/core-react'; - -const BoxWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - margin-top: 24px; - padding-bottom: 20px; -`; - -type Props = { - onConnectSuccess?: () => void; -}; - -const ACCOUNTS_PER_PAGE = 5; -const ACCOUNTS_TOTAL_PAGES = 4; - -export const LedgerAccountScreen: FC = ({ onConnectSuccess }) => { - const [currentPage, setCurrentPage] = useState(1); - const [derivationPathTemplate, setDerivationPathTemplate] = useState( - DERIVATION_PATHS[0].template, - ); - const [accountsStorage, setAccountsStorage] = useState(); - - const { setError, disconnectTransport } = useLedgerContext(); - - const accountsForPage = useLedgerAccounts({ - accountsStorage, - derivationPathTemplate, - accountsPerPage: ACCOUNTS_PER_PAGE, - currentPage, - }); - - useEffect(() => { - if (Object.values(accountsForPage).length === ACCOUNTS_PER_PAGE) { - const { pathTemplate } = Object.values(accountsForPage)[0]; - - setAccountsStorage({ - ...accountsStorage, - [pathTemplate]: { - ...accountsStorage?.[pathTemplate], - ...accountsForPage, - }, - }); - } - }, [accountsForPage, accountsStorage, derivationPathTemplate]); - - const { mutateAsync: connectAsync } = useConnect(); - const { walletDataList } = useReefKnotContext(); - - const handleAccountButtonClick = useCallback( - async (account: AccountRecord) => { - const ledgerWalletData = walletDataList.find( - (c) => c.walletId === idLedgerHid, - ); - if (!ledgerWalletData) return; - saveLedgerDerivationPath(account.path); - await disconnectTransport(true); - try { - await connectAsync({ - connector: ledgerWalletData.createConnectorFn, - }); - onConnectSuccess?.(); - } catch (e) { - setError(helpers.interceptLedgerError(e as Error)); - } - }, - [ - disconnectTransport, - walletDataList, - setError, - connectAsync, - onConnectSuccess, - ], - ); - - const handleDerivationPathSelect = useCallback((value: string) => { - setCurrentPage(1); - setDerivationPathTemplate(value); - }, []); - - return ( - - - - - - {/* If accounts storage contains the first account for the current page, we can assume that others are loaded too */} - {Array.from({ length: ACCOUNTS_PER_PAGE }).map( - accountsStorage?.[derivationPathTemplate]?.[ - getFirstIndexOnPage(currentPage, ACCOUNTS_PER_PAGE) - ] - ? (_, i) => { - const accountIndex = - i + getFirstIndexOnPage(currentPage, ACCOUNTS_PER_PAGE); - const account = - accountsStorage[derivationPathTemplate][accountIndex]; - return ( - { - void handleAccountButtonClick(account); - }} - /> - ); - } - : (_, i) => , - )} - - - - - - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerModal.tsx b/packages/connect-wallet-modal/src/components/Ledger/LedgerModal.tsx deleted file mode 100644 index 8a5eeace..00000000 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerModal.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useCallback } from 'react'; -import { Modal, ModalProps } from '@reef-knot/ui-react'; -import { LedgerConnectionScreen } from './LedgerConnectionScreen'; -import { LedgerContextProvider } from './LedgerContext'; -import { LedgerErrorScreen } from './LedgerErrorScreen'; -import { useLedgerContext } from './hooks'; -import { LedgerAccountScreen } from './LedgerAccountScreen'; -import { LedgerModalInnerContainer } from './styles'; - -export type LedgerModalProps = ModalProps & { - onCloseSuccess?: () => void; - onCloseReject?: () => void; -}; - -export const LedgerModal = ({ - onCloseSuccess, - onCloseReject, - ...props -}: LedgerModalProps) => { - const handleClose = useCallback( - (event?: any) => { - // hack needed to prevent the Modal closing on Select - if (!event) return; - onCloseReject?.(); - }, - [onCloseReject], - ); - - return ( - - - - - - ); -}; - -export const LedgerScreen = ({ onCloseSuccess }: LedgerModalProps) => { - const { - error, - reconnectTransport, - isTransportConnected, - isUserActivationRequired, - } = useLedgerContext(); - - const handleClickRetry = useCallback(() => { - void reconnectTransport(); - }, [reconnectTransport]); - - return ( - - {error && ( - - )} - {!error && isTransportConnected && ( - - )} - {!error && !isTransportConnected && ( - - )} - - ); -}; diff --git a/packages/connect-wallet-modal/src/components/Ledger/index.ts b/packages/connect-wallet-modal/src/components/Ledger/index.ts deleted file mode 100644 index 3f745f54..00000000 --- a/packages/connect-wallet-modal/src/components/Ledger/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './LedgerModal'; diff --git a/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/ReefKnotWalletsModal.tsx b/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/ReefKnotWalletsModal.tsx deleted file mode 100644 index cb80630f..00000000 --- a/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/ReefKnotWalletsModal.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; -import { Modal } from '@reef-knot/ui-react'; -import { useReefKnotModal } from '@reef-knot/core-react'; -import type { ReefKnotWalletsModalProps } from '@reef-knot/types'; -import { LedgerModal } from '../Ledger'; -import { EagerConnectModal } from '../EagerConnectModal'; -import { ConnectWalletModal } from '../ConnectWalletModal'; -import { EIP6963WalletsList } from '../EIP6963WalletsList'; - -export function ReefKnotWalletsModal( - props: ReefKnotWalletsModalProps, -) { - const { config } = props; - const { currentModal, closeModal, forceCloseAllModals } = useReefKnotModal(); - const onCloseSuccess = () => closeModal({ success: true }); - const onCloseReject = () => closeModal({ success: false }); - const onExit = () => forceCloseAllModals(); - - switch (currentModal?.type) { - case 'wallet': { - return ( - - ); - } - - case 'ledger': - return ( - - ); - - case 'eager': { - const { tryConnection, initialError } = currentModal.props; - return ( - - ); - } - - case 'requirements': { - const { icon: titleIcon, title, text: subtitle } = currentModal.props; - return ( - - ); - } - - case 'eip6963': { - const { providers, onSelect } = currentModal.props; - return ( - - - - ); - } - - default: - return null; - } -} diff --git a/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/getDefaultWalletsModalConfig.ts b/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/getDefaultWalletsModalConfig.ts deleted file mode 100644 index a921c741..00000000 --- a/packages/connect-wallet-modal/src/components/ReefKnotWalletsModal/getDefaultWalletsModalConfig.ts +++ /dev/null @@ -1,61 +0,0 @@ -import type { WalletIdsEthereum } from '@reef-knot/wallets-list'; -import type { - ButtonComponentsByConnectorId, - ReefKnotWalletsModalConfig, -} from '@reef-knot/types'; -import { - ConnectInjected, - ConnectLedger, - ConnectWC, - ConnectCoinbase, - ConnectBrowser, - ConnectMetaMask, -} from '../../connectButtons'; - -const TERMS_LINK_DEFAULT = 'https://lido.fi/terms-of-use'; -const PRIVACY_NOTICE_LINK_DEFAULT = 'https://lido.fi/privacy-notice'; - -export const WALLETS_MODAL_BUTTON_COMPONENTS_DEFAULT: ButtonComponentsByConnectorId = - { - default: ConnectInjected, // fallback - browserExtension: ConnectBrowser, - walletConnect: ConnectWC, - coinbaseWallet: ConnectCoinbase, - ledgerHID: ConnectLedger, - metaMask: ConnectMetaMask, - }; - -export const WALLETS_MODAL_DISPLAY_CONFIG_DEFAULT: WalletIdsEthereum[] = [ - 'browserExtension', - 'metaMask', - 'okx', - 'ledgerHID', - 'ledgerLive', - 'walletConnect', - 'coinbaseSmartWallet', - 'bitget', - 'anchorageDigital', - 'imToken', - 'ambire', - 'safe', - 'dappBrowserInjected', -]; - -export const WALLETS_MODAL_PINNED_CONFIG_DEFAULT: WalletIdsEthereum[] = [ - 'browserExtension', -]; - -export const getDefaultWalletsModalConfig = (): Pick< - ReefKnotWalletsModalConfig, - | 'buttonComponentsByConnectorId' - | 'walletsShown' - | 'walletsPinned' - | 'linkTerms' - | 'linkPrivacyNotice' -> => ({ - buttonComponentsByConnectorId: WALLETS_MODAL_BUTTON_COMPONENTS_DEFAULT, - walletsShown: WALLETS_MODAL_DISPLAY_CONFIG_DEFAULT, - walletsPinned: WALLETS_MODAL_PINNED_CONFIG_DEFAULT, - linkTerms: TERMS_LINK_DEFAULT, - linkPrivacyNotice: PRIVACY_NOTICE_LINK_DEFAULT, -}); diff --git a/packages/connect-wallet-modal/src/components/Terms/Terms.tsx b/packages/connect-wallet-modal/src/components/Terms/Terms.tsx deleted file mode 100644 index 364f6dbb..00000000 --- a/packages/connect-wallet-modal/src/components/Terms/Terms.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { ChangeEvent, FC, useCallback } from 'react'; -import { Checkbox, Link } from '@reef-knot/ui-react'; -import { useReefKnotModal } from '@reef-knot/core-react'; -import type { ReefKnotWalletsModalConfig } from '@reef-knot/types'; -import { TermsStyle, TermsTextStyle } from './styles'; - -export type TermsProps = { - config: ReefKnotWalletsModalConfig; -}; - -export const Terms: FC = ({ config }) => { - const { linkTerms, linkPrivacyNotice, onClickTermsAccept } = config; - const { setTermsChecked, termsChecked } = useReefKnotModal(); - - const handleCheckboxChange = useCallback( - (e: ChangeEvent) => { - const isAccepted = e.currentTarget.checked; - setTermsChecked(isAccepted); - if (isAccepted) { - onClickTermsAccept?.({ isAccepted }); - } - }, - [setTermsChecked, onClickTermsAccept], - ); - - return ( - - - - I certify that I have read and accept the updated{' '} - Terms of Use and{' '} - Privacy Notice. - - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/ConnectBrowser.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/ConnectBrowser.tsx deleted file mode 100644 index 0c0d5c5b..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/ConnectBrowser.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import 'viem/window'; // for window.ethereum?: EIP1193Provider -import { FC, useCallback } from 'react'; -import { injected } from 'wagmi/connectors'; -import { - useDisconnect, - useReefKnotContext, - useReefKnotModal, -} from '@reef-knot/core-react'; -import type { EIP6963ProviderDetail } from '@reef-knot/core-react'; -import { Warning } from '@reef-knot/ui-react'; -import { isMobileOrTablet } from '@reef-knot/wallets-helpers'; -import { useEIP6963ProvidersWithoutAdapters } from '../../hooks/useEIP6963ProvidersWithoutAdapters'; -import { ConnectButtonBase } from '../../components/ConnectButtonBase'; -import { ConnectInjectedProps } from '../types'; -import { useConnectWithLoading } from '../../hooks/useConnectWithLoading'; -import { BrowserWalletIconsGrid } from '../../components/BrowserWalletIconsGrid'; - -const ConnectBrowserButton: FC = ( - props: ConnectInjectedProps, -) => { - const { - darkThemeEnabled, - walletId, - walletName, - connector, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - const { openModal, openModalAsync } = useReefKnotModal(); - - const web3ProviderIsDetected = - typeof globalThis.window?.ethereum?.request === 'function'; - - const { loadingWalletId } = useReefKnotContext(); - const { connectWithLoading } = useConnectWithLoading(); - const { disconnect } = useDisconnect(); - const detectedProviders = useEIP6963ProvidersWithoutAdapters(); - - const isEIP6963ProviderLoading = detectedProviders.some( - (p) => p.info.rdns === loadingWalletId, - ); - - const connectToEIP6963Provider = useCallback( - async (provider: EIP6963ProviderDetail) => { - const connectorFn = injected({ - target: { - id: provider.info.rdns, - name: provider.info.name, - provider: () => provider.provider, - }, - }); - disconnect?.(); - await connectWithLoading(provider.info.rdns, { connector: connectorFn }); - onConnectSuccess?.({ rdns: provider.info.rdns }); - }, - [connectWithLoading, disconnect, onConnectSuccess], - ); - - const handleConnect = useCallback(async () => { - onConnectStart?.(); - - if (detectedProviders.length === 1) { - await connectToEIP6963Provider(detectedProviders[0]); - return; - } - - if (detectedProviders.length >= 2) { - openModal({ - type: 'eip6963', - props: { - providers: detectedProviders, - onSelect: connectToEIP6963Provider, - }, - }); - return; - } - - // No EIP-6963 wallets detected — fall back to legacy window.ethereum - if (web3ProviderIsDetected) { - disconnect?.(); - await connectWithLoading(walletId, { connector }); - onConnectSuccess?.(); - } else { - await openModalAsync({ - type: 'requirements', - props: { - icon: , - title: 'No wallets detected', - }, - }); - } - }, [ - onConnectStart, - detectedProviders, - connectToEIP6963Provider, - openModal, - web3ProviderIsDetected, - disconnect, - connectWithLoading, - walletId, - connector, - onConnectSuccess, - openModalAsync, - ]); - - return ( - { - void handleConnect(); - }} - > - {walletName} - - ); -}; - -export const ConnectBrowser: FC = (props) => { - // There is no point in showing this button on mobile or tablet devices - if (isMobileOrTablet) return null; - - return ; -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/index.ts b/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/index.ts deleted file mode 100644 index 028f1760..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectBrowser/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ConnectBrowser'; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectCoinbase.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectCoinbase.tsx deleted file mode 100644 index 76581b47..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectCoinbase.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { FC, useCallback } from 'react'; -import { useConnect } from 'wagmi'; -import { useDisconnect } from '@reef-knot/core-react'; -import { ConnectButtonBase } from '../components/ConnectButtonBase'; -import { ConnectInjectedProps } from './types'; - -export const ConnectCoinbase: FC = ( - props: ConnectInjectedProps, -) => { - const { - darkThemeEnabled, - walletId, - walletName, - icon: WalletIcon, - downloadURLs, - detector, - connector, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - - const { mutate: connect } = useConnect(); - const { disconnect } = useDisconnect(); - - const handleConnect = useCallback(() => { - onConnectStart?.(); - disconnect?.(); - connect( - { connector }, - { - onSuccess: () => { - onConnectSuccess?.(); - }, - }, - ); - }, [connect, connector, disconnect, onConnectStart, onConnectSuccess]); - - return ( - - {walletName} - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectInjected.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectInjected.tsx deleted file mode 100644 index 90d01867..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectInjected.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import { FC, useCallback } from 'react'; -import { useDisconnect, useReefKnotContext } from '@reef-knot/core-react'; -import { isMobileOrTablet } from '@reef-knot/wallets-helpers'; -import { ConnectButtonBase } from '../components/ConnectButtonBase'; -import { suggestApp } from '../helpers/suggestApp'; -import { openWindow } from '../helpers/openWindow'; -import { ConnectInjectedProps } from './types'; -import { useConnectWithLoading } from '../hooks/useConnectWithLoading'; - -export const ConnectInjected: FC = ( - props: ConnectInjectedProps, -) => { - const { - darkThemeEnabled, - walletId, - walletName, - icon: WalletIcon, - downloadURLs, - detector, - connector, - deeplink, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - - const { disconnect } = useDisconnect(); - const { loadingWalletId } = useReefKnotContext(); - const { connectWithLoading } = useConnectWithLoading(); - - const handleConnect = useCallback(async () => { - onConnectStart?.(); - - if (await detector?.()) { - disconnect?.(); - await connectWithLoading(walletId, { connector }); - onConnectSuccess?.(); - } else if (isMobileOrTablet && deeplink) { - openWindow(deeplink); - } else if (downloadURLs) { - suggestApp(downloadURLs); - } - }, [ - connectWithLoading, - connector, - deeplink, - detector, - disconnect, - downloadURLs, - onConnectStart, - onConnectSuccess, - walletId, - ]); - - return ( - { - void handleConnect(); - }} - > - {walletName} - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectLedger.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectLedger.tsx deleted file mode 100644 index ffc49d32..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectLedger.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { FC, useCallback } from 'react'; -import { ConnectLedgerProps } from './types'; -import { ConnectButtonBase } from '../components/ConnectButtonBase'; -import { useReefKnotModal } from '@reef-knot/core-react'; - -export const ConnectLedger: FC = (props) => { - const { - walletId, - darkThemeEnabled, - icon: WalletIcon, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - - const { openModalAsync } = useReefKnotModal(); - - const handleConnect = useCallback(async () => { - onConnectStart?.(); - const result = await openModalAsync({ type: 'ledger' }); - if (result.success) onConnectSuccess?.(); - }, [openModalAsync, onConnectStart, onConnectSuccess]); - - return ( - { - void handleConnect(); - }} - > - Ledger - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectMetaMask.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectMetaMask.tsx deleted file mode 100644 index 9953c00f..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectMetaMask.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { FC, useCallback } from 'react'; -import { useDisconnect, useReefKnotContext } from '@reef-knot/core-react'; -import { useConnectWithLoading } from '../hooks/useConnectWithLoading'; -import { ConnectButtonBase } from '../components/ConnectButtonBase'; -import { ConnectInjectedProps } from './types'; - -export const ConnectMetaMask: FC = ( - props: ConnectInjectedProps, -) => { - const { - darkThemeEnabled, - walletId, - walletName, - icon: WalletIcon, - downloadURLs, - detector, - connector, - deeplink, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - - const { loadingWalletId } = useReefKnotContext(); - const { connectWithLoading } = useConnectWithLoading(); - const { disconnect } = useDisconnect(); - - const handleConnect = useCallback(async () => { - onConnectStart?.(); - disconnect?.(); - await connectWithLoading(walletId, { connector }); - onConnectSuccess?.(); - }, [ - connectWithLoading, - connector, - disconnect, - onConnectStart, - onConnectSuccess, - walletId, - ]); - - return ( - { - void handleConnect(); - }} - > - {walletName} - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/ConnectWC.tsx b/packages/connect-wallet-modal/src/connectButtons/ConnectWC.tsx deleted file mode 100644 index b9a9dd26..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/ConnectWC.tsx +++ /dev/null @@ -1,134 +0,0 @@ -import { FC, useCallback } from 'react'; -import { Connector, useConfig, useConnect } from 'wagmi'; -import { - providersStore, - useDisconnect, - useReefKnotContext, -} from '@reef-knot/core-react'; -import { isMobileOrTablet } from '@reef-knot/wallets-helpers'; -import { getWalletConnectUri } from '@reef-knot/wallets-helpers'; -import { ConnectButtonBase } from '../components/ConnectButtonBase'; -import { openWindow } from '../helpers/openWindow'; -import { ConnectWCProps } from './types'; -import { useConnectWithLoading } from '../hooks/useConnectWithLoading'; - -let redirectionWindow: Window | null = null; - -const getRedirectionLoadingHTML = () => { - return `Wallet loading

Wallet loading

`; -}; - -const setRedirectionWindowLocation = (redirectLink: string, WCURI: string) => { - if (redirectionWindow && redirectLink && WCURI) { - const encodedWCURI = encodeURIComponent(WCURI); - redirectionWindow.location.href = `${redirectLink}${encodedWCURI}`; - } -}; - -export const ConnectWC: FC = (props: ConnectWCProps) => { - const { - darkThemeEnabled, - walletId, - walletName, - icon: WalletIcon, - downloadURLs, - connector, - walletconnectExtras, - deeplink, - onConnectStart, - onConnectSuccess, - ...rest - } = props; - - const config = useConfig(); - const { loadingWalletId } = useReefKnotContext(); - const { mutateAsync: connectAsync } = useConnect(); - const { connectWithLoading } = useConnectWithLoading(); - const { disconnect } = useDisconnect(); - - // WCURI – WalletConnect Pairing URI: https://docs.walletconnect.com/2.0/specs/clients/core/pairing/pairing-uri - // Used for connection without WalletConnect QR modal via redirect - const WCURIConnectorFn = - walletconnectExtras?.connectionViaURI?.createConnectorFn; - const WCURICondition = walletconnectExtras?.connectionViaURI?.condition; - const WCURIRedirectLink = walletconnectExtras?.connectionViaURI?.redirectLink; - const WCURICloseRedirectionWindow = - walletconnectExtras?.connectionViaURI?.closeRedirectionWindow ?? true; - - const handleConnect = useCallback(async () => { - // Handle deeplink on mobiles before connecting to WC - if (isMobileOrTablet && deeplink) { - openWindow(deeplink); - return; // A user was redirected to a wallet mobile app, no need to continue - } - - onConnectStart?.(); - disconnect?.(); - - const onSuccess = () => { - onConnectSuccess?.(); - }; - - if (WCURICondition && WCURIConnectorFn && WCURIRedirectLink) { - // BEGIN Handle connection via redirect using WC Pairing URI (without WalletConnect QR modal) - // Because of popup blockers, window.open must be called directly from onclick handler - redirectionWindow = window.open('', '_blank', 'noopener,noreferrer'); - redirectionWindow?.document.write(getRedirectionLoadingHTML()); - - await Promise.all([ - connectAsync({ connector: WCURIConnectorFn }), - (async () => { - // One-time disposable connector to access `.getProvider()` before wagmi will initialize it - // Do not save it nor use it later - const connectorDisposable = WCURIConnectorFn({ - chains: config.chains, - emitter: {} as any, - providers: providersStore.getProviders(), - }) as Connector; - // Wait for WalletConnect Pairing URI to arrive - const wcUri = await getWalletConnectUri(connectorDisposable); - setRedirectionWindowLocation(WCURIRedirectLink, wcUri); - // END Handle connection via redirect using WC Pairing URI (without WalletConnect QR modal) - })(), - ]); - - onSuccess(); - // We got a connection result - if (WCURICloseRedirectionWindow) { - // Close the previously opened window if necessary - redirectionWindow?.close(); - } - } else { - await connectWithLoading(walletId, { connector }); - onSuccess(); - } - }, [ - deeplink, - disconnect, - WCURICloseRedirectionWindow, - WCURICondition, - WCURIConnectorFn, - WCURIRedirectLink, - onConnectStart, - onConnectSuccess, - connectAsync, - config.chains, - connectWithLoading, - walletId, - connector, - ]); - - return ( - { - void handleConnect(); - }} - > - {walletName} - - ); -}; diff --git a/packages/connect-wallet-modal/src/connectButtons/index.ts b/packages/connect-wallet-modal/src/connectButtons/index.ts deleted file mode 100644 index d3f8de4c..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './ConnectLedger'; -export * from './ConnectInjected'; -export * from './ConnectWC'; -export * from './ConnectCoinbase'; -export * from './ConnectBrowser'; -export * from './ConnectMetaMask'; diff --git a/packages/connect-wallet-modal/src/connectButtons/types.ts b/packages/connect-wallet-modal/src/connectButtons/types.ts deleted file mode 100644 index aa67ffa0..00000000 --- a/packages/connect-wallet-modal/src/connectButtons/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { ConnectWalletButtonProps } from '@reef-knot/types'; - -export type ConnectInjectedProps = ConnectWalletButtonProps; -export type ConnectWCProps = ConnectWalletButtonProps; -export type ConnectLedgerProps = ConnectWalletButtonProps; diff --git a/packages/connect-wallet-modal/src/hooks/useConnectWithLoading.ts b/packages/connect-wallet-modal/src/hooks/useConnectWithLoading.ts deleted file mode 100644 index 05fd06e1..00000000 --- a/packages/connect-wallet-modal/src/hooks/useConnectWithLoading.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { useConnect } from 'wagmi'; -import { useReefKnotContext } from '@reef-knot/core-react'; - -type UseConnectParams = Parameters[0]; - -export function useConnectWithLoading(params?: UseConnectParams) { - const { setLoadingWalletId } = useReefKnotContext(); - - const { mutateAsync: connectAsync } = useConnect(params); - - const connectWithLoading = async ( - walletId: string, - connectAsyncVariables: Parameters[0], - connectAsyncOptions?: Parameters[1], - ) => { - try { - setLoadingWalletId(walletId); - await connectAsync(connectAsyncVariables, connectAsyncOptions); - } finally { - setLoadingWalletId(null); - } - }; - - return { connectWithLoading }; -} diff --git a/packages/connect-wallet-modal/src/hooks/useEIP6963ProvidersWithoutAdapters.ts b/packages/connect-wallet-modal/src/hooks/useEIP6963ProvidersWithoutAdapters.ts deleted file mode 100644 index 2304c421..00000000 --- a/packages/connect-wallet-modal/src/hooks/useEIP6963ProvidersWithoutAdapters.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useMemo } from 'react'; -import { useEIP6963Providers, useReefKnotContext } from '@reef-knot/core-react'; - -export const useEIP6963ProvidersWithoutAdapters = () => { - const { walletDataList } = useReefKnotContext(); - const allProviders = useEIP6963Providers(); - - const adapterRdnsSet = useMemo( - () => - new Set( - walletDataList - .map((w) => w.rdns) - .filter((rdns): rdns is string => rdns != null), - ), - [walletDataList], - ); - - return useMemo( - () => allProviders.filter((p) => !adapterRdnsSet.has(p.info.rdns)), - [allProviders, adapterRdnsSet], - ); -}; diff --git a/packages/connectors/ledger-connector/.eslintrc.json b/packages/connectors/ledger-connector/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/connectors/ledger-connector/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/connectors/ledger-connector/CHANGELOG.md b/packages/connectors/ledger-connector/CHANGELOG.md index ecf0d40c..95cd4be0 100644 --- a/packages/connectors/ledger-connector/CHANGELOG.md +++ b/packages/connectors/ledger-connector/CHANGELOG.md @@ -1,5 +1,11 @@ # @reef-knot/ledger-connector +## 5.3.0 + +- Reject Ledger HID transactions for a chain other than the configured chain, including when the RPC returns a different chain ID. +- Use bundler module resolution for TypeScript checks to support dependencies with package exports. +- Add tests for transaction chain checks and include connector tests in TypeScript checks. + ## 5.2.0 - Updated @ledgerhq/hw-app-eth to 7.8.12, @ledgerhq/hw-transport to 6.35.7, @ledgerhq/hw-transport-webhid to 6.36.0, @ledgerhq/iframe-provider to 0.4.3 diff --git a/packages/connectors/ledger-connector/package.json b/packages/connectors/ledger-connector/package.json index f1ba6365..e9a1d4d2 100644 --- a/packages/connectors/ledger-connector/package.json +++ b/packages/connectors/ledger-connector/package.json @@ -34,15 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", + "lint": "yarn run -T eslint .", "test": "vitest run", - "typecheck": "tsc --noEmit" + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { "@ledgerhq/hw-transport-mocker": "6.34.7", "@types/w3c-web-hid": "^1.0.7", "build-config": "*", - "eslint-config-custom": "*", "happy-dom": "^20.0.0", "viem": ">=2.50", "vitest": "^4.1.11", diff --git a/packages/connectors/ledger-connector/src/hid/__tests__/account.test.ts b/packages/connectors/ledger-connector/src/hid/__tests__/account.test.ts new file mode 100644 index 00000000..6d7da885 --- /dev/null +++ b/packages/connectors/ledger-connector/src/hid/__tests__/account.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, it, vi } from 'vitest'; +import { createLedgerAccount } from '../account'; +import { ADDRESS_A, DERIVATION_PATH, LEGACY_TX } from './fixtures'; + +describe.each([false, true])( + 'account chain binding (forceClearSign=%s)', + (forceClearSign) => { + it.each([undefined, 0, 137])( + 'rejects chainId %s before serialization or device access', + async (chainId) => { + const withEthApp = vi.fn(() => + Promise.reject(new Error('Unexpected device access')), + ); + const serializer = vi.fn(); + const account = createLedgerAccount( + ADDRESS_A, + DERIVATION_PATH, + withEthApp, + { chainId: 1, forceClearSign }, + ); + + await expect( + account.signTransaction({ ...LEGACY_TX, chainId }, { serializer }), + ).rejects.toThrow( + 'Transaction chain ID does not match the configured Ledger chain', + ); + expect(serializer).not.toHaveBeenCalled(); + expect(withEthApp).not.toHaveBeenCalled(); + }, + ); + }, +); diff --git a/packages/connectors/ledger-connector/src/hid/__tests__/provider.test.ts b/packages/connectors/ledger-connector/src/hid/__tests__/provider.test.ts index 0d732bd5..6a1d1aed 100644 --- a/packages/connectors/ledger-connector/src/hid/__tests__/provider.test.ts +++ b/packages/connectors/ledger-connector/src/hid/__tests__/provider.test.ts @@ -575,6 +575,144 @@ describe('signing', () => { }); }); +describe.each([false, true])( + 'transaction chain binding (forceClearSign=%s)', + (forceClearSign) => { + const transactionCases = [ + { type: '0x0', fees: { gasPrice: '0x3b9aca00' }, exchange: SIGN_TX }, + { type: '0x1', fees: { gasPrice: '0x3b9aca00' }, exchange: SIGN_TX_2930 }, + { + type: '0x2', + fees: { + maxFeePerGas: '0x77359400', + maxPriorityFeePerGas: '0x3b9aca00', + }, + exchange: SIGN_TX_1559, + }, + ]; + + it('rejects a foreign incoming chain before accessing the device or RPC', async () => { + const { fetchMock } = stubRpc({}); + const provider = createProvider({ forceClearSign }); + const getAccount = vi.spyOn(provider, 'getAccount'); + + await expect( + send1559(provider, { chainId: '0x89' }), + ).rejects.toMatchObject({ + name: 'ChainMismatchError', + }); + expect(getAccount).not.toHaveBeenCalled(); + expect(fetchMock).not.toHaveBeenCalled(); + await expect(provider.request({ method: 'eth_chainId' })).resolves.toBe( + '0x1', + ); + }); + + it.each(transactionCases)( + 'rejects a forged fill chain for type $type', + async ({ type, fees }) => { + const { calls } = stubRpc({ + eth_fillTransaction: () => ({ + tx: { + chainId: '0x89', + type, + from: ADDRESS_A, + to: ADDRESS_A, + input: '0x', + value: '0x1', + nonce: '0x0', + gas: '0x5208', + accessList: [], + ...fees, + }, + }), + }); + const provider = createProvider({ forceClearSign }); + const store = injectReplayer( + provider, + APP_CONFIG, + getAddressExchange(ADDRESS_A), + ); + await provider.enable(); + const withEthApp = vi.spyOn(provider, 'withEthApp'); + const resolve = vi.spyOn(ledgerService, 'resolveTransaction'); + + // Missing gas forces a real viem fill, even though chainId is pinned. + await expect( + provider.request({ + method: 'eth_sendTransaction', + params: [ + { from: ADDRESS_A, to: ADDRESS_A, value: '0x1', type, ...fees }, + ], + }), + ).rejects.toThrow( + 'Transaction chain ID does not match the configured Ledger chain', + ); + + expect(calls).toHaveLength(1); + expect(calls[0]).toMatchObject({ + method: 'eth_fillTransaction', + }); + expect(withEthApp).not.toHaveBeenCalled(); + expect(resolve).not.toHaveBeenCalled(); + store.ensureQueueEmpty(); + }, + ); + + it.each(transactionCases)( + 'signs a correctly filled chain for type $type', + async ({ type, fees, exchange }) => { + const { calls } = stubRpc({ + eth_fillTransaction: () => ({ + tx: { + chainId: '0x1', + type, + from: ADDRESS_A, + to: ADDRESS_A, + input: '0x', + value: '0x1', + nonce: '0x0', + gas: '0x5208', + accessList: [], + ...fees, + }, + }), + eth_sendRawTransaction: () => '0xtxhash', + }); + const provider = createProvider({ forceClearSign }); + const store = injectReplayer( + provider, + APP_CONFIG, + getAddressExchange(ADDRESS_A), + APP_CONFIG, + exchange, + ); + + await expect( + provider.request({ + method: 'eth_sendTransaction', + params: [ + { + from: ADDRESS_A, + chainId: '0x1', + to: ADDRESS_A, + value: '0x1', + type, + ...fees, + }, + ], + }), + ).resolves.toBe('0xtxhash'); + expect(calls.map((call) => call.method)).toEqual([ + 'eth_fillTransaction', + 'eth_sendRawTransaction', + ]); + store.ensureQueueEmpty(); + }, + ); + }, +); + describe('clear signing', () => { it('falls back to blind signing when metadata resolution fails', async () => { vi.spyOn(ledgerService, 'resolveTransaction').mockRejectedValue( diff --git a/packages/connectors/ledger-connector/src/hid/account.ts b/packages/connectors/ledger-connector/src/hid/account.ts index dbde97f8..926e7b67 100644 --- a/packages/connectors/ledger-connector/src/hid/account.ts +++ b/packages/connectors/ledger-connector/src/hid/account.ts @@ -1,6 +1,7 @@ import type Eth from '@ledgerhq/hw-app-eth'; import { toAccount } from 'viem/accounts'; import { + BaseError, bytesToHex, getTypesForEIP712Domain, hashStruct, @@ -11,7 +12,6 @@ import { type Hex, type LocalAccount, type TypedDataDefinition, - type TypedDataDomain, } from 'viem'; type EIP712Message = Parameters[1]; @@ -21,6 +21,7 @@ export type WithEthApp = ( ) => Promise; export type LedgerAccountOptions = { + chainId: number; // Refuse to sign a contract call the device cannot clear sign. forceClearSign?: boolean; }; @@ -67,7 +68,7 @@ export const createLedgerAccount = ( address: Address, path: string, withEthApp: WithEthApp, - { forceClearSign = false }: LedgerAccountOptions = {}, + { chainId, forceClearSign = false }: LedgerAccountOptions, ): LocalAccount => toAccount({ address, @@ -76,6 +77,12 @@ export const createLedgerAccount = ( transaction, { serializer = serializeTransaction } = {}, ) { + // RPC filling can replace chainId even when the request pinned it. + // Fail before serialization, metadata resolution or any device action. + if (transaction.chainId !== chainId) + throw new BaseError( + 'Transaction chain ID does not match the configured Ledger chain.', + ); const unsignedRawTx = (await serializer(transaction)).slice(2); const { r, s, v } = await withEthApp(async (eth) => { // Metadata fetch failures are swallowed by the Ledger service and @@ -135,7 +142,7 @@ export const createLedgerAccount = ( } catch (error) { if (!shouldFallbackToHashedSigning(error)) throw error; - const typedDataDomain = domain as TypedDataDomain; + const typedDataDomain = domain; const domainSeparator = hashStruct({ data: typedDataDomain, primaryType: 'EIP712Domain', diff --git a/packages/connectors/ledger-connector/src/hid/connector.ts b/packages/connectors/ledger-connector/src/hid/connector.ts index 2c03937c..b6488bdd 100644 --- a/packages/connectors/ledger-connector/src/hid/connector.ts +++ b/packages/connectors/ledger-connector/src/hid/connector.ts @@ -109,7 +109,6 @@ export function ledgerHIDConnector({ } }, - // eslint-disable-next-line @typescript-eslint/require-await async disconnect() { forgetSession(); }, @@ -139,7 +138,6 @@ export function ledgerHIDConnector({ } }, - // eslint-disable-next-line @typescript-eslint/require-await async switchChain({ chainId }) { const chain = chains.find((x) => x.id === chainId); if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()); diff --git a/packages/connectors/ledger-connector/src/hid/helpers.ts b/packages/connectors/ledger-connector/src/hid/helpers.ts index 3ea329f1..050f0182 100644 --- a/packages/connectors/ledger-connector/src/hid/helpers.ts +++ b/packages/connectors/ledger-connector/src/hid/helpers.ts @@ -13,22 +13,21 @@ export type PersistedLedgerAccount = { export const isLockedDeviceError = (error: unknown): boolean => (error as { name?: string } | null)?.name === 'LockedDeviceError'; -export const checkError = (error: any): never => { - if (error.statusText === 'INS_NOT_SUPPORTED') { - // eslint-disable-next-line no-param-reassign - error.message = +export const checkError = (error: unknown): never => { + // Ledger transport errors expose statusText in addition to the standard Error fields. + const ledgerError = error as { statusText?: string; message?: string }; + if (ledgerError.statusText === 'INS_NOT_SUPPORTED') { + ledgerError.message = 'Device is not supported. Make sure the Ethereum app is open on the device.'; } - if (error.statusText === 'UNKNOWN_ERROR') { - // eslint-disable-next-line no-param-reassign - error.message = + if (ledgerError.statusText === 'UNKNOWN_ERROR') { + ledgerError.message = 'Unknown error. Make sure the device is connected and the Ethereum app is open on the device.'; } - if (error.statusText === 'CONDITIONS_OF_USE_NOT_SATISFIED') { - // eslint-disable-next-line no-param-reassign - error.message = 'User rejected the request'; + if (ledgerError.statusText === 'CONDITIONS_OF_USE_NOT_SATISFIED') { + ledgerError.message = 'User rejected the request'; } throw error; diff --git a/packages/connectors/ledger-connector/src/hid/provider.ts b/packages/connectors/ledger-connector/src/hid/provider.ts index b5d8799b..7dfdbf3d 100644 --- a/packages/connectors/ledger-connector/src/hid/provider.ts +++ b/packages/connectors/ledger-connector/src/hid/provider.ts @@ -1,6 +1,7 @@ import type Eth from '@ledgerhq/hw-app-eth'; import type TransportWebHID from '@ledgerhq/hw-transport-webhid'; import { + ChainMismatchError, createPublicClient, createWalletClient, getAddress, @@ -69,6 +70,10 @@ type RequestArguments = { params?: unknown[]; }; +// Some callers include chainId in eth_sendTransaction, although viem's RPC +// request union does not include it for every transaction type. +type LedgerTransactionRequest = RpcTransactionRequest & { chainId?: Hex }; + type ProviderEvent = 'disconnect'; type Listener = () => void; @@ -116,7 +121,6 @@ export class LedgerHQProvider { this.forceClearSign = forceClearSign; if (!rpcUrl) { - // eslint-disable-next-line no-console console.warn( `[reef-knot] No RPC URL configured for chain ${chain.id} (${chain.name}), ` + `falling back to its default public RPC endpoint`, @@ -254,6 +258,7 @@ export class LedgerHQProvider { }); this.account = createLedgerAccount(address, path, withVerifyingEthApp, { + chainId: this.chain.id, forceClearSign: this.forceClearSign, }); this.accountPath = path; @@ -308,8 +313,16 @@ export class LedgerHQProvider { } private async sendTransaction( - transaction: RpcTransactionRequest, + transaction: LedgerTransactionRequest, ): Promise { + if (transaction.chainId != null) { + const chainId = hexToNumber(transaction.chainId); + if (chainId !== this.chain.id) + throw new ChainMismatchError({ + chain: this.chain, + currentChainId: chainId, + }); + } const walletClient = await this.getWalletClient(); const account = walletClient.account as LocalAccount; @@ -334,6 +347,7 @@ export class LedgerHQProvider { const request = { account, chain: this.chain, + chainId: this.chain.id, to: transaction.to ?? undefined, data: transaction.data, value: transaction.value ? hexToBigInt(transaction.value) : undefined, @@ -393,7 +407,7 @@ export class LedgerHQProvider { return [await this.getAddress()]; case 'eth_sendTransaction': - return this.sendTransaction(params[0] as RpcTransactionRequest); + return this.sendTransaction(params[0] as LedgerTransactionRequest); case 'personal_sign': { const messageHex = params[0]; @@ -415,7 +429,9 @@ export class LedgerHQProvider { if (typeof params[1] !== 'string') throw new Error('eth_signTypedData_v4 arg 1 is not a string'); const account = await this.getAccount(); - return account.signTypedData(JSON.parse(params[1])); + return account.signTypedData( + JSON.parse(params[1]) as Parameters[0], + ); } case 'wallet_getCapabilities': { diff --git a/packages/connectors/ledger-connector/src/iframe/__tests__/helpers.test.ts b/packages/connectors/ledger-connector/src/iframe/__tests__/helpers.test.ts index 10ea7438..7537db1f 100644 --- a/packages/connectors/ledger-connector/src/iframe/__tests__/helpers.test.ts +++ b/packages/connectors/ledger-connector/src/iframe/__tests__/helpers.test.ts @@ -6,7 +6,7 @@ const originalParent = window.parent; // happy-dom is a top-level window: parent === window. Pretend to be embedded. const embedInIframe = () => { Object.defineProperty(window, 'parent', { - value: {} as Window, + value: {}, configurable: true, }); }; diff --git a/packages/connectors/ledger-connector/src/iframe/connector.ts b/packages/connectors/ledger-connector/src/iframe/connector.ts index df0cd9ac..afd23886 100644 --- a/packages/connectors/ledger-connector/src/iframe/connector.ts +++ b/packages/connectors/ledger-connector/src/iframe/connector.ts @@ -149,7 +149,9 @@ export function ledgerLiveConnector({ async getAccounts() { const provider = await this.getProvider(); - const accounts = await provider.send('eth_requestAccounts'); + const accounts = await provider.send( + 'eth_requestAccounts', + ); // Checksum each address; the explicit lambda keeps Array.map's index // out of getAddress's second (chainId, EIP-1191) parameter. return accounts.map((account: string) => getAddress(account)); @@ -157,14 +159,16 @@ export function ledgerLiveConnector({ async getChainId() { const provider = await this.getProvider(); - const chainId = await provider.send('eth_chainId'); + const chainId: unknown = await provider.send('eth_chainId'); return Number(chainId); }, async isAuthorized() { try { const provider = await this.getProvider(); - const accounts = await provider.send('eth_accounts'); + const accounts = await provider.send( + 'eth_accounts', + ); const account = accounts[0]; return !!account; } catch { @@ -180,7 +184,6 @@ export function ledgerLiveConnector({ handlers.onChainChanged(chainId); }, - // eslint-disable-next-line @typescript-eslint/require-await async disconnect() { handlers.detach(); }, diff --git a/packages/connectors/ledger-connector/src/iframe/helpers.ts b/packages/connectors/ledger-connector/src/iframe/helpers.ts index a1aa150e..d8388800 100644 --- a/packages/connectors/ledger-connector/src/iframe/helpers.ts +++ b/packages/connectors/ledger-connector/src/iframe/helpers.ts @@ -9,7 +9,7 @@ export const isLedgerLive = () => { const isEmbed = !!params.get('embed'); return isIframe() && isEmbed; - } catch (error) { + } catch { return false; } }; diff --git a/packages/connectors/ledger-connector/src/iframe/provider.ts b/packages/connectors/ledger-connector/src/iframe/provider.ts index 0afbddc5..15fe1e1b 100644 --- a/packages/connectors/ledger-connector/src/iframe/provider.ts +++ b/packages/connectors/ledger-connector/src/iframe/provider.ts @@ -2,7 +2,7 @@ import { IFrameEthereumProvider } from '@ledgerhq/iframe-provider'; interface RequestArguments { readonly method: string; - readonly params?: any[]; + readonly params?: unknown[]; } export class LedgerIFrameProvider extends IFrameEthereumProvider { diff --git a/packages/connectors/ledger-connector/tsconfig.json b/packages/connectors/ledger-connector/tsconfig.json index 8acf31ca..04cfe874 100644 --- a/packages/connectors/ledger-connector/tsconfig.json +++ b/packages/connectors/ledger-connector/tsconfig.json @@ -4,5 +4,6 @@ "exclude": ["node_modules", "dist"], "compilerOptions": { "rootDir": "src", + "moduleResolution": "bundler", } } diff --git a/packages/core-react/.eslintrc.json b/packages/core-react/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/core-react/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/core-react/CHANGELOG.md b/packages/core-react/CHANGELOG.md deleted file mode 100644 index ae3e9ad7..00000000 --- a/packages/core-react/CHANGELOG.md +++ /dev/null @@ -1,314 +0,0 @@ -# @reef-knot/core-react - -## 7.3.0 - -- Add `ledgerForceClearSign` config option, passed to wallet adapters - -## 7.2.0 - -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update peerDependencies requirements: viem >=2.50, wagmi >=3.6 - -## 7.1.0 - -- Export EIP-6963 provider store, provider type, and `useEIP6963Providers` hook for tracking announced browser wallet providers. -- Add modal stack support for the EIP-6963 provider selection view. - -## 7.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 6.2.0 - -### Minor Changes - -- Adds ability to pass onAutoConnect and onReconnect callbacks to the reef-knot config -- Minor fixes and tech updates - -## 6.1.0 - -### Minor Changes - -- Update viem to v2.23 and wagmi to v2.14, so the @coinbase/wallet-sdk would be updated too, which fixes a dependabot issue - -## 6.0.0 - -### Major Changes - -- Metrics config refactored, replaced with certain actions callbacks - -### Patch Changes - -- Updated dependencies - - @reef-knot/types@4.0.0 - - @reef-knot/wallets-list@4.0.0 - -## 5.1.0 - -### Minor Changes - -- wagmi arguments pass through get default config - -## 5.0.0 - -### Major Changes - -- reef-knot setup rework - -### Patch Changes - -- Updated dependencies - - @reef-knot/types@3.0.0 - - @reef-knot/wallets-list@3.0.0 - -## 4.3.1 - -### Patch Changes - -- accbcde: viem and wagmi versions updated with flexible declarations - -## 4.3.0 - -### Minor Changes - -- Add the "loading" state for WC and Binance wallet connection buttons; -- Fix the "retry" button for some cases in the Ledger HID connection modal; -- Show a loading spinner in the Ledger modal during ledger packages loading; -- Fix the issue with passing onClickWalletsLess, onClickWalletsMore props; - -## 4.2.1 - -### Patch Changes - -- Remove unsupported chain check from eager connect - -## 4.2.0 - -### Minor Changes - -- Support EIP-6963 - -## 4.1.1 - -### Patch Changes - -- Wagmi version updated - -## 4.1.0 - -### Minor Changes - -- Remove WC warning banner - -## 4.0.1 - -### Patch Changes - -- useDisconnect condition fixed - -## 4.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -### Patch Changes - -- Updated dependencies - - @reef-knot/ledger-connector@4.0.0 - - @reef-knot/wallets-helpers@2.0.0 - - @reef-knot/wallets-list@2.0.0 - - @reef-knot/ui-react@2.0.0 - - @reef-knot/types@2.0.0 - -## 3.2.0 - -### Minor Changes - -- a6ca608: Add deeplinks support - -## 3.1.2 - -### Patch Changes - -- Updated dependencies - -## 3.1.1 - -### Patch Changes - -- 92be1c7: Fix "checkIfDisconnectMakesSense" - -## 3.1.0 - -### Minor Changes - -- Make it possible for wallet detectors to be async; -- Improve Safe wallet detection; - -## 3.0.0 - -### Major Changes - -- Rework modals interface, add useConnect hook for connection - -## 2.1.1 - -### Patch Changes - -- Fix isAutoConnectionSuitable, add a separate useAutoConnectCheck hook - -## 2.1.0 - -### Minor Changes - -- 85b3f79: - - rework getUnsupportedChainError, hide mumbai network in the error - - (web3-react) fix logic of useConnectorError - - (web3-react) deprecate useConnectorInfo, useDisconnect - - (core-react) rework and add hooks: useConnectorInfo, useDisconnect, useEagerConnect - - (reef-knot) add connectors export as "Connectors" - -## 2.0.0 - -### Major Changes - -- 1046886: Add auto-connect, based on wagmi and autoConnectOnly wallet adapters - -## 1.8.1 - -### Patch Changes - -- 253796d: Fix typings - -## 1.8.0 - -### Minor Changes - -- Use Ledger hid wallet adapter, based on wagmi - -## 1.7.0 - -### Minor Changes - -- Handle connection errors in AcceptTermsModal - -## 1.6.0 - -### Minor Changes - -- Add Holesky custom wagmi chain - -## 1.5.1 - -### Patch Changes - -- Move TERMS_ACCEPTANCE_LS_K const into core-react package - -## 1.5.0 - -### Minor Changes - -- 217c144: Show "Accept Terms" Modal for Ledger Live, Safe, dapp browsers - -### Patch Changes - -- 48d8c4b: Update wagmi to 0.12.19 - -## 1.4.3 - -### Patch Changes - -- e6e579e: wagmi 0.12.18 - -## 1.4.2 - -### Patch Changes - -- Add a notification about WC v2 issues -- Updated dependencies - - @reef-knot/ui-react@1.0.4 - -## 1.4.1 - -### Patch Changes - -- Update wagmi to v0.12.17 -- Updated dependencies - - @reef-knot/types@1.2.1 - - @reef-knot/wallets-list@1.4.1 - -## 1.4.0 - -### Minor Changes - -- Explicitly pass chains to wagmi connectors, update wagmi to v0.12.16 - -### Patch Changes - -- Updated dependencies - -## 1.3.1 - -### Patch Changes - -- Take WalletConnect project ID as a prop -- Add and export getWalletDataList, use a single instance of walletDataList -- Updated dependencies - - @reef-knot/types@1.1.1 - - @reef-knot/wallets-list@1.3.1 - -## 1.3.0 - -### Minor Changes - -- faa8815: Add Reef Knot context, clean up, wagmi v0.12 - -### Patch Changes - -- Updated dependencies [faa8815] - -## 1.2.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@1.2.0 - -## 1.1.1 - -### Patch Changes - -- WalletConnect: actualize mobileLinks (wallets list on mobiles) - -## 1.1.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallets-list@1.1.0 - -## 1.0.1 - -### Patch Changes - -- Support custom connectors for wallet adapters. Reorganize code. -- Updated dependencies - - @reef-knot/wallets-list@1.0.1 - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes diff --git a/packages/core-react/LICENSE.txt b/packages/core-react/LICENSE.txt deleted file mode 100644 index 07e71353..00000000 --- a/packages/core-react/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Lido - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/core-react/README.md b/packages/core-react/README.md deleted file mode 100644 index c4cee667..00000000 --- a/packages/core-react/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Core React - - diff --git a/packages/core-react/src/constants/localStorage.ts b/packages/core-react/src/constants/localStorage.ts deleted file mode 100644 index 00541e38..00000000 --- a/packages/core-react/src/constants/localStorage.ts +++ /dev/null @@ -1,12 +0,0 @@ -// This key can be changed to enforce all users to accept the Terms again, -// for example if the Terms were significantly updated -export const LS_KEY_TERMS_ACCEPTANCE = 'reef-knot_accept-terms_n2'; - -// Storage key for restoring connector after page refresh -// `/packages/core-react/src/hooks/useAutoConnect.ts` -// Stores either: -// • a reef-knot `WalletAdapterData['walletId']` (for wallets in `walletDataList`), or -// • an EIP-6963 `provider.info.rdns` (for wallets discovered via eip6963:announceProvider -// that are not in `walletDataList`). -// On reconnect both paths are tried: walletDataList lookup first, then EIP-6963 rdns match. -export const LS_KEY_RECONNECT_WALLET_ID = 'reef-knot_reconnect-wallet-id'; diff --git a/packages/core-react/src/context/reefKnotContext.ts b/packages/core-react/src/context/reefKnotContext.ts deleted file mode 100644 index a7fc5eb8..00000000 --- a/packages/core-react/src/context/reefKnotContext.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { createContext } from 'react'; -import type { ReefKnotContextValue } from '@reef-knot/types'; - -// re-export config types from @reef-knot/types for legacy reasons -export type { - ReefKnotConfig, - ReefKnotProviderConfig, - ReefKnotContextValue, -} from '@reef-knot/types'; - -/** - * Context definition is in separated file to avoid circular dependencies - */ - -export const ReefKnotContext = createContext({} as ReefKnotContextValue); diff --git a/packages/core-react/src/hooks/useAutoConnect.ts b/packages/core-react/src/hooks/useAutoConnect.ts deleted file mode 100644 index 12346f4b..00000000 --- a/packages/core-react/src/hooks/useAutoConnect.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { useEffect } from 'react'; -import { useConfig, useConnection, useReconnect } from 'wagmi'; -import { injected } from 'wagmi/connectors'; -import { useEagerConnect } from './useEagerConnect'; -import { checkTermsAccepted } from '../helpers/checkTermsAccepted'; -import { useReefKnotContext } from './useReefKnotContext'; -import { LS_KEY_RECONNECT_WALLET_ID } from '../constants'; -import { withCallback } from '../helpers/withCallback'; -import { providersStore } from '../eip6963'; - -export const useAutoConnect = (autoConnectEnabled: boolean) => { - const { storage } = useConfig(); - const { mutateAsync: reconnectAsync } = useReconnect(); - const { isConnected } = useConnection(); - const { eagerConnect } = useEagerConnect(); - const { walletDataList, onReconnect } = useReefKnotContext(); - - useEffect(() => { - const tryReconnect = async () => { - // Don't auto-connect if already connected or if the auto-connect feature is disabled - if (isConnected || !autoConnectEnabled) return; - - // Try to eagerly connect wallets that are meant to be used only with auto-connection. - // For example, wallets with dApp browsers, or using iframes to open dApps. - const connectResult = await eagerConnect(); - - // If still not connected and there were no errors and the terms of service are accepted, - // call the default wagmi autoConnect method, which attempts to connect to the last used connector. - if ( - !connectResult && - checkTermsAccepted() && - // We do not want to reconnect if the `recentConnectorId` item was deleted during disconnect - (await storage?.getItem('recentConnectorId')) - ) { - const savedReconnectWalletId = await storage?.getItem( - LS_KEY_RECONNECT_WALLET_ID, - ); - const walletData = walletDataList.find( - (data) => data.walletId === savedReconnectWalletId, - ); - // Wait for all EIP-6963 wallets to load their code and fire "eip6963:announceProvider" event - // Without the delay, this code can be called from a browser's cache faster than wallet extension code - await new Promise((resolve) => setTimeout(resolve, 100)); - - const reconnectWithCallback = withCallback(reconnectAsync, onReconnect); - - if (walletData) { - let createConnectorFn = walletData.createConnectorFn; - if (walletData?.walletconnectExtras?.connectionViaURI?.condition) { - createConnectorFn = - walletData.walletconnectExtras.connectionViaURI.createConnectorFn; - } - - await reconnectWithCallback({ connectors: [createConnectorFn] }); - } else { - const eip6963Provider = providersStore - .getProviders() - .find((p) => p.info.rdns === savedReconnectWalletId); - - if (eip6963Provider) { - const createConnectorFn = injected({ - target: { - id: eip6963Provider.info.rdns, - name: eip6963Provider.info.name, - provider: () => eip6963Provider.provider, - }, - }); - await reconnectWithCallback({ connectors: [createConnectorFn] }); - } - } - } - }; - - void tryReconnect(); - - // No hook deps: do not retry the auto-connect attemption. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); -}; diff --git a/packages/core-react/src/hooks/useDisconnect.ts b/packages/core-react/src/hooks/useDisconnect.ts deleted file mode 100644 index 4998ef8c..00000000 --- a/packages/core-react/src/hooks/useDisconnect.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useCallback, useMemo } from 'react'; -import { - useConnection, - useConfig, - useDisconnect as useDisconnectWagmi, -} from 'wagmi'; -import { useReefKnotContext } from './useReefKnotContext'; -import { useReefKnotModal } from './useReefKnotModal'; -import { LS_KEY_RECONNECT_WALLET_ID } from '../constants'; - -const useDisconnectCleaningStorage = () => { - const { storage } = useConfig(); - const { mutate: disconnect } = useDisconnectWagmi(); - - return useCallback( - (...args: Parameters) => { - disconnect(...args); - void storage?.removeItem('recentConnectorId'); - void storage?.removeItem(LS_KEY_RECONNECT_WALLET_ID); - }, - [disconnect, storage], - ); -}; - -export const useForceDisconnect = () => { - const disconnect = useDisconnectCleaningStorage(); - const { forceCloseAllModals } = useReefKnotModal(); - - const forceDisconnect = useCallback(() => { - forceCloseAllModals(); - disconnect(); - }, [disconnect, forceCloseAllModals]); - - return { forceDisconnect }; -}; - -export const useDisconnect = (): { - disconnect?: () => void; - isDisconnectMakesSense: boolean; -} => { - const { isConnected, connector } = useConnection(); - const disconnect = useDisconnectCleaningStorage(); - const { walletDataList } = useReefKnotContext(); - - const isDisconnectMakesSense = useMemo(() => { - // It doesn't make sense to offer a user the ability to disconnect if the user is not connected yet, - // or if the user was connected automatically - const connectorData = walletDataList.find( - (c) => c.walletId === connector?.id, - ); - return isConnected && !connectorData?.autoConnectOnly; - }, [isConnected, connector, walletDataList]); - - return { - disconnect: isDisconnectMakesSense ? disconnect : undefined, - isDisconnectMakesSense, - }; -}; diff --git a/packages/core-react/tsconfig.json b/packages/core-react/tsconfig.json deleted file mode 100644 index 23709e73..00000000 --- a/packages/core-react/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], - "compilerOptions": { - "rootDir": "src", - } -} diff --git a/packages/core-react/tsdown.config.ts b/packages/core-react/tsdown.config.ts deleted file mode 100644 index 57dae503..00000000 --- a/packages/core-react/tsdown.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; - -export default defineConfig(defineStandardConfig()); diff --git a/packages/eslint-config-custom/.eslintrc.json b/packages/eslint-config-custom/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/eslint-config-custom/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/eslint-config-custom/index.js b/packages/eslint-config-custom/index.js deleted file mode 100644 index 168eb42d..00000000 --- a/packages/eslint-config-custom/index.js +++ /dev/null @@ -1,37 +0,0 @@ -const { resolve } = require('node:path'); - -const project = resolve(process.cwd(), 'tsconfig.json'); - -module.exports = { - env: { - browser: true, - es2021: true, - node: true, - }, - extends: ['turbo', '@lidofinance', 'prettier'], - plugins: ['prettier', '@typescript-eslint', 'react', 'react-hooks'], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - ecmaVersion: 12, - sourceType: 'module', - project: project, - }, - ignorePatterns: ['*.js', '*.config.ts', 'dist/', 'node_modules/'], - settings: { - react: { - version: 'detect', - }, - 'import/resolver': { - typescript: { - project, - }, - }, - }, - rules: { - 'prettier/prettier': ['error', {}, { usePrettierrc: true }], - 'react/react-in-jsx-scope': 'off', - }, -}; diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json deleted file mode 100644 index 6ad0af6c..00000000 --- a/packages/eslint-config-custom/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "eslint-config-custom", - "version": "0.0.0", - "private": true, - "main": "index.js", - "files": [ - "index.js" - ] -} diff --git a/packages/reef-knot/.eslintrc.json b/packages/reef-knot/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/reef-knot/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/reef-knot/CHANGELOG.md b/packages/reef-knot/CHANGELOG.md index 315ea9d8..83e74b90 100644 --- a/packages/reef-knot/CHANGELOG.md +++ b/packages/reef-knot/CHANGELOG.md @@ -1,5 +1,39 @@ # reef-knot +## 9.0.0 + +### Breaking changes + +- Merge the core, types and default wallet catalog into `reef-knot`. Use named imports from `reef-knot`; the old namespace and `reef-knot/*` imports are removed. +- Add two new UI skin packages and move the wallet modal and UI components into them: `@reef-knot/ui-lido-legacy` keeps the previous Lido appearance, and `@reef-knot/ui-lido` uses Lido App UI. Use a skin for a ready-made modal, or build a custom skin with the public headless hooks. The core no longer requires a UI kit or styled-components. +- Remove `useWeb3` and `useSupportedChains`. Use wagmi hooks instead. +- Replace `buttonComponentsByConnectorId` and wallet-specific `Connect*` components with `components.WalletButton`. +- Remove the `linkDontHaveWallet` modal option and the WalletConnect URI redirect flow, including `walletconnectExtras` and `getWalletConnectUri`. +- Save wallet and connector IDs together for reconnect. Wallets saved by older versions need one manual connection after upgrading. +- Remove the shared `@reef-knot/wallets-icons` package. Use wallet adapter icons or provide your own. +- Rename the modal result field from `success` to `connected`. This changes the results of `startConnection()`, `connect()`, `openModalAsync()` and the `closeModal()` argument. +- The modal Close action now closes all screens. Use Back to return to the previous screen. + +### Added + +- Add public hooks and providers for custom wallet pickers, Terms, eager connection, EIP-6963 selection and Ledger screens. +- Add shared modal focus, Escape and scroll-lock hooks, plus a renderer with replaceable screen components. +- Add `goBack()` to `useReefKnotModal()`. It removes the top screen and shows the previous one. +- Add `useConnectionFlow().startConnection()`. Keep `useConnect().connect()` as a deprecated wrapper. +- Add `disconnectAsync()` to `useDisconnect()` for callers that need to wait for cleanup. +- Add [upgrade instructions](../../docs/migration-guide-8.x-to-9.md) and a [custom UI guide](../../docs/headless-ui.md). + +### Fixed + +- Show clear connection errors with a way back to the picker. Keep search, expanded wallets and Terms acceptance when dismissing an error. +- Wait for the old wallet to disconnect before connecting a new one. Ignore errors from dismissed screens and verify the selected connection before reporting success. +- Disconnect every wallet retained by wagmi and clear reconnect storage, even if a wallet fails to disconnect. +- Reconnect only when the saved wallet matches wagmi's last connector. Wait for late EIP-6963 announcements before trying to reconnect. +- Keep Ledger account loading in order and preserve the account screen while handing the device over to the connector. +- Keep the selected Ledger account when replacing a connection. If Ledger returns a different account, refresh the list and let the user choose again. +- Reject Ledger HID transactions for a chain other than the configured chain. +- Keep the full page URL in OKX wallet links and encode it safely. + ## 8.4.0 - Add `ledgerForceClearSign` config option for the Ledger HID wallet diff --git a/packages/reef-knot/README.md b/packages/reef-knot/README.md index 2cbc6378..93fb8eb3 100644 --- a/packages/reef-knot/README.md +++ b/packages/reef-knot/README.md @@ -1,3 +1,25 @@ -# Reef Knot Index Package +# Reef Knot -Re-exports other Reef Knot packages. It is advised to use it for importing something from Reef Knot. +The main Reef Knot package contains the wallet connection core, React providers +and headless hooks, configuration types, and the default Ethereum +wallet catalog. + +Import the public core APIs from `reef-knot` and the ready-made wallet modal +from your chosen UI skin: + +```ts +import { + ReefKnotProvider, + WalletsListEthereum, + getDefaultConfig, +} from 'reef-knot'; +import { ReefKnotWalletsModal } from '@reef-knot/ui-lido'; +``` + +Use `@reef-knot/ui-lido-legacy` instead for the legacy appearance, or build +your own UI with the headless hooks. See [the headless UI guide](../../docs/headless-ui.md) +for setup and customization. + +Wallet adapters and the Ledger connector remain separate packages so they can +be built, tested, and released independently. Shared adapter types and helpers +live in `@reef-knot/wallets-helpers`. diff --git a/packages/reef-knot/package.json b/packages/reef-knot/package.json index 365a3c52..2aa8b6e0 100644 --- a/packages/reef-knot/package.json +++ b/packages/reef-knot/package.json @@ -4,16 +4,16 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "exports": { - ".": "./dist/index.js", - "./*": "./dist/packages/*.js" + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } }, "typesVersions": { "*": { ".": [ "dist/index.d.ts" - ], - "*": [ - "dist/packages/*" ] } }, @@ -38,30 +38,48 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit", + "test": "vitest run" }, "dependencies": { - "@reef-knot/connect-wallet-modal": "*", - "@reef-knot/core-react": "*", + "@ledgerhq/hw-app-eth": "7.8.12", + "@ledgerhq/hw-transport": "6.35.7", + "@ledgerhq/hw-transport-webhid": "6.36.0", "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", - "@reef-knot/ui-react": "*", + "@reef-knot/wallet-adapter-ambire": "*", + "@reef-knot/wallet-adapter-anchorage-digital": "*", + "@reef-knot/wallet-adapter-bitkeep": "*", + "@reef-knot/wallet-adapter-browser-extension": "*", + "@reef-knot/wallet-adapter-coinbase-smart-wallet": "*", + "@reef-knot/wallet-adapter-dapp-browser-injected": "*", + "@reef-knot/wallet-adapter-imtoken": "*", + "@reef-knot/wallet-adapter-ledger-hid": "*", + "@reef-knot/wallet-adapter-ledger-live": "*", + "@reef-knot/wallet-adapter-metamask": "*", + "@reef-knot/wallet-adapter-okx": "*", + "@reef-knot/wallet-adapter-safe": "*", + "@reef-knot/wallet-adapter-walletconnect": "*", "@reef-knot/wallets-helpers": "*", - "@reef-knot/wallets-list": "*", - "@reef-knot/web3-react": "*" + "mipd": "0.0.7" }, "peerDependencies": { - "@lidofinance/lido-ui": "^3.18.0", "@tanstack/react-query": "^5.51.1", "react": ">=18", "react-dom": ">=18", - "styled-components": "^5.3.5", "viem": ">=2.50", "wagmi": ">=3.6" }, "devDependencies": { + "@types/react": "18.2.45", + "@types/react-dom": "18.2.17", "build-config": "*", - "eslint-config-custom": "*" + "happy-dom": "^20.0.0", + "react": "18.2.0", + "react-dom": "18.2.0", + "tsconfig": "*", + "viem": ">=2.50", + "vitest": "^4.1.11", + "wagmi": ">=3.6" } } diff --git a/packages/core-react/src/components/AutoConnect.tsx b/packages/reef-knot/src/core-react/components/AutoConnect.tsx similarity index 100% rename from packages/core-react/src/components/AutoConnect.tsx rename to packages/reef-knot/src/core-react/components/AutoConnect.tsx diff --git a/packages/core-react/src/constants/index.ts b/packages/reef-knot/src/core-react/constants/index.ts similarity index 100% rename from packages/core-react/src/constants/index.ts rename to packages/reef-knot/src/core-react/constants/index.ts diff --git a/packages/reef-knot/src/core-react/constants/localStorage.ts b/packages/reef-knot/src/core-react/constants/localStorage.ts new file mode 100644 index 00000000..79ae59c1 --- /dev/null +++ b/packages/reef-knot/src/core-react/constants/localStorage.ts @@ -0,0 +1,6 @@ +// This key can be changed to enforce all users to accept the Terms again, +// for example if the Terms were significantly updated +export const LS_KEY_TERMS_ACCEPTANCE = 'reef-knot_accept-terms_n2'; + +// Keep the wallet id or provider rdns to restore the same wallet after a refresh. +export const LS_KEY_RECONNECT_WALLET_ID = 'reef-knot_reconnect-wallet-id'; diff --git a/packages/reef-knot/src/core-react/context/reefKnotContext.ts b/packages/reef-knot/src/core-react/context/reefKnotContext.ts new file mode 100644 index 00000000..b54bd000 --- /dev/null +++ b/packages/reef-knot/src/core-react/context/reefKnotContext.ts @@ -0,0 +1,4 @@ +import { createContext } from 'react'; +import type { ReefKnotContextValue } from '../../types/index'; + +export const ReefKnotContext = createContext({} as ReefKnotContextValue); diff --git a/packages/core-react/src/context/reefKnotModalContext.tsx b/packages/reef-knot/src/core-react/context/reefKnotModalContext.tsx similarity index 70% rename from packages/core-react/src/context/reefKnotModalContext.tsx rename to packages/reef-knot/src/core-react/context/reefKnotModalContext.tsx index 9f41910d..f09e6b83 100644 --- a/packages/core-react/src/context/reefKnotModalContext.tsx +++ b/packages/reef-knot/src/core-react/context/reefKnotModalContext.tsx @@ -11,7 +11,8 @@ import type { EIP6963ProviderDetail } from '../eip6963'; /// MODAL STATE -type RequirementsData = { +export type RequirementsData = { + kind?: 'no-wallets'; icon?: ReactNode; title?: string; text?: ReactNode; @@ -22,7 +23,7 @@ type EIP6963ModalData = { onSelect: (provider: EIP6963ProviderDetail) => void | Promise; }; -type ModalTypes = +export type ModalTypes = | { type: 'wallet' | 'ledger'; props?: undefined; @@ -30,6 +31,7 @@ type ModalTypes = | { type: 'eager'; props: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any tryConnection: () => Promise; initialError?: Error; }; @@ -43,11 +45,12 @@ type ModalTypes = props: EIP6963ModalData; }; -type ModalResult = { - success: boolean; +export type ModalResult = { + /** False when the screen closed without a wallet connection. */ + connected: boolean; }; -type ModalStateEntry = { +export type ModalStateEntry = { onClose: (props: ModalResult) => void; } & ModalTypes; @@ -62,6 +65,8 @@ export type ReefKnotModalContextValue = { openModalAsync: (params: AsyncModalOpenParams) => Promise; forceCloseAllModals: () => void; closeModal: (result: ModalResult) => void; + /** Removes the top screen. The screen below becomes active again. */ + goBack: () => void; modalStack: ModalStateEntry[]; currentModal: ModalStateEntry | undefined; termsChecked: boolean; @@ -83,53 +88,57 @@ export const ReefKnotModalContextProvider = ({ ); const [modalStack, updateModalStack] = useState([]); const modalStackRef = useRef([]); - const stableCallbacks = useMemo( - () => ({ + const stableCallbacks = useMemo(() => { + const closeModal = (result: ModalResult) => { + const old = modalStackRef.current; + const modal = old[old.length - 1]; + const next = old.slice(0, -1); + + modalStackRef.current = next; + updateModalStack(next); + modal?.onClose(result); + }; + return { openModal: ({ onClose = NOOP, ...props }: ModalOpenParams) => { const next = [...modalStackRef.current, { ...props, onClose }]; modalStackRef.current = next; updateModalStack(next); }, - openModalAsync: async ({ type, props }: AsyncModalOpenParams) => { + openModalAsync: async (params: AsyncModalOpenParams) => { return new Promise((resolve) => { const next = [ - // for some reason TS cannot match type and props here ...modalStackRef.current, - { type, props: props as any, onClose: resolve }, + // Omit does not preserve the discriminated union in AsyncModalOpenParams. + { + type: params.type, + props: params.props, + onClose: resolve, + } as ModalStateEntry, ]; modalStackRef.current = next; updateModalStack(next); }); }, - closeModal: (result: ModalResult) => { - const old = modalStackRef.current; - const modal = old[old.length - 1]; - const next = old.slice(0, -1); - - modalStackRef.current = next; - updateModalStack(next); - modal?.onClose(result); - }, + closeModal, + goBack: () => closeModal({ connected: false }), forceCloseAllModals: () => { const old = modalStackRef.current; modalStackRef.current = []; for (let i = old.length - 1; i >= 0; i -= 1) { - old[i]?.onClose({ success: false }); + old[i]?.onClose({ connected: false }); } updateModalStack([]); }, - }), - [], - ); + }; + }, []); const contextValue = useMemo( () => ({ modalStack, - currentModal: modalStack[modalStack.length - 1] as - ModalStateEntry | undefined, + currentModal: modalStack[modalStack.length - 1], termsChecked, setTermsChecked, ...stableCallbacks, diff --git a/packages/core-react/src/context/reefKnotProvider.tsx b/packages/reef-knot/src/core-react/context/reefKnotProvider.tsx similarity index 89% rename from packages/core-react/src/context/reefKnotProvider.tsx rename to packages/reef-knot/src/core-react/context/reefKnotProvider.tsx index a9bbd299..53e0ba0d 100644 --- a/packages/core-react/src/context/reefKnotProvider.tsx +++ b/packages/reef-knot/src/core-react/context/reefKnotProvider.tsx @@ -1,7 +1,8 @@ import React, { ReactNode, useMemo, useState } from 'react'; import { ReefKnotModalContextProvider } from './reefKnotModalContext'; -import { ReefKnotContext, ReefKnotProviderConfig } from './reefKnotContext'; +import { ReefKnotContext } from './reefKnotContext'; import { AutoConnect } from '../components/AutoConnect'; +import { ReefKnotProviderConfig } from '../../types'; export interface ReefKnotProviderProps { config: ReefKnotProviderConfig; diff --git a/packages/core-react/src/eip6963.ts b/packages/reef-knot/src/core-react/eip6963.ts similarity index 100% rename from packages/core-react/src/eip6963.ts rename to packages/reef-knot/src/core-react/eip6963.ts diff --git a/packages/core-react/src/helpers/checkTermsAccepted.ts b/packages/reef-knot/src/core-react/helpers/checkTermsAccepted.ts similarity index 100% rename from packages/core-react/src/helpers/checkTermsAccepted.ts rename to packages/reef-knot/src/core-react/helpers/checkTermsAccepted.ts diff --git a/packages/core-react/src/helpers/getConnectedProviderName.ts b/packages/reef-knot/src/core-react/helpers/getConnectedProviderName.ts similarity index 92% rename from packages/core-react/src/helpers/getConnectedProviderName.ts rename to packages/reef-knot/src/core-react/helpers/getConnectedProviderName.ts index c861162f..40d6fb43 100644 --- a/packages/core-react/src/helpers/getConnectedProviderName.ts +++ b/packages/reef-knot/src/core-react/helpers/getConnectedProviderName.ts @@ -1,5 +1,5 @@ import type { Connector } from 'wagmi'; -import type { WalletAdapterData } from '@reef-knot/types'; +import type { WalletAdapterData } from '../../types/index'; import { providersStore } from '../eip6963'; type GetConnectedProviderNameArgs = { diff --git a/packages/core-react/src/helpers/getDefaultConfig.ts b/packages/reef-knot/src/core-react/helpers/getDefaultConfig.ts similarity index 86% rename from packages/core-react/src/helpers/getDefaultConfig.ts rename to packages/reef-knot/src/core-react/helpers/getDefaultConfig.ts index e4c43dca..66c3c786 100644 --- a/packages/core-react/src/helpers/getDefaultConfig.ts +++ b/packages/reef-knot/src/core-react/helpers/getDefaultConfig.ts @@ -4,7 +4,7 @@ import type { ReefKnotWalletsModalConfig, ReefKnotProviderConfig, ReefKnotConfig, -} from '@reef-knot/types'; +} from '../../types/index'; import { getWalletsDataList, GetWalletsDataListArgs, @@ -23,7 +23,7 @@ type WagmiConfigArgs = Omit< 'connectors' | 'client' >; -type DefaultConfigArgs = ReefKnotConfig & +export type DefaultConfigArgs = ReefKnotConfig & ReefKnotWalletsModalConfig & GetWalletsDataListArgs & WagmiConfigArgs; @@ -52,13 +52,11 @@ export const getDefaultConfig = ({ onReconnect, // Wallets config args - buttonComponentsByConnectorId, walletsShown, walletsPinned, walletsDisplayInitialCount, linkTerms, linkPrivacyNotice, - linkDontHaveWallet, onClickTermsAccept, onClickWalletsLess, onClickWalletsMore, @@ -91,15 +89,12 @@ export const getDefaultConfig = ({ ...wagmiArgs, }); - // TODO: We could use `getDefaultWalletsModalConfig` here, but it cause package dependency cycle rn - const walletsModalConfig: ReefKnotWalletsModalConfig = { - buttonComponentsByConnectorId, + const walletsModalConfig: ReefKnotWalletsModalConfig = { walletsShown, walletsPinned, walletsDisplayInitialCount, linkTerms, linkPrivacyNotice, - linkDontHaveWallet, onClickTermsAccept, onClickWalletsLess, onClickWalletsMore, diff --git a/packages/core-react/src/helpers/getUnsupportedChainError.ts b/packages/reef-knot/src/core-react/helpers/getUnsupportedChainError.ts similarity index 100% rename from packages/core-react/src/helpers/getUnsupportedChainError.ts rename to packages/reef-knot/src/core-react/helpers/getUnsupportedChainError.ts diff --git a/packages/core-react/src/helpers/getWalletsDataList.ts b/packages/reef-knot/src/core-react/helpers/getWalletsDataList.ts similarity index 87% rename from packages/core-react/src/helpers/getWalletsDataList.ts rename to packages/reef-knot/src/core-react/helpers/getWalletsDataList.ts index 8ebf24fd..5ab53a0f 100644 --- a/packages/core-react/src/helpers/getWalletsDataList.ts +++ b/packages/reef-knot/src/core-react/helpers/getWalletsDataList.ts @@ -1,5 +1,5 @@ import type { Chain } from 'wagmi/chains'; -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '../../types/index'; import { providersStore } from '../eip6963'; export interface GetWalletsDataListArgs { @@ -22,7 +22,7 @@ export const getWalletsDataList = ({ const walletAdapters = Object.values(walletsList); if (!rpc[defaultChain.id]) { - throw 'RPC for default chain must be provided'; + throw new Error('RPC for default chain must be provided'); } const walletsDataList = walletAdapters.map((walletAdapter) => diff --git a/packages/core-react/src/helpers/index.ts b/packages/reef-knot/src/core-react/helpers/index.ts similarity index 85% rename from packages/core-react/src/helpers/index.ts rename to packages/reef-knot/src/core-react/helpers/index.ts index 3caf08c3..2eaa0d66 100644 --- a/packages/core-react/src/helpers/index.ts +++ b/packages/reef-knot/src/core-react/helpers/index.ts @@ -4,3 +4,4 @@ export * from './getWalletsDataList'; export * from './checkTermsAccepted'; export * from './providerDetectors'; export * from './useLocalStorage'; +export * from './interceptLedgerError'; diff --git a/packages/web3-react/src/helpers/interceptLedgerError.ts b/packages/reef-knot/src/core-react/helpers/interceptLedgerError.ts similarity index 61% rename from packages/web3-react/src/helpers/interceptLedgerError.ts rename to packages/reef-knot/src/core-react/helpers/interceptLedgerError.ts index 42f40b3b..5107b7c9 100644 --- a/packages/web3-react/src/helpers/interceptLedgerError.ts +++ b/packages/reef-knot/src/core-react/helpers/interceptLedgerError.ts @@ -1,3 +1,5 @@ +import { UserFacingError } from './userFacingError'; + export const LedgerErrorsDict: Record = { TransportOpenUserCancelled: 'The connection attempt has been rejected.', TransportStatusError: @@ -8,10 +10,10 @@ export const LedgerErrorsDict: Record = { TransportError: undefined, }; +// Keep the original error if there is no message for it. The UI then shows a generic message. export const interceptLedgerError = (error: Error) => { - if (Object.hasOwn(LedgerErrorsDict, error.name)) { - return new Error(LedgerErrorsDict[error.name]); - } - - return error; + const message = Object.hasOwn(LedgerErrorsDict, error.name) + ? LedgerErrorsDict[error.name] + : undefined; + return message ? new UserFacingError(message, { cause: error }) : error; }; diff --git a/packages/core-react/src/helpers/providerDetectors.ts b/packages/reef-knot/src/core-react/helpers/providerDetectors.ts similarity index 100% rename from packages/core-react/src/helpers/providerDetectors.ts rename to packages/reef-knot/src/core-react/helpers/providerDetectors.ts diff --git a/packages/core-react/src/helpers/useLocalStorage.ts b/packages/reef-knot/src/core-react/helpers/useLocalStorage.ts similarity index 82% rename from packages/core-react/src/helpers/useLocalStorage.ts rename to packages/reef-knot/src/core-react/helpers/useLocalStorage.ts index b7a82d9d..43608ff3 100644 --- a/packages/core-react/src/helpers/useLocalStorage.ts +++ b/packages/reef-knot/src/core-react/helpers/useLocalStorage.ts @@ -9,13 +9,16 @@ export function useLocalStorage(key: string, initialValue: T) { item = window.localStorage?.getItem(key); } // Parse stored json or if none return initialValue - return item ? JSON.parse(item) : initialValue; + return item ? (JSON.parse(item) as T) : initialValue; }); // Return a wrapped version of useState's setter function that persists the new value to localStorage. const setValue = (value: T) => { // Allow value to be a function, so we have same API as useState - const valueToStore = value instanceof Function ? value(storedValue) : value; + const valueToStore: T = + value instanceof Function + ? (value as (previous: T) => T)(storedValue) + : value; // Save state setStoredValue(valueToStore); // Save to local storage diff --git a/packages/reef-knot/src/core-react/helpers/userFacingError.ts b/packages/reef-knot/src/core-react/helpers/userFacingError.ts new file mode 100644 index 00000000..be09d6d1 --- /dev/null +++ b/packages/reef-knot/src/core-react/helpers/userFacingError.ts @@ -0,0 +1,10 @@ +/** + * An error with a message that we wrote for the user. + * The UI shows only these messages. It replaces other error text with a generic one. + */ +export class UserFacingError extends Error { + constructor(message: string, options?: ErrorOptions) { + super(message, options); + this.name = 'UserFacingError'; + } +} diff --git a/packages/core-react/src/helpers/withCallback.ts b/packages/reef-knot/src/core-react/helpers/withCallback.ts similarity index 56% rename from packages/core-react/src/helpers/withCallback.ts rename to packages/reef-knot/src/core-react/helpers/withCallback.ts index 0828956d..ed8c4a6b 100644 --- a/packages/core-react/src/helpers/withCallback.ts +++ b/packages/reef-knot/src/core-react/helpers/withCallback.ts @@ -1,13 +1,16 @@ // Utility to wrap a function and call a callback after the function call export function withCallback< - T extends (...args: any[]) => any, - C extends ((...args: any[]) => void) | undefined, + T extends (...args: never[]) => unknown, + C extends ((...args: never[]) => void) | undefined, >( fn: T, callback: C, ): (...args: Parameters) => ReturnType | Promise> { + const call = fn as ( + ...args: Parameters + ) => ReturnType | Promise>; return async (...args: Parameters) => { - const result = await fn(...args); + const result = await call(...args); if (callback) callback(); return result; }; diff --git a/packages/reef-knot/src/core-react/hooks/__tests__/useAutoConnect.test.tsx b/packages/reef-knot/src/core-react/hooks/__tests__/useAutoConnect.test.tsx new file mode 100644 index 00000000..894b1155 --- /dev/null +++ b/packages/reef-knot/src/core-react/hooks/__tests__/useAutoConnect.test.tsx @@ -0,0 +1,222 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import type { WalletAdapterData } from '@reef-knot/wallets-helpers'; +import { useAutoConnect } from '../useAutoConnect'; +import { LS_KEY_RECONNECT_WALLET_ID } from '../../constants'; + +type ProviderDetail = { + info: { rdns: string; name: string }; + provider: unknown; +}; +const mocks = vi.hoisted(() => ({ + items: new Map(), + reconnect: vi.fn(async () => []), + providers: [] as ProviderDetail[], + listeners: new Set<(providers: ProviderDetail[]) => void>(), + state: { status: 'disconnected' }, +})); +vi.mock('wagmi', async (importOriginal) => ({ + ...(await importOriginal()), + useConfig: () => ({ + storage: { getItem: async (key: string) => mocks.items.get(key) ?? null }, + state: mocks.state, + }), + useReconnect: () => ({ mutateAsync: mocks.reconnect }), + useConnection: () => ({ isConnected: false }), +})); +vi.mock('../useEagerConnect', () => ({ + useEagerConnect: () => ({ eagerConnect: async () => null }), +})); +vi.mock('../../helpers/checkTermsAccepted', () => ({ + checkTermsAccepted: () => true, +})); +vi.mock('../../eip6963', () => ({ + providersStore: { + getProviders: () => mocks.providers, + subscribe: (listener: (providers: ProviderDetail[]) => void) => { + mocks.listeners.add(listener); + return () => mocks.listeners.delete(listener); + }, + }, +})); + +const createLedger = vi.fn(); +const createMetaMask = vi.fn(); +const createOkx = vi.fn(); +const walletDataList = [ + { walletId: 'ledgerHID', createConnectorFn: createLedger }, + { + walletId: 'metaMask', + type: 'metaMask', + rdns: 'io.metamask', + createConnectorFn: createMetaMask, + }, + { + walletId: 'okx', + type: 'injected', + rdns: 'com.okex.wallet', + createConnectorFn: createOkx, + }, +] as unknown as WalletAdapterData[]; +vi.mock('../useReefKnotContext', () => ({ + useReefKnotContext: () => ({ walletDataList, onReconnect: undefined }), +})); + +function Probe() { + useAutoConnect(true); + return null; +} +let root: Root; +let container: HTMLDivElement; + +const save = (recentConnectorId: string | null, walletId: unknown) => { + mocks.items.set('recentConnectorId', recentConnectorId); + mocks.items.set(LS_KEY_RECONNECT_WALLET_ID, walletId); +}; +async function mountAndWait(duringDelay?: () => void) { + await act(async () => root.render()); + duringDelay?.(); + await act(async () => vi.advanceTimersByTimeAsync(100)); +} +const wait = (ms: number) => act(async () => vi.advanceTimersByTimeAsync(ms)); +const announce = (detail: ProviderDetail) => + act(async () => { + mocks.providers = [...mocks.providers, detail]; + mocks.listeners.forEach((listener) => listener(mocks.providers)); + }); +const okxDetail = { + info: { rdns: 'com.okex.wallet', name: 'OKX Wallet' }, + provider: {}, +}; + +beforeEach(() => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + vi.useFakeTimers(); + vi.clearAllMocks(); + mocks.items.clear(); + mocks.providers = []; + mocks.listeners.clear(); + mocks.state = { status: 'disconnected' }; + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); +}); +afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); + vi.useRealTimers(); +}); + +describe('useAutoConnect', () => { + it('restores a wallet id saved by v8', async () => { + save('metaMask', 'metaMask'); + await mountAndWait(); + expect(mocks.reconnect).toHaveBeenCalledExactlyOnceWith({ + connectors: [createMetaMask], + }); + }); + it('reconnects a saved EIP-6963 wallet by rdns', async () => { + const provider = { info: { rdns: 'org.test', name: 'Test' }, provider: {} }; + mocks.providers = [provider]; + save('org.test', 'org.test'); + await mountAndWait(); + expect(mocks.reconnect).toHaveBeenCalledOnce(); + }); + it.each([ + ['no recent connector', null, 'metaMask'], + ['no saved wallet', 'metaMask', null], + ['an empty wallet id', 'metaMask', ''], + ['an invalid wallet id', 'metaMask', 123], + ])('does not reconnect with %s', async (_, recent, walletId) => { + save(recent, walletId); + await mountAndWait(); + expect(mocks.reconnect).not.toHaveBeenCalled(); + }); + it('uses the keys stored after the discovery delay', async () => { + save('ledgerHID', 'ledgerHID'); + await mountAndWait(() => save('metaMask', 'metaMask')); + expect(mocks.reconnect).toHaveBeenCalledExactlyOnceWith({ + connectors: [createMetaMask], + }); + }); + + describe('waiting for an EIP-6963 wallet', () => { + it('reconnects an injected wallet after its late announcement', async () => { + save('com.okex.wallet', 'okx'); + await mountAndWait(); + expect(mocks.reconnect).not.toHaveBeenCalled(); + + await announce(okxDetail); + expect(mocks.reconnect).toHaveBeenCalledExactlyOnceWith({ + connectors: [createOkx], + }); + expect(mocks.listeners.size).toBe(0); + }); + + it('leaves wagmi to skip an injected wallet that never announces', async () => { + save('com.okex.wallet', 'okx'); + await mountAndWait(); + await wait(999); + expect(mocks.reconnect).not.toHaveBeenCalled(); + + // The connector has no provider now, so wagmi does not authorize it. + await wait(1); + expect(mocks.reconnect).toHaveBeenCalledExactlyOnceWith({ + connectors: [createOkx], + }); + expect(mocks.listeners.size).toBe(0); + }); + + it('reconnects a wallet outside the list after its late announcement', async () => { + save('org.test', 'org.test'); + await mountAndWait(); + await announce({ + info: { rdns: 'org.test', name: 'Test' }, + provider: {}, + }); + expect(mocks.reconnect).toHaveBeenCalledOnce(); + }); + + it('stays disconnected when a wallet outside the list never announces', async () => { + save('org.test', 'org.test'); + await mountAndWait(); + await wait(1000); + expect(mocks.reconnect).not.toHaveBeenCalled(); + expect(mocks.listeners.size).toBe(0); + }); + + it.each([ + ['recentConnectorId', null], + ['recentConnectorId', 'metaMask'], + [LS_KEY_RECONNECT_WALLET_ID, null], + [LS_KEY_RECONNECT_WALLET_ID, 'metaMask'], + ] as const)( + 'does not reconnect when %s becomes %s during the wait', + async (key, value) => { + save('com.okex.wallet', 'okx'); + await mountAndWait(); + mocks.items.set(key, value); + await announce(okxDetail); + expect(mocks.reconnect).not.toHaveBeenCalled(); + }, + ); + + it('does not reconnect while a manual connection is in progress', async () => { + save('com.okex.wallet', 'okx'); + await mountAndWait(); + mocks.state.status = 'connecting'; + await announce(okxDetail); + expect(mocks.reconnect).not.toHaveBeenCalled(); + }); + + it('does not wait for a wallet with an SDK connector', async () => { + // MetaMask has an rdns, but its connector does not read EIP-6963. + save('metaMask', 'metaMask'); + await mountAndWait(); + expect(mocks.reconnect).toHaveBeenCalledOnce(); + expect(mocks.listeners.size).toBe(0); + }); + }); +}); diff --git a/packages/reef-knot/src/core-react/hooks/__tests__/useDisconnect.test.tsx b/packages/reef-knot/src/core-react/hooks/__tests__/useDisconnect.test.tsx new file mode 100644 index 00000000..0514c898 --- /dev/null +++ b/packages/reef-knot/src/core-react/hooks/__tests__/useDisconnect.test.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, expect, it, vi } from 'vitest'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { http } from 'viem'; +import { mainnet } from 'viem/chains'; +import { WagmiProvider, createConfig, createStorage } from 'wagmi'; +import { connect } from 'wagmi/actions'; +import { mock } from 'wagmi/connectors'; +import { useDisconnect } from '../useDisconnect'; +import { LS_KEY_RECONNECT_WALLET_ID } from '../../constants'; + +vi.mock('../useReefKnotContext', () => ({ + useReefKnotContext: () => ({ walletDataList: [] }), +})); + +Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + +const items = new Map(); +const createTestConfig = () => + createConfig({ + chains: [mainnet], + connectors: [ + mock({ accounts: ['0x0000000000000000000000000000000000000001'] }), + mock({ accounts: ['0x0000000000000000000000000000000000000002'] }), + ], + transports: { [mainnet.id]: http() }, + storage: createStorage({ + storage: { + getItem: (key) => items.get(key) ?? null, + setItem: (key, value) => void items.set(key, value), + removeItem: (key) => void items.delete(key), + }, + }), + }); + +let root: Root; +let config: ReturnType; +let hook: ReturnType; + +function Probe() { + hook = useDisconnect(); + return null; +} + +beforeEach(async () => { + items.clear(); + config = createTestConfig(); + root = createRoot(document.createElement('div')); + await act(async () => + root.render( + + + + + , + ), + ); + // Wagmi keeps the first connection when the second wallet connects. + for (const connector of config.connectors) { + await act(async () => void (await connect(config, { connector }))); + } + await config.storage?.setItem(LS_KEY_RECONNECT_WALLET_ID, 'mock'); +}); + +afterEach(async () => { + await act(async () => root.unmount()); +}); + +const readSavedKeys = async () => [ + await config.storage?.getItem('recentConnectorId'), + await config.storage?.getItem(LS_KEY_RECONNECT_WALLET_ID), +]; + +it('disconnectAsync removes every retained connection', async () => { + expect(config.state.connections.size).toBe(2); + await act(async () => hook.disconnectAsync?.()); + expect(config.state.status).toBe('disconnected'); + expect(config.state.connections.size).toBe(0); + expect(await readSavedKeys()).toEqual([null, null]); +}); + +it('disconnect removes every retained connection', async () => { + expect(config.state.connections.size).toBe(2); + await act(async () => { + hook.disconnect?.(); + await vi.waitFor(async () => + expect(await readSavedKeys()).toEqual([null, null]), + ); + }); + expect(config.state.status).toBe('disconnected'); + expect(config.state.connections.size).toBe(0); +}); + +it('disconnects the other wallets when one fails, then reports the error', async () => { + const failure = new Error('Wallet did not respond'); + vi.spyOn(config.connectors[0], 'disconnect').mockRejectedValueOnce(failure); + await act(async () => expect(hook.disconnectAsync?.()).rejects.toBe(failure)); + const remaining = [...config.state.connections.values()]; + expect(remaining.map((c) => c.connector.uid)).toEqual([ + config.connectors[0].uid, + ]); + expect(await readSavedKeys()).toEqual([null, null]); +}); + +it('disconnect does not throw when a wallet fails to disconnect', async () => { + // A rejection with no value must still count as a failure. + vi.spyOn(config.connectors[0], 'disconnect').mockRejectedValueOnce(undefined); + await expect(hook.disconnectAsync?.()).rejects.toBeUndefined(); + + vi.spyOn(config.connectors[0], 'disconnect').mockRejectedValueOnce( + new Error('Wallet did not respond'), + ); + // Vitest fails the test on an unhandled rejection. + await act(async () => { + hook.disconnect?.(); + await vi.waitFor(async () => + expect(await readSavedKeys()).toEqual([null, null]), + ); + }); + expect(config.state.connections.size).toBe(1); +}); diff --git a/packages/core-react/src/hooks/index.ts b/packages/reef-knot/src/core-react/hooks/index.ts similarity index 89% rename from packages/core-react/src/hooks/index.ts rename to packages/reef-knot/src/core-react/hooks/index.ts index 91fc2b34..dc7a5377 100644 --- a/packages/core-react/src/hooks/index.ts +++ b/packages/reef-knot/src/core-react/hooks/index.ts @@ -5,5 +5,6 @@ export * from './useEagerConnect'; export * from './useDisconnect'; export * from './useConnectorInfo'; export * from './useConnect'; +export * from './useConnectionFlow'; export * from './useReefKnotModal'; export * from './useEIP6963Providers'; diff --git a/packages/reef-knot/src/core-react/hooks/useAutoConnect.ts b/packages/reef-knot/src/core-react/hooks/useAutoConnect.ts new file mode 100644 index 00000000..05b9ac3a --- /dev/null +++ b/packages/reef-knot/src/core-react/hooks/useAutoConnect.ts @@ -0,0 +1,127 @@ +import { useEffect } from 'react'; +import { useConfig, useConnection, useReconnect } from 'wagmi'; +import { injected } from 'wagmi/connectors'; +import type { WalletAdapterData } from '@reef-knot/wallets-helpers'; +import { useEagerConnect } from './useEagerConnect'; +import { checkTermsAccepted } from '../helpers/checkTermsAccepted'; +import { useReefKnotContext } from './useReefKnotContext'; +import { LS_KEY_RECONNECT_WALLET_ID } from '../constants'; +import { withCallback } from '../helpers/withCallback'; +import { providersStore, type EIP6963ProviderDetail } from '../eip6963'; + +// Some wallets may announce themselves late, for example after a cold browser start. +const PROVIDER_WAIT_TIMEOUT_MS = 1000; + +// Resolves with the announced wallet, or with `undefined` after the timeout. +const waitForProvider = (rdns: string) => + new Promise((resolve) => { + const find = (providers: readonly EIP6963ProviderDetail[]) => + providers.find((p) => p.info.rdns === rdns); + const found = find(providersStore.getProviders()); + if (found) { + resolve(found); + return; + } + let unsubscribe = () => {}; + const timer = setTimeout(() => { + unsubscribe(); + resolve(undefined); + }, PROVIDER_WAIT_TIMEOUT_MS); + unsubscribe = providersStore.subscribe((providers) => { + const detail = find(providers); + if (!detail) return; + clearTimeout(timer); + unsubscribe(); + resolve(detail); + }); + }); + +// Returns the rdns to wait for, if the wallet reads its provider from EIP-6963. +const getAnnouncedRdns = (walletId: string, walletData?: WalletAdapterData) => { + // Wallets outside `walletDataList` are saved by their rdns. + if (!walletData) return walletId; + // MetaMask and Coinbase also have an rdns, but their SDK connectors do not need an announcement. + return walletData.type === injected.type ? walletData.rdns : undefined; +}; + +export const useAutoConnect = (autoConnectEnabled: boolean) => { + const config = useConfig(); + const { mutateAsync: reconnectAsync } = useReconnect(); + const { isConnected } = useConnection(); + const { eagerConnect } = useEagerConnect(); + const { walletDataList, onReconnect } = useReefKnotContext(); + + useEffect(() => { + // Disconnect clears wagmi's key, so both keys must exist before reconnecting. + const readSavedWallet = async () => { + const [recentConnectorId, walletId] = await Promise.all([ + config.storage?.getItem('recentConnectorId'), + config.storage?.getItem(LS_KEY_RECONNECT_WALLET_ID), + ]); + if (!recentConnectorId || typeof walletId !== 'string' || !walletId) + return null; + return { walletId, recentConnectorId }; + }; + + const tryReconnect = async () => { + // Don't auto-connect if already connected or if the auto-connect feature is disabled + if (isConnected || !autoConnectEnabled) return; + + // Try to eagerly connect wallets that are meant to be used only with auto-connection. + // For example, wallets with dApp browsers, or using iframes to open dApps. + const connectResult = await eagerConnect(); + + // If still not connected and there were no errors and the terms of service are accepted, + // call the default wagmi autoConnect method, which attempts to connect to the last used connector. + if (!connectResult && checkTermsAccepted()) { + // Wait for all EIP-6963 wallets to load their code and fire "eip6963:announceProvider" event + // Without the delay, this code can be called from a browser's cache faster than wallet extension code + await new Promise((resolve) => setTimeout(resolve, 100)); + + // Read both keys after the delay, so a connection made meanwhile is not mixed with an older one. + const savedWallet = await readSavedWallet(); + if (!savedWallet) return; + + const walletData = walletDataList.find( + (data) => data.walletId === savedWallet.walletId, + ); + const rdns = getAnnouncedRdns(savedWallet.walletId, walletData); + const eip6963Provider = rdns ? await waitForProvider(rdns) : undefined; + + // A new connection may have started while we waited. + const currentWallet = await readSavedWallet(); + if ( + !currentWallet || + currentWallet.walletId !== savedWallet.walletId || + currentWallet.recentConnectorId !== savedWallet.recentConnectorId + ) + return; + // The keys change only after a manual connection succeeds. Do not overwrite one in progress. + if (config.state.status === 'connecting') return; + + const reconnectWithCallback = withCallback(reconnectAsync, onReconnect); + + if (walletData) { + // If the wallet did not announce itself, its connector has no provider and wagmi skips it. + await reconnectWithCallback({ + connectors: [walletData.createConnectorFn], + }); + } else if (eip6963Provider) { + const createConnectorFn = injected({ + target: { + id: eip6963Provider.info.rdns, + name: eip6963Provider.info.name, + provider: () => eip6963Provider.provider, + }, + }); + await reconnectWithCallback({ connectors: [createConnectorFn] }); + } + } + }; + + void tryReconnect(); + + // No hook deps: do not retry the auto-connect attemption. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); +}; diff --git a/packages/core-react/src/hooks/useAutoConnectCheck.ts b/packages/reef-knot/src/core-react/hooks/useAutoConnectCheck.ts similarity index 100% rename from packages/core-react/src/hooks/useAutoConnectCheck.ts rename to packages/reef-knot/src/core-react/hooks/useAutoConnectCheck.ts diff --git a/packages/reef-knot/src/core-react/hooks/useConnect.ts b/packages/reef-knot/src/core-react/hooks/useConnect.ts new file mode 100644 index 00000000..a9ed41cf --- /dev/null +++ b/packages/reef-knot/src/core-react/hooks/useConnect.ts @@ -0,0 +1,7 @@ +import { useConnectionFlow } from './useConnectionFlow'; + +/** @deprecated Use useConnectionFlow().startConnection() instead. */ +export const useConnect = () => { + const { startConnection } = useConnectionFlow(); + return { connect: startConnection }; +}; diff --git a/packages/core-react/src/hooks/useConnect.ts b/packages/reef-knot/src/core-react/hooks/useConnectionFlow.ts similarity index 70% rename from packages/core-react/src/hooks/useConnect.ts rename to packages/reef-knot/src/core-react/hooks/useConnectionFlow.ts index 077270ca..cd672b9d 100644 --- a/packages/core-react/src/hooks/useConnect.ts +++ b/packages/reef-knot/src/core-react/hooks/useConnectionFlow.ts @@ -3,18 +3,19 @@ import { useAutoConnectCheck } from './useAutoConnectCheck'; import { useEagerConnect } from './useEagerConnect'; import { useReefKnotModal } from './useReefKnotModal'; -export const useConnect = () => { +/** Starts eager connection or wallet selection and returns the outcome of that flow. */ +export const useConnectionFlow = () => { const { openModalAsync } = useReefKnotModal(); const { checkIfShouldAutoConnect } = useAutoConnectCheck(); const { eagerConnect } = useEagerConnect(); - const connect = useCallback(async () => { + const startConnection = useCallback(async () => { if (await checkIfShouldAutoConnect()) { const result = await eagerConnect(); - return { success: !!result }; + return { connected: !!result }; } else { return openModalAsync({ type: 'wallet' }); } }, [checkIfShouldAutoConnect, eagerConnect, openModalAsync]); - return { connect }; + return { startConnection }; }; diff --git a/packages/core-react/src/hooks/useConnectorInfo.ts b/packages/reef-knot/src/core-react/hooks/useConnectorInfo.ts similarity index 100% rename from packages/core-react/src/hooks/useConnectorInfo.ts rename to packages/reef-knot/src/core-react/hooks/useConnectorInfo.ts diff --git a/packages/reef-knot/src/core-react/hooks/useDisconnect.ts b/packages/reef-knot/src/core-react/hooks/useDisconnect.ts new file mode 100644 index 00000000..4c695794 --- /dev/null +++ b/packages/reef-knot/src/core-react/hooks/useDisconnect.ts @@ -0,0 +1,81 @@ +import { useCallback, useMemo } from 'react'; +import { + useConnection, + useConfig, + useDisconnect as useDisconnectWagmi, +} from 'wagmi'; +import { useReefKnotContext } from './useReefKnotContext'; +import { useReefKnotModal } from './useReefKnotModal'; +import { LS_KEY_RECONNECT_WALLET_ID } from '../constants'; + +const useDisconnectCleaningStorage = () => { + const config = useConfig(); + const { mutateAsync } = useDisconnectWagmi(); + + const disconnectAsync = useCallback(async () => { + // Wagmi keeps the old connection when another wallet connects. + // If we disconnect only the current one, wagmi makes the old one current again. + const connectors = [...config.state.connections.values()].map( + (connection) => connection.connector, + ); + const errors: unknown[] = []; + // One at a time: each wagmi disconnect changes the shared connections map. + for (const connector of connectors) { + // Keep going, so one failing wallet does not keep the others connected. + await mutateAsync({ connector }).catch((e: unknown) => errors.push(e)); + } + // Wagmi writes recentConnectorId while it finishes a disconnect. + // Clear the keys after that, and before a new connection saves its own keys. + // Clear them even if a wallet failed: the user asked to disconnect, + // so a page reload must not connect that wallet again. + await Promise.all([ + config.storage?.removeItem('recentConnectorId'), + config.storage?.removeItem(LS_KEY_RECONNECT_WALLET_ID), + ]); + if (errors.length) throw errors[0]; + }, [config, mutateAsync]); + + // For callers that don't wait. Like wagmi's mutate, it does not throw. + const disconnect = useCallback(() => { + disconnectAsync().catch(() => {}); + }, [disconnectAsync]); + + return { disconnect, disconnectAsync }; +}; + +export const useForceDisconnect = () => { + const { disconnect } = useDisconnectCleaningStorage(); + const { forceCloseAllModals } = useReefKnotModal(); + + const forceDisconnect = useCallback(() => { + forceCloseAllModals(); + disconnect(); + }, [disconnect, forceCloseAllModals]); + + return { forceDisconnect }; +}; + +export const useDisconnect = (): { + disconnect?: () => void; + disconnectAsync?: () => Promise; + isDisconnectMakesSense: boolean; +} => { + const { isConnected, connector } = useConnection(); + const { disconnect, disconnectAsync } = useDisconnectCleaningStorage(); + const { walletDataList } = useReefKnotContext(); + + const isDisconnectMakesSense = useMemo(() => { + // It doesn't make sense to offer a user the ability to disconnect if the user is not connected yet, + // or if the user was connected automatically + const connectorData = walletDataList.find( + (c) => c.walletId === connector?.id, + ); + return isConnected && !connectorData?.autoConnectOnly; + }, [isConnected, connector, walletDataList]); + + return { + disconnect: isDisconnectMakesSense ? disconnect : undefined, + disconnectAsync: isDisconnectMakesSense ? disconnectAsync : undefined, + isDisconnectMakesSense, + }; +}; diff --git a/packages/core-react/src/hooks/useEIP6963Providers.ts b/packages/reef-knot/src/core-react/hooks/useEIP6963Providers.ts similarity index 100% rename from packages/core-react/src/hooks/useEIP6963Providers.ts rename to packages/reef-knot/src/core-react/hooks/useEIP6963Providers.ts diff --git a/packages/core-react/src/hooks/useEagerConnect.ts b/packages/reef-knot/src/core-react/hooks/useEagerConnect.ts similarity index 94% rename from packages/core-react/src/hooks/useEagerConnect.ts rename to packages/reef-knot/src/core-react/hooks/useEagerConnect.ts index e253467c..c6056f5b 100644 --- a/packages/core-react/src/hooks/useEagerConnect.ts +++ b/packages/reef-knot/src/core-react/hooks/useEagerConnect.ts @@ -6,8 +6,9 @@ import { useReefKnotModal } from './useReefKnotModal'; import { connect } from 'wagmi/actions'; import { checkTermsAccepted } from '../helpers/checkTermsAccepted'; -import type { WalletAdapterData } from '@reef-knot/types'; -import type { Config, ConnectReturnType } from '@wagmi/core'; +import type { WalletAdapterData } from '../../types/index'; +import type { Config } from 'wagmi'; +import type { ConnectReturnType } from 'wagmi/actions'; import type { ReefKnotModalContextValue } from '../context/reefKnotModalContext'; type ConnectResult = ConnectReturnType; diff --git a/packages/core-react/src/hooks/useReefKnotContext.ts b/packages/reef-knot/src/core-react/hooks/useReefKnotContext.ts similarity index 53% rename from packages/core-react/src/hooks/useReefKnotContext.ts rename to packages/reef-knot/src/core-react/hooks/useReefKnotContext.ts index 1cef6e6d..4b945ab2 100644 --- a/packages/core-react/src/hooks/useReefKnotContext.ts +++ b/packages/reef-knot/src/core-react/hooks/useReefKnotContext.ts @@ -1,8 +1,6 @@ import { useContext } from 'react'; -import { - ReefKnotContext, - ReefKnotContextValue, -} from '../context/reefKnotContext'; +import { ReefKnotContext } from '../context/reefKnotContext'; +import { ReefKnotContextValue } from '../../types'; export const useReefKnotContext = (): ReefKnotContextValue => useContext(ReefKnotContext); diff --git a/packages/core-react/src/hooks/useReefKnotModal.ts b/packages/reef-knot/src/core-react/hooks/useReefKnotModal.ts similarity index 100% rename from packages/core-react/src/hooks/useReefKnotModal.ts rename to packages/reef-knot/src/core-react/hooks/useReefKnotModal.ts diff --git a/packages/core-react/src/index.ts b/packages/reef-knot/src/core-react/index.ts similarity index 77% rename from packages/core-react/src/index.ts rename to packages/reef-knot/src/core-react/index.ts index f52dbd9a..ecae5884 100644 --- a/packages/core-react/src/index.ts +++ b/packages/reef-knot/src/core-react/index.ts @@ -5,5 +5,11 @@ export * from './context/reefKnotContext'; export * from './context/reefKnotProvider'; export { ReefKnotModalContextProvider } from './context/reefKnotModalContext'; export type { ReefKnotModalContextValue } from './context/reefKnotModalContext'; +export type { + ModalTypes, + ModalResult, + ModalStateEntry, + RequirementsData, +} from './context/reefKnotModalContext'; export { providersStore } from './eip6963'; export type { EIP6963ProviderDetail } from './eip6963'; diff --git a/packages/reef-knot/src/headless/__tests__/connection-flow.test.tsx b/packages/reef-knot/src/headless/__tests__/connection-flow.test.tsx new file mode 100644 index 00000000..695fdc97 --- /dev/null +++ b/packages/reef-knot/src/headless/__tests__/connection-flow.test.tsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, expect, it, vi } from 'vitest'; +import { ReefKnotModalContextProvider } from '../../core-react/context/reefKnotModalContext'; +import { useReefKnotModal } from '../../core-react/hooks/useReefKnotModal'; +import { useConnectionFlow } from '../../core-react/hooks/useConnectionFlow'; +import { useConnect } from '../../core-react/hooks/useConnect'; + +const mocks = vi.hoisted(() => ({ check: vi.fn(), eager: vi.fn() })); +vi.mock('../../core-react/hooks/useAutoConnectCheck', () => ({ + useAutoConnectCheck: () => ({ checkIfShouldAutoConnect: mocks.check }), +})); +vi.mock('../../core-react/hooks/useEagerConnect', () => ({ + useEagerConnect: () => ({ eagerConnect: mocks.eager }), +})); + +let root: Root; +let container: HTMLDivElement; +let flow: ReturnType; +let legacy: ReturnType; +let modal: ReturnType; +function Probe() { + flow = useConnectionFlow(); + legacy = useConnect(); + modal = useReefKnotModal(); + return null; +} + +beforeEach(async () => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + vi.resetAllMocks(); + localStorage.clear(); + mocks.check.mockResolvedValue(false); + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); + await act(async () => + root.render( + + + , + ), + ); +}); +afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); +}); + +it.each([true, false])( + 'waits for the picker result (connected=%s)', + async (connected) => { + let result!: ReturnType; + const settled = vi.fn(); + await act(async () => { + result = flow.startConnection(); + void result.then(settled); + }); + expect(modal.currentModal?.type).toBe('wallet'); + expect(settled).not.toHaveBeenCalled(); + expect(mocks.eager).not.toHaveBeenCalled(); + + await act(async () => modal.closeModal({ connected })); + await expect(result).resolves.toEqual({ connected }); + expect(settled).toHaveBeenCalledExactlyOnceWith({ connected }); + }, +); + +it.each([true, false])( + 'returns the eager outcome without opening a picker (connected=%s)', + async (connected) => { + mocks.check.mockResolvedValue(true); + mocks.eager.mockResolvedValue(connected); + await expect(flow.startConnection()).resolves.toEqual({ connected }); + expect(mocks.eager).toHaveBeenCalledOnce(); + expect(modal.currentModal).toBeUndefined(); + }, +); + +it('preserves errors from eager connection', async () => { + mocks.check.mockResolvedValue(true); + const error = new Error('Eager connection failed'); + mocks.eager.mockRejectedValue(error); + await expect(flow.startConnection()).rejects.toBe(error); + expect(modal.currentModal).toBeUndefined(); +}); + +it('keeps the deprecated connect callback compatible with the picker flow', async () => { + let result!: ReturnType; + await act(async () => { + result = legacy.connect(); + }); + expect(modal.currentModal?.type).toBe('wallet'); + await act(async () => modal.goBack()); + await expect(result).resolves.toEqual({ connected: false }); +}); diff --git a/packages/reef-knot/src/headless/__tests__/connection.test.tsx b/packages/reef-knot/src/headless/__tests__/connection.test.tsx new file mode 100644 index 00000000..3f80b522 --- /dev/null +++ b/packages/reef-knot/src/headless/__tests__/connection.test.tsx @@ -0,0 +1,1056 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { UserRejectedRequestError } from 'viem'; +import { mainnet } from 'viem/chains'; +import type { CreateConnectorFn } from 'wagmi'; +import { + LS_KEY_DERIVATION_PATH, + idLedgerHid, + ledgerHIDConnector, +} from '@reef-knot/ledger-connector'; +import { ReefKnotProvider } from '../../core-react/context/reefKnotProvider'; +import { useReefKnotModal } from '../../core-react/hooks/useReefKnotModal'; +import { + LS_KEY_RECONNECT_WALLET_ID, + LS_KEY_TERMS_ACCEPTANCE, +} from '../../core-react/constants'; +import { + ReefKnotUIProvider, + useWalletConnection, + useWalletPicker, + useTerms, + useEIP6963Picker, +} from '../connection'; +import { useEagerConnectScreen } from '../eager'; +import { ReefKnotLedgerProvider, useLedgerFlow } from '../ledger/flow'; +import type { WalletAdapterData } from '@reef-knot/wallets-helpers'; +import type { ReefKnotWalletsModalConfig } from '../../types/reef-knot-wallets-modal'; + +type TestConnector = { + id: string; + uid: string; + disconnect?: () => Promise; +}; + +const mocks = vi.hoisted(() => ({ + connect: vi.fn<(...args: unknown[]) => Promise>(), + setItem: vi.fn(), + removeItem: vi.fn(), + disconnect: vi.fn<(args: { connector: TestConnector }) => Promise>(), + acquire: vi.fn(), + closeTransport: vi.fn(), + ledgerRead: vi.fn<(path: string) => Promise<{ address: string }>>(), + skipCommit: false, + // One fake address per account index, so a wrong path gives a wrong address. + ledgerAddress: (path: string) => + `0x${(parseInt(path.split('/')[3], 10) + 1).toString(16).padStart(40, '0')}`, + state: { + status: 'disconnected', + current: null as string | null, + connections: new Map(), + }, +})); +// Keep one config object: the Ledger account loader reloads when it changes. +const wagmiConfig = vi.hoisted(() => ({})); +vi.mock('wagmi', async (importOriginal) => ({ + ...(await importOriginal()), + useConfig: () => + Object.assign(wagmiConfig, { + chains: [mainnet], + storage: { setItem: mocks.setItem, removeItem: mocks.removeItem }, + state: mocks.state, + }), + useConnect: () => ({ + mutateAsync: async ({ connector }: { connector: CreateConnectorFn }) => { + const uid = `selected-${mocks.connect.mock.calls.length}`; + const instance = connector({ + emitter: { uid }, + chains: [mainnet], + providers: [], + } as unknown as Parameters[0]); + const result = await mocks.connect({ connector }); + if (!mocks.skipCommit) { + mocks.state.status = 'connected'; + mocks.state.current = uid; + mocks.state.connections.set(uid, { + connector: { + id: instance.id ?? 'metaMask', + uid, + ...(instance.disconnect ? { disconnect: instance.disconnect } : {}), + }, + }); + } + return result; + }, + }), + useConnection: () => ({ + isConnected: mocks.state.status === 'connected', + connector: mocks.state.connections.get(mocks.state.current ?? '') + ?.connector, + }), + useDisconnect: () => ({ + mutate: mocks.disconnect, + mutateAsync: mocks.disconnect, + }), +})); + +vi.mock('../ledger/helpers', async (original) => ({ + ...(await original()), + getTransport: mocks.acquire, + isHIDSupported: () => true, +})); +vi.mock('@ledgerhq/hw-app-eth', () => ({ + default: class { + getAppConfiguration = async () => ({}); + getAddress = mocks.ledgerRead; + }, +})); +vi.mock('wagmi/actions', async (importOriginal) => ({ + ...(await importOriginal()), + getBalance: async () => ({ value: 0n, symbol: 'ETH' }), +})); + +const wallet: WalletAdapterData = { + walletId: 'metaMask', + walletName: 'MetaMask', + type: 'injected', + detector: vi.fn(async () => true), + createConnectorFn: + (() => ({})) as unknown as WalletAdapterData['createConnectorFn'], +}; +const browserWallet: WalletAdapterData = { + ...wallet, + walletId: 'browserExtension', + walletName: 'Browser wallet', +}; +const ledgerWallet: WalletAdapterData = { + ...wallet, + walletId: idLedgerHid, + walletName: 'Ledger', + createConnectorFn: ledgerHIDConnector({ rpc: {}, defaultChain: mainnet }), +}; +let root: Root; +let container: HTMLDivElement; +let modal: ReturnType; +let connection: ReturnType; +let picker: ReturnType; +let terms: ReturnType; +let eager: ReturnType; +let providers: ReturnType; +let ledger: ReturnType; + +function Probe({ walletId }: { walletId: string }) { + modal = useReefKnotModal(); + connection = useWalletConnection(walletId); + picker = useWalletPicker(); + terms = useTerms(); + eager = useEagerConnectScreen(); + providers = useEIP6963Picker(); + return null; +} +function LedgerProbe() { + ledger = useLedgerFlow(); + return null; +} +function LedgerSession() { + const { currentModal } = useReefKnotModal(); + return currentModal?.type === 'ledger' ? ( + + + + ) : null; +} +async function mount( + overrides: Partial = {}, + walletId = 'metaMask', + extra?: React.ReactNode, +) { + const config: ReefKnotWalletsModalConfig = { + walletsShown: ['metaMask', 'browserExtension'], + walletsPinned: [], + ...overrides, + }; + await act(async () => { + root.render( + + + + {extra} + + , + ); + }); + await act(async () => { + modal.openModal({ type: 'wallet' }); + }); +} +beforeEach(() => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + vi.clearAllMocks(); + mocks.connect.mockResolvedValue({}); + mocks.disconnect.mockResolvedValue(undefined); + mocks.closeTransport.mockReset().mockResolvedValue(undefined); + mocks.acquire.mockReset().mockResolvedValue({ close: mocks.closeTransport }); + mocks.ledgerRead.mockReset().mockImplementation(async (path) => ({ + address: mocks.ledgerAddress(path), + })); + mocks.skipCommit = false; + mocks.state.status = 'disconnected'; + mocks.state.current = null; + mocks.state.connections.clear(); + localStorage.clear(); + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); +}); +afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); +}); + +describe('public headless connection flow', () => { + it('waits for the old wallet disconnect and storage cleanup before connecting its replacement', async () => { + mocks.state.status = 'connected'; + mocks.state.current = 'old'; + mocks.state.connections.set('old', { + connector: { id: 'old-wallet', uid: 'old' }, + }); + let finishDisconnect!: () => void; + mocks.disconnect.mockImplementationOnce( + () => + new Promise((resolve) => { + finishDisconnect = () => { + mocks.state.status = 'disconnected'; + mocks.state.current = null; + mocks.state.connections.clear(); + resolve(); + }; + }), + ); + let finishCleanup!: () => void; + mocks.removeItem.mockImplementationOnce( + () => + new Promise((resolve) => { + finishCleanup = resolve; + }), + ); + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + let pending!: Promise; + await act(async () => { + pending = connection.connect(); + }); + expect(mocks.disconnect).toHaveBeenCalledOnce(); + expect(mocks.connect).not.toHaveBeenCalled(); + expect(connection.isLoading).toBe(true); + expect(success).not.toHaveBeenCalled(); + + await act(async () => finishDisconnect()); + expect(mocks.removeItem).toHaveBeenCalledWith('recentConnectorId'); + expect(mocks.removeItem).toHaveBeenCalledWith(LS_KEY_RECONNECT_WALLET_ID); + expect(mocks.connect).not.toHaveBeenCalled(); + await act(async () => { + finishCleanup(); + await pending; + }); + expect(mocks.state.status).toBe('connected'); + expect(mocks.state.current).toBe('selected-0'); + expect(mocks.connect).toHaveBeenCalledOnce(); + expect(success).toHaveBeenCalledExactlyOnceWith({ + walletId: 'metaMask', + rdns: undefined, + }); + expect(mocks.setItem).toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + 'metaMask', + ); + expect(modal.currentModal).toBeUndefined(); + }); + it('does not start a replacement connection if disconnect fails', async () => { + mocks.state.status = 'connected'; + mocks.state.current = 'old'; + mocks.state.connections.set('old', { + connector: { id: 'old-wallet', uid: 'old' }, + }); + mocks.disconnect.mockRejectedValueOnce(new Error('Disconnect failed')); + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error?.message).toBe('Disconnect failed'); + expect(mocks.connect).not.toHaveBeenCalled(); + expect(mocks.setItem).not.toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); + expect(modal.currentModal?.type).toBe('wallet'); + }); + it.each(['disconnected', 'another-instance'])( + 'does not commit success when the selected connector is %s', + async (outcome) => { + mocks.skipCommit = true; + if (outcome === 'another-instance') { + mocks.connect.mockImplementationOnce(async () => { + mocks.state.status = 'connected'; + mocks.state.current = 'other'; + // Same wallet id, different connector instance. + mocks.state.connections.set('other', { + connector: { id: 'metaMask', uid: 'other' }, + }); + }); + } + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error?.message).toBe( + 'The selected wallet is no longer connected. Please retry.', + ); + expect(connection.errorMessage).toBe(connection.error?.message); + expect(mocks.setItem).not.toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); + expect(modal.currentModal?.type).toBe('wallet'); + expect(connection.isLoading).toBe(false); + }, + ); + it('guards Terms in the action, then stores reconnect and calls success once', async () => { + const success = vi.fn(); + const start = vi.fn(); + const accepted = vi.fn(); + await mount({ + onConnectSuccess: success, + onConnectStart: start, + onClickTermsAccept: accepted, + }); + await act(async () => { + await connection.connect(); + }); + expect(mocks.connect).not.toHaveBeenCalled(); + await act(async () => terms.setChecked(true)); + expect(JSON.parse(localStorage.getItem(LS_KEY_TERMS_ACCEPTANCE)!)).toBe( + true, + ); + expect(accepted).toHaveBeenCalledOnce(); + await act(async () => { + await connection.connect(); + }); + expect(mocks.connect).toHaveBeenCalledOnce(); + expect(start).toHaveBeenCalledOnce(); + expect(success).toHaveBeenCalledExactlyOnceWith({ + walletId: 'metaMask', + rdns: undefined, + }); + expect(mocks.setItem).toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + 'metaMask', + ); + expect(modal.currentModal).toBeUndefined(); + }); + it('reports success only after the wallet id is stored', async () => { + let finishWrite!: () => void; + mocks.setItem.mockImplementationOnce( + () => + new Promise((resolve) => { + finishWrite = resolve; + }), + ); + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + let pending!: Promise; + await act(async () => { + pending = connection.connect(); + }); + expect(mocks.setItem).toHaveBeenCalledOnce(); + expect(success).not.toHaveBeenCalled(); + expect(modal.currentModal?.type).toBe('wallet'); + expect(connection.isLoading).toBe(true); + + await act(async () => { + finishWrite(); + await pending; + }); + expect(success).toHaveBeenCalledOnce(); + expect(modal.currentModal).toBeUndefined(); + expect(connection.isLoading).toBe(false); + }); + it('completes the connection when the wallet id cannot be stored', async () => { + mocks.setItem.mockRejectedValueOnce(new Error('Quota exceeded')); + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error).toBeNull(); + expect(success).toHaveBeenCalledOnce(); + expect(modal.currentModal).toBeUndefined(); + }); + it('shares loading and blocks concurrent requests from several hook consumers', async () => { + let finish!: () => void; + mocks.connect.mockImplementation( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + await mount(); + await act(async () => terms.setChecked(true)); + let pending!: Promise; + await act(async () => { + pending = connection.connect(); + await connection.connect(); + }); + expect(connection.isLoading).toBe(true); + expect(connection.disabled).toBe(true); + expect(mocks.connect).toHaveBeenCalledOnce(); + await act(async () => { + finish(); + await pending; + }); + expect(connection.isLoading).toBe(false); + }); + it('keeps the picker open on rejection and permits retry', async () => { + const success = vi.fn(); + mocks.connect.mockRejectedValueOnce(new Error('Rejected')); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error?.message).toBe('Rejected'); + // The UI must not show the text of an unknown error. + expect(connection.errorMessage).toBe('Connection error. Please try again.'); + expect(connection.isLoading).toBe(false); + expect(modal.currentModal?.type).toBe('wallet'); + expect(success).not.toHaveBeenCalled(); + await act(async () => { + await connection.connect(); + }); + expect(success).toHaveBeenCalledOnce(); + }); + it('shows no error when the user rejects the request in the wallet', async () => { + mocks.connect.mockRejectedValueOnce( + new UserRejectedRequestError(new Error('User rejected the request.')), + ); + await mount(); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error).toBeNull(); + expect(connection.isLoading).toBe(false); + expect(modal.currentModal?.type).toBe('wallet'); + }); + it('does not show a message from a wallet error that is not an Error', async () => { + mocks.connect.mockRejectedValueOnce({ reason: 'unknown' }); + await mount(); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(connection.error).toBeInstanceOf(Error); + expect(connection.error?.message).not.toContain('[object'); + }); + it.each([false, true])( + 'ignores a late rejection after closing the picker (reopen before rejection: %s)', + async (reopenBeforeRejection) => { + let rejectConnection!: (error: Error) => void; + mocks.connect.mockImplementationOnce( + () => + new Promise((_resolve, reject) => { + rejectConnection = reject; + }), + ); + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + let pending!: Promise; + await act(async () => { + pending = connection.connect(); + }); + expect(connection.isLoading).toBe(true); + await act(async () => modal.goBack()); + if (reopenBeforeRejection) + await act(async () => modal.openModal({ type: 'wallet' })); + + await act(async () => { + rejectConnection(new Error('Late rejection')); + await pending; + }); + expect(connection.error).toBeNull(); + expect(connection.isLoading).toBe(false); + expect(success).not.toHaveBeenCalled(); + expect(mocks.setItem).not.toHaveBeenCalled(); + + if (!reopenBeforeRejection) + await act(async () => modal.openModal({ type: 'wallet' })); + expect(modal.currentModal?.type).toBe('wallet'); + expect(picker.error).toBeNull(); + expect(connection.disabled).toBe(false); + await act(async () => connection.connect()); + expect(success).toHaveBeenCalledOnce(); + expect(mocks.connect).toHaveBeenCalledTimes(2); + }, + ); + it('ignores a late EIP-6963 rejection after returning to the underlying picker', async () => { + let rejectConnection!: (error: Error) => void; + const onSelect = vi.fn( + () => + new Promise((_resolve, reject) => { + rejectConnection = reject; + }), + ); + await mount(); + await act(async () => terms.setChecked(true)); + const provider = { + info: { + uuid: 'test-id', + name: 'Test wallet', + rdns: 'org.test.wallet', + icon: 'data:image/png;base64,AA' as const, + }, + provider: { request: vi.fn(), on: vi.fn(), removeListener: vi.fn() }, + }; + await act(async () => + modal.openModal({ + type: 'eip6963', + props: { providers: [provider], onSelect }, + }), + ); + let pending!: Promise; + await act(async () => { + pending = providers.select(provider); + }); + await act(async () => modal.goBack()); + await act(async () => { + rejectConnection(new Error('Late provider rejection')); + await pending; + }); + expect(modal.currentModal?.type).toBe('wallet'); + expect(picker.error).toBeNull(); + expect(connection.disabled).toBe(false); + expect(mocks.setItem).not.toHaveBeenCalled(); + }); + it('shares search, expansion and callbacks without rerunning discovery per consumer', async () => { + const more = vi.fn(); + const less = vi.fn(); + await mount({ + walletsDisplayInitialCount: 1, + onClickWalletsMore: more, + onClickWalletsLess: less, + }); + expect(picker.wallets).toHaveLength(1); + await act(async () => picker.toggleExpanded()); + expect(picker.wallets).toHaveLength(2); + expect(more).toHaveBeenCalledOnce(); + await act(async () => picker.setSearch('MASK')); + expect(picker.wallets.map((w) => w.walletId)).toEqual(['metaMask']); + await act(async () => picker.toggleExpanded()); + expect(picker.search).toBe(''); + expect(less).toHaveBeenCalledOnce(); + }); + it('eager connect guards consent, exposes errors, and retries', async () => { + const tryConnection = vi + .fn() + .mockRejectedValueOnce(new Error('Try again')) + .mockResolvedValueOnce({}); + await mount(); + await act(async () => + modal.openModal({ type: 'eager', props: { tryConnection } }), + ); + await act(async () => { + await eager.connect(); + }); + expect(tryConnection).not.toHaveBeenCalled(); + await act(async () => terms.setChecked(true)); + await act(async () => { + await eager.connect(); + }); + expect(eager.errorMessage).toBe('Connection error. Please try again.'); + expect(modal.currentModal?.type).toBe('eager'); + await act(async () => { + await eager.connect(); + }); + expect(modal.currentModal?.type).toBe('wallet'); + }); + it('completes EIP-6963 and the underlying picker once and persists rdns', async () => { + const success = vi.fn(); + await mount({ onConnectSuccess: success }); + await act(async () => terms.setChecked(true)); + const provider = { + info: { + uuid: 'test-id', + name: 'Test wallet', + rdns: 'org.test.wallet', + icon: 'data:image/png;base64,AA' as const, + }, + provider: { request: vi.fn(), on: vi.fn(), removeListener: vi.fn() }, + }; + await act(async () => + modal.openModal({ + type: 'eip6963', + props: { + providers: [provider], + onSelect: () => { + mocks.state.status = 'connected'; + mocks.state.current = 'eip6963'; + mocks.state.connections.set('eip6963', { + connector: { id: provider.info.rdns, uid: 'eip6963' }, + }); + }, + }, + }), + ); + await act(async () => { + await providers.select(provider); + }); + expect(modal.modalStack).toHaveLength(0); + expect(success).toHaveBeenCalledExactlyOnceWith({ + walletId: 'browserExtension', + rdns: 'org.test.wallet', + }); + expect(mocks.setItem).toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + 'org.test.wallet', + ); + }); + it('shows requirements when no browser provider exists', async () => { + await mount({}, 'browserExtension'); + await act(async () => terms.setChecked(true)); + await act(async () => { + await connection.connect(); + }); + expect(modal.currentModal?.type).toBe('requirements'); + expect(mocks.connect).not.toHaveBeenCalled(); + }); + it('does not close a newly opened screen when an older connect resolves', async () => { + let finish!: () => void; + mocks.connect.mockImplementation( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + await mount(); + await act(async () => terms.setChecked(true)); + let pending!: Promise; + await act(async () => { + pending = connection.connect(); + }); + await act(async () => { + modal.goBack(); + modal.openModal({ + type: 'requirements', + props: { title: 'Other screen' }, + }); + }); + await act(async () => { + finish(); + await pending; + }); + expect(modal.currentModal?.type).toBe('requirements'); + }); + it('resolves cancelled modal promises as not connected', async () => { + await mount(); + let result!: Promise<{ connected: boolean }>; + await act(async () => { + result = modal.openModalAsync({ type: 'ledger' }); + }); + await act(async () => modal.forceCloseAllModals()); + expect(await result).toEqual({ connected: false }); + }); + it('goes back only from the top screen', async () => { + await mount(); + let walletResult!: Promise<{ connected: boolean }>; + let ledgerResult!: Promise<{ connected: boolean }>; + const walletSettled = vi.fn(); + await act(async () => { + walletResult = modal.openModalAsync({ type: 'wallet' }); + void walletResult.then(walletSettled); + ledgerResult = modal.openModalAsync({ type: 'ledger' }); + }); + await act(async () => modal.goBack()); + expect(await ledgerResult).toEqual({ connected: false }); + expect(modal.currentModal?.type).toBe('wallet'); + expect(walletSettled).not.toHaveBeenCalled(); + await act(async () => modal.forceCloseAllModals()); + expect(await walletResult).toEqual({ connected: false }); + }); + describe('replacing a connected Ledger', () => { + const DEFAULT_PATH = "m/44'/60'/0'/0/0"; + const SELECTED_PATH = "m/44'/60'/1'/0/0"; + beforeEach(() => { + // A real connector, so its disconnect really deletes the saved path. + const oldLedger = Object.assign( + ledgerHIDConnector({ rpc: {}, defaultChain: mainnet })({ + chains: [mainnet], + emitter: { emit: vi.fn() }, + } as never), + { uid: 'old' }, + ); + mocks.state.status = 'connected'; + mocks.state.current = 'old'; + mocks.state.connections.set('old', { connector: oldLedger }); + localStorage.setItem( + LS_KEY_DERIVATION_PATH, + JSON.stringify(DEFAULT_PATH), + ); + mocks.disconnect.mockImplementation( + async ({ + connector, + }: { + connector: { uid: string; disconnect?: () => Promise }; + }) => { + await connector.disconnect?.(); + mocks.state.connections.delete(connector.uid); + if (mocks.state.current === connector.uid) { + mocks.state.status = 'disconnected'; + mocks.state.current = null; + } + }, + ); + }); + async function mountLedger(success: () => void) { + await mount({ onConnectSuccess: success }, 'metaMask', ); + await act(async () => terms.setChecked(true)); + await act(async () => { + modal.openModal({ type: 'ledger' }); + }); + expect(ledger.screen).toBe('accounts'); + expect(ledger.accounts).toHaveLength(5); + const selected = ledger.accounts[1]; + expect(selected.path).toBe(SELECTED_PATH); + return selected; + } + + it('connects the selected account after the old Ledger clears its path', async () => { + // Like the real provider, read the path when the device connects. + mocks.connect.mockImplementation(async () => ({ + accounts: [ + mocks.ledgerAddress( + localStorage.getItem(LS_KEY_DERIVATION_PATH) ?? DEFAULT_PATH, + ), + ], + chainId: mainnet.id, + })); + const success = vi.fn(); + const selected = await mountLedger(success); + await act(async () => ledger.selectAccount(selected)); + expect(mocks.disconnect).toHaveBeenCalledOnce(); + expect(mocks.connect).toHaveBeenCalledOnce(); + await expect(mocks.connect.mock.results[0].value).resolves.toMatchObject({ + accounts: [selected.address], + }); + expect(JSON.parse(localStorage.getItem(LS_KEY_DERIVATION_PATH)!)).toBe( + SELECTED_PATH, + ); + expect(ledger.error).toBeNull(); + expect(success).toHaveBeenCalledExactlyOnceWith({ + walletId: idLedgerHid, + rdns: undefined, + }); + }); + + it('reloads accounts from the current Ledger and waits for a new selection after a mismatch', async () => { + mocks.connect.mockResolvedValue({ + accounts: [mocks.ledgerAddress(DEFAULT_PATH)], + chainId: mainnet.id, + }); + const success = vi.fn(); + const selected = await mountLedger(success); + const nextDeviceAddress = (path: string) => + mocks.ledgerAddress(path).replace('0x0000', '0xab00'); + mocks.ledgerRead.mockImplementation(async (path) => ({ + address: nextDeviceAddress(path), + })); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.error).toBeNull(); + expect(ledger.screen).toBe('accounts'); + expect(ledger.accounts).toHaveLength(5); + expect(ledger.accounts[1].address).toBe(nextDeviceAddress(SELECTED_PATH)); + expect(ledger.accounts).not.toContainEqual(selected); + expect(terms.checked).toBe(true); + expect(modal.currentModal?.type).toBe('ledger'); + expect(success).not.toHaveBeenCalled(); + expect(mocks.disconnect).toHaveBeenCalledTimes(2); + expect(mocks.disconnect.mock.lastCall?.[0].connector).toMatchObject({ + id: idLedgerHid, + uid: 'selected-0', + }); + expect(mocks.state.connections.size).toBe(0); + expect(mocks.setItem).not.toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + expect.anything(), + ); + expect(mocks.removeItem).toHaveBeenLastCalledWith('recentConnectorId'); + expect(localStorage.getItem(LS_KEY_DERIVATION_PATH)).toBeNull(); + expect(mocks.acquire).toHaveBeenCalledTimes(2); + + const nextSelected = ledger.accounts[1]; + mocks.connect.mockResolvedValue({ + accounts: [nextSelected.address], + chainId: mainnet.id, + }); + await act(async () => ledger.selectAccount(nextSelected)); + expect(success).toHaveBeenCalledExactlyOnceWith({ + walletId: idLedgerHid, + rdns: undefined, + }); + expect(mocks.setItem).toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + idLedgerHid, + ); + expect(modal.currentModal).toBeUndefined(); + }); + + it('reloads account selection after a normal retry', async () => { + const success = vi.fn(); + await mountLedger(success); + await act(async () => ledger.retry()); + expect(ledger.screen).toBe('accounts'); + expect(ledger.accounts).toHaveLength(5); + expect(ledger.error).toBeNull(); + expect(success).not.toHaveBeenCalled(); + }); + + it('waits for disconnect cleanup before saving the selected path', async () => { + const success = vi.fn(); + const selected = await mountLedger(success); + const disconnect = mocks.disconnect.getMockImplementation()!; + let finishDisconnect!: () => Promise; + mocks.disconnect.mockImplementationOnce( + (args) => + new Promise((resolve) => { + finishDisconnect = async () => { + await disconnect(args); + resolve(); + }; + }), + ); + mocks.connect.mockResolvedValue({ + accounts: [selected.address], + chainId: mainnet.id, + }); + let selection!: Promise; + await act(async () => { + selection = ledger.selectAccount(selected); + }); + expect(JSON.parse(localStorage.getItem(LS_KEY_DERIVATION_PATH)!)).toBe( + DEFAULT_PATH, + ); + expect(mocks.connect).not.toHaveBeenCalled(); + await act(async () => { + await finishDisconnect(); + await selection; + }); + expect(JSON.parse(localStorage.getItem(LS_KEY_DERIVATION_PATH)!)).toBe( + SELECTED_PATH, + ); + expect(success).toHaveBeenCalledOnce(); + }); + + it('does not save the selection or connect if the old wallet cannot disconnect', async () => { + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.disconnect.mockRejectedValueOnce(new Error('Disconnect failed')); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.screen).toBe('error'); + expect(ledger.error?.message).toBe('Disconnect failed'); + expect(ledger.errorMessage).toBe('Connection error. Please try again.'); + expect(mocks.connect).not.toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); + expect(JSON.parse(localStorage.getItem(LS_KEY_DERIVATION_PATH)!)).toBe( + DEFAULT_PATH, + ); + }); + + it('shows an error instead of recovering if the incorrect connection cannot disconnect', async () => { + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.connect.mockResolvedValue({ + accounts: [mocks.ledgerAddress(DEFAULT_PATH)], + chainId: mainnet.id, + }); + mocks.disconnect + .mockImplementationOnce(mocks.disconnect.getMockImplementation()!) + .mockRejectedValueOnce(new Error('Cleanup failed')); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.screen).toBe('error'); + expect(ledger.error?.message).toBe('Cleanup failed'); + expect(mocks.acquire).toHaveBeenCalledOnce(); + expect(success).not.toHaveBeenCalled(); + expect(mocks.setItem).not.toHaveBeenCalledWith( + LS_KEY_RECONNECT_WALLET_ID, + expect.anything(), + ); + expect(mocks.removeItem).toHaveBeenLastCalledWith('recentConnectorId'); + }); + + it.each([ + { accounts: [] }, + { accounts: ['invalid-address'] }, + { accounts: undefined }, + ])( + 'reloads selection when Ledger returns missing or invalid accounts: $accounts', + async ({ accounts }) => { + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.connect.mockResolvedValue({ accounts, chainId: mainnet.id }); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.error).toBeNull(); + expect(ledger.accounts).toHaveLength(5); + expect(mocks.acquire).toHaveBeenCalledTimes(2); + expect(mocks.state.connections.size).toBe(0); + expect(success).not.toHaveBeenCalled(); + }, + ); + + it('disconnects a mismatched account even without a previous wallet connection', async () => { + mocks.state.status = 'disconnected'; + mocks.state.current = null; + mocks.state.connections.clear(); + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.connect.mockResolvedValue({ + accounts: [mocks.ledgerAddress(DEFAULT_PATH)], + chainId: mainnet.id, + }); + await act(async () => ledger.selectAccount(selected)); + expect(mocks.disconnect).toHaveBeenCalledOnce(); + expect(mocks.state.connections.size).toBe(0); + expect(ledger.error).toBeNull(); + expect(mocks.acquire).toHaveBeenCalledTimes(2); + expect(success).not.toHaveBeenCalled(); + }); + + it('compares the selected address without regard to checksum casing', async () => { + const success = vi.fn(); + await mountLedger(success); + await act(async () => ledger.setPage(3)); + const selected = ledger.accounts[1]; + const address = selected.address.toUpperCase().replace('0X', '0x'); + expect(address).not.toBe(selected.address); + mocks.connect.mockResolvedValue({ + accounts: [address], + chainId: mainnet.id, + }); + await act(async () => ledger.selectAccount(selected)); + expect(success).toHaveBeenCalledOnce(); + expect(mocks.acquire).toHaveBeenCalledOnce(); + }); + + it('preserves the path template, resets pagination and hides old accounts while reloading', async () => { + const success = vi.fn(); + await mountLedger(success); + const template = ledger.derivationPaths[1].template; + await act(async () => ledger.setDerivationPath(template)); + await act(async () => ledger.setPage(2)); + const selected = ledger.accounts[1]; + let finishRead!: (result: { address: string }) => void; + mocks.ledgerRead.mockImplementationOnce( + () => + new Promise((resolve) => { + finishRead = resolve; + }), + ); + mocks.connect.mockResolvedValue({ + accounts: ['0x00000000000000000000000000000000000000aa'], + chainId: mainnet.id, + }); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.derivationPath).toBe(template); + expect(ledger.currentPage).toBe(1); + expect(ledger.accounts).toEqual([]); + expect(ledger.isLoading).toBe(true); + expect(success).not.toHaveBeenCalled(); + await act(async () => + finishRead({ address: mocks.ledgerAddress(DEFAULT_PATH) }), + ); + expect(ledger.accounts).toHaveLength(5); + expect(ledger.accounts[0].path).toBe(template.replace('x', '0')); + expect(ledger.isLoading).toBe(false); + }); + + it('can retry if reading the refreshed device accounts fails', async () => { + const consoleError = vi + .spyOn(console, 'error') + .mockImplementation(() => {}); + try { + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.connect.mockResolvedValue({ + accounts: [mocks.ledgerAddress(DEFAULT_PATH)], + chainId: mainnet.id, + }); + mocks.ledgerRead.mockRejectedValueOnce(new Error('Device unavailable')); + await act(async () => ledger.selectAccount(selected)); + expect(ledger.screen).toBe('error'); + expect(ledger.error?.message).toContain('loading accounts'); + expect(ledger.errorMessage).toContain('loading accounts'); + await act(async () => ledger.retry()); + expect(ledger.screen).toBe('accounts'); + expect(ledger.error).toBeNull(); + expect(ledger.accounts).toHaveLength(5); + expect(success).not.toHaveBeenCalled(); + expect(mocks.acquire).toHaveBeenCalledTimes(3); + } finally { + consoleError.mockRestore(); + } + }); + + it('does not reopen Ledger selection if its dialog closes during mismatch cleanup', async () => { + const success = vi.fn(); + const selected = await mountLedger(success); + mocks.connect.mockResolvedValue({ + accounts: [mocks.ledgerAddress(DEFAULT_PATH)], + chainId: mainnet.id, + }); + const disconnect = mocks.disconnect.getMockImplementation()!; + let finishCleanup!: () => void; + mocks.disconnect.mockImplementation(async (args) => { + if (args.connector.uid.startsWith('selected')) + await new Promise((resolve) => { + finishCleanup = resolve; + }); + await disconnect(args); + }); + let selection!: Promise; + await act(async () => { + selection = ledger.selectAccount(selected); + }); + expect(mocks.disconnect).toHaveBeenCalledTimes(2); + await act(async () => modal.forceCloseAllModals()); + await act(async () => { + finishCleanup(); + await selection; + }); + expect(modal.currentModal).toBeUndefined(); + expect(mocks.state.connections.size).toBe(0); + expect(mocks.acquire).toHaveBeenCalledOnce(); + expect(success).not.toHaveBeenCalled(); + }); + }); + it('keeps inactive Ledger providers inert', async () => { + await mount( + {}, + 'metaMask', + + + , + ); + expect(ledger.screen).toBe('connection'); + expect(ledger.accounts).toEqual([]); + expect(ledger.error).toBeNull(); + }); +}); diff --git a/packages/reef-knot/src/headless/__tests__/getConnectionErrorMessage.test.ts b/packages/reef-knot/src/headless/__tests__/getConnectionErrorMessage.test.ts new file mode 100644 index 00000000..056de178 --- /dev/null +++ b/packages/reef-knot/src/headless/__tests__/getConnectionErrorMessage.test.ts @@ -0,0 +1,222 @@ +import { describe, expect, it } from 'vitest'; +import { + ChainDisconnectedError, + ResourceUnavailableRpcError, + UnauthorizedProviderError, + UserRejectedRequestError, +} from 'viem'; +import { mainnet, sepolia } from 'viem/chains'; +import { ConnectorNotFoundError, ProviderNotFoundError } from 'wagmi'; +import { UserFacingError } from '../../core-react/helpers/userFacingError'; +import { interceptLedgerError } from '../../core-react/helpers/interceptLedgerError'; +import { + getConnectionErrorMessage, + isRequestPendingError, + isUserRejectedError, + toConnectionError, +} from '../helpers/getConnectionErrorMessage'; + +describe('isUserRejectedError', () => { + it.each([ + ['viem error', new UserRejectedRequestError(new Error('denied'))], + ['EIP-1193 object', { code: 4001, message: 'Request rejected' }], + ['ethers code', { code: 'ACTION_REJECTED' }], + ['message only', new Error('User rejected the request.')], + ['message only', new Error('User denied account authorization')], + ['MetaMask modal closed', new Error('User closed modal')], + ['nested cause', new Error('Wrapped', { cause: { code: 4001 } })], + ])('detects a rejection: %s', (_name, error) => { + expect(isUserRejectedError(error)).toBe(true); + }); + + it.each([ + ['plain error', new Error('Chain not configured')], + ['other code', { code: 4100 }], + ['string', 'User rejected'], + ['null', null], + ])('ignores other errors: %s', (_name, error) => { + expect(isUserRejectedError(error)).toBe(false); + }); + + it('stops on a cyclic cause chain', () => { + const error: { cause?: unknown } = {}; + error.cause = error; + expect(isUserRejectedError(error)).toBe(false); + }); +}); + +const METAMASK_PENDING_MESSAGE = + "MetaMask - RPC Error: Request of type 'wallet_requestPermissions' already pending for origin http://localhost:3000. Please wait."; + +// Ledger Live wraps every non-4001 error in ResourceUnavailableRpcError. +const LEDGER_LIVE_TIMEOUT = new ResourceUnavailableRpcError( + new Error('RPC ID "1" timed out after 240000 milliseconds'), +); + +describe('isRequestPendingError', () => { + it.each([ + [ + 'viem error', + new ResourceUnavailableRpcError(new Error(METAMASK_PENDING_MESSAGE)), + ], + ['EIP-1193 object', { code: -32002, message: METAMASK_PENDING_MESSAGE }], + ['MetaMask message', new Error(METAMASK_PENDING_MESSAGE)], + [ + 'MetaMask eth_requestAccounts', + new Error('Already processing eth_requestAccounts. Please wait.'), + ], + [ + 'nested cause', + new Error('Wrapped', { cause: new Error(METAMASK_PENDING_MESSAGE) }), + ], + ])('detects a pending request: %s', (_name, error) => { + expect(isRequestPendingError(error)).toBe(true); + }); + + it.each([ + ['plain error', new Error('Chain not configured')], + ['rejection', { code: 4001 }], + ['code -32002 only', { code: -32002, message: 'Resource unavailable' }], + ['Ledger Live timeout', LEDGER_LIVE_TIMEOUT], + ['null', null], + ])('ignores other errors: %s', (_name, error) => { + expect(isRequestPendingError(error)).toBe(false); + }); +}); + +describe('toConnectionError', () => { + it('keeps Error instances', () => { + const error = new Error('Failed'); + expect(toConnectionError(error)).toBe(error); + }); + + it('keeps a readable message from a thrown value', () => { + expect(toConnectionError('Failed').message).toBe('Failed'); + expect(toConnectionError({ message: 'Failed' }).message).toBe('Failed'); + }); + + it('does not convert an object to "[object Object]"', () => { + const value = { reason: 'unknown' }; + const error = toConnectionError(value); + expect(error.message).not.toContain('[object'); + expect(error.cause).toBe(value); + }); +}); + +const FALLBACK = 'Connection error. Please try again.'; + +describe('getConnectionErrorMessage', () => { + it.each([ + [ + 'TypeError', + new TypeError( + "Cannot read properties of undefined (reading 'sendMessage')", + ), + ], + ['plain error', new Error('Failed')], + [ + 'viem shortMessage', + Object.assign(new Error('Long details'), { shortMessage: 'Short' }), + ], + ['object message', Object.assign(new Error(), { message: {} })], + ['string', 'Failed'], + ['null', null], + ])('hides the text of an unknown error: %s', (_name, error) => { + expect(getConnectionErrorMessage(error)).toBe(FALLBACK); + }); + + it('shows the message of a UserFacingError', () => { + const error = new UserFacingError('Reconnect the wallet.'); + expect(getConnectionErrorMessage(error)).toBe('Reconnect the wallet.'); + }); + + it('finds a UserFacingError in the cause chain', () => { + const error = new Error('Wrapped', { + cause: new UserFacingError('Reconnect the wallet.'), + }); + expect(getConnectionErrorMessage(error)).toBe('Reconnect the wallet.'); + }); + + it('replaces a technical message for a pending request', () => { + const error = Object.assign(new Error(METAMASK_PENDING_MESSAGE), { + code: -32002, + }); + expect(getConnectionErrorMessage(error)).toMatch( + /already open in your wallet/, + ); + }); + + it('shows the generic message for a Ledger Live timeout', () => { + expect(getConnectionErrorMessage(LEDGER_LIVE_TIMEOUT)).toBe(FALLBACK); + }); + + it('shows the generic message for code -32002 without pending text', () => { + expect(getConnectionErrorMessage({ code: -32002 })).toBe(FALLBACK); + }); + + it('shows a rejection message', () => { + expect(getConnectionErrorMessage({ code: 4001 })).toMatch(/rejected/); + }); + + it.each([ + [ + 'legacy name', + Object.assign(new Error(), { name: 'UnsupportedChainIdError' }), + ], + [ + 'wagmi name', + Object.assign(new Error(), { name: 'ChainNotConfiguredError' }), + ], + ['EIP-1193 code', { code: 4902 }], + ])('names the supported chains: %s', (_name, error) => { + expect(getConnectionErrorMessage(error, [mainnet, sepolia])).toBe( + 'Unsupported chain. Please switch to Ethereum or Sepolia in your wallet.', + ); + }); + + it('shows a generic chain message without chains', () => { + expect(getConnectionErrorMessage({ code: 4902 })).toMatch( + /^Unsupported chain/, + ); + }); + + it.each([ + ['wagmi provider', new ProviderNotFoundError()], + ['wagmi connector', new ConnectorNotFoundError()], + ])('shows a "not found" message: %s', (_name, error) => { + expect(getConnectionErrorMessage(error)).toMatch(/^Wallet not found/); + }); + + it('shows an authorization message', () => { + const error = new UnauthorizedProviderError(new Error('4100')); + expect(getConnectionErrorMessage(error)).toMatch(/did not authorize/); + }); + + it('shows a disconnection message', () => { + const error = new ChainDisconnectedError(new Error('4901')); + expect(getConnectionErrorMessage(error)).toMatch(/disconnected/); + }); +}); + +describe('interceptLedgerError', () => { + it('maps a known Ledger error to a UserFacingError', () => { + const error = Object.assign(new Error('0x5515'), { + name: 'LockedDeviceError', + }); + const mapped = interceptLedgerError(error); + expect(mapped).toBeInstanceOf(UserFacingError); + expect(mapped.cause).toBe(error); + expect(getConnectionErrorMessage(mapped)).toMatch(/device is locked/); + }); + + it.each([ + [ + 'without a message', + Object.assign(new Error('x'), { name: 'TransportError' }), + ], + ['unknown', new Error('Internal')], + ])('keeps a Ledger error %s', (_name, error) => { + expect(interceptLedgerError(error)).toBe(error); + expect(getConnectionErrorMessage(error)).toBe(FALLBACK); + }); +}); diff --git a/packages/reef-knot/src/headless/__tests__/ledger.test.tsx b/packages/reef-knot/src/headless/__tests__/ledger.test.tsx new file mode 100644 index 00000000..497cb988 --- /dev/null +++ b/packages/reef-knot/src/headless/__tests__/ledger.test.tsx @@ -0,0 +1,167 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, expect, it, vi } from 'vitest'; +import { + LedgerContext, + LedgerContextProvider, + type LedgerContextValue, +} from '../ledger/LedgerContext'; +import { useLedgerContext, useLedgerAccounts } from '../ledger/hooks'; + +const mocks = vi.hoisted(() => ({ + acquire: vi.fn(), + close: vi.fn(), + address: vi.fn(), +})); +vi.mock('../ledger/helpers', async (original) => ({ + ...(await original()), + getTransport: mocks.acquire, + isHIDSupported: () => true, +})); +vi.mock('@ledgerhq/hw-app-eth', () => ({ + default: class { + getAppConfiguration = async () => ({}); + getAddress = mocks.address; + }, +})); +vi.mock('wagmi', () => { + const config = {}; + return { useConfig: () => config }; +}); +vi.mock('wagmi/actions', () => ({ + getBalance: async () => ({ value: 0n, symbol: 'ETH' }), +})); +Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); +const container = document.createElement('div'); +document.body.append(container); +let root = createRoot(container); +afterEach(async () => { + await act(async () => root.unmount()); + root = createRoot(container); + vi.clearAllMocks(); +}); + +it('releases a transport acquired after the Ledger screen has closed', async () => { + let resolveTransport!: (transport: { close: typeof mocks.close }) => void; + mocks.acquire.mockImplementationOnce( + () => + new Promise<{ close: typeof mocks.close }>((resolve) => { + resolveTransport = resolve; + }), + ); + await act(async () => + root.render( + + + , + ), + ); + await act(async () => + root.render( + + + , + ), + ); + await act(async () => resolveTransport({ close: mocks.close })); + expect(mocks.acquire).toHaveBeenCalledOnce(); + expect(mocks.close).toHaveBeenCalledOnce(); +}); + +it('serializes page requests and loads the latest page after rapid navigation', async () => { + let resolveAddress!: (address: { address: string }) => void; + mocks.address.mockImplementationOnce( + () => + new Promise<{ address: string }>((resolve) => { + resolveAddress = resolve; + }), + ); + mocks.address.mockResolvedValue({ address: '0x123' }); + let accounts: ReturnType = {}; + const partialContext = { + isActive: true, + isTransportConnected: true, + ledgerAppEth: { current: { getAddress: mocks.address } }, + transport: { current: {} }, + setError: vi.fn(), + }; + const context = partialContext as unknown as LedgerContextValue; + function Probe({ page }: { page: number }) { + accounts = useLedgerAccounts({ + derivationPathTemplate: "m/44'/60'/x'/0/0", + currentPage: page, + accountsPerPage: 2, + }); + return null; + } + const render = (page: number) => + root.render( + + + , + ); + await act(async () => render(1)); + await act(async () => { + render(2); + }); + await act(async () => { + render(3); + }); + expect(mocks.address).toHaveBeenCalledOnce(); + await act(async () => resolveAddress({ address: '0x123' })); + expect(Object.keys(accounts)).toEqual(['4', '5']); + expect(mocks.address).toHaveBeenCalledTimes(3); + expect(partialContext.setError).not.toHaveBeenCalled(); +}); + +it('retries a failed transport and releases the connected device on exit', async () => { + mocks.acquire + .mockRejectedValueOnce(new Error('Connection refused')) + .mockResolvedValueOnce({ close: mocks.close }); + let context!: ReturnType; + function Probe() { + context = useLedgerContext(); + return null; + } + await act(async () => + root.render( + + + , + ), + ); + expect(context.error?.message).toBe('Connection refused'); + expect(context.isTransportConnected).toBe(false); + await act(async () => context.reconnectTransport()); + expect(context.error).toBeNull(); + expect(context.isTransportConnected).toBe(true); + await act(async () => root.render()); + expect(mocks.close).toHaveBeenCalledOnce(); +}); + +it('preserves the accounts screen when releasing the transport for connector handoff', async () => { + mocks.acquire.mockResolvedValueOnce({ close: mocks.close }); + let context!: ReturnType; + function Probe() { + context = useLedgerContext(); + return null; + } + await act(async () => + root.render( + + + , + ), + ); + expect(context.isTransportConnected).toBe(true); + await act(async () => context.disconnectTransport(true)); + expect(mocks.close).toHaveBeenCalledOnce(); + expect(context.transport.current).toBeNull(); + expect(context.ledgerAppEth.current).toBeNull(); + expect(context.isTransportConnected).toBe(true); + + await act(async () => context.disconnectTransport()); + expect(context.isTransportConnected).toBe(false); + expect(mocks.close).toHaveBeenCalledOnce(); +}); diff --git a/packages/reef-knot/src/headless/components/EIP6963Picker.tsx b/packages/reef-knot/src/headless/components/EIP6963Picker.tsx new file mode 100644 index 00000000..52a51d36 --- /dev/null +++ b/packages/reef-knot/src/headless/components/EIP6963Picker.tsx @@ -0,0 +1,41 @@ +import type { ReefKnotUIComponents, ReefKnotTheme } from '../../types/ui'; +import { useEIP6963Picker } from '../connection'; +import { validateIcon, FALLBACK_WALLET_ICON } from '../helpers/validateIcon'; +import { Terms } from './Terms'; + +/** + * Renders discovered EIP-6963 providers through the same replaceable wallet + * buttons. Validates provider-supplied icons and delegates selection to the hook. + */ +export function EIP6963Picker({ + components, + theme, +}: { + components: ReefKnotUIComponents; + theme?: ReefKnotTheme; +}) { + const state = useEIP6963Picker(); + return ( + } + error={state.error} + errorMessage={state.errorMessage} + > + {state.providers.map((provider) => ( + { + void state.select(provider); + }} + /> + ))} + + ); +} diff --git a/packages/reef-knot/src/headless/components/EagerConnect.tsx b/packages/reef-knot/src/headless/components/EagerConnect.tsx new file mode 100644 index 00000000..571956b7 --- /dev/null +++ b/packages/reef-knot/src/headless/components/EagerConnect.tsx @@ -0,0 +1,18 @@ +import type { ReefKnotUIComponents } from '../../types/ui'; +import { useEagerConnectScreen } from '../eager'; +import { Terms } from './Terms'; + +/** Supplies the eager connection confirmation/retry view with its actions and Terms. */ +export function EagerConnect({ + components, +}: { + components: ReefKnotUIComponents; +}) { + const state = useEagerConnectScreen(); + return ( + } + /> + ); +} diff --git a/packages/reef-knot/src/headless/components/Ledger.tsx b/packages/reef-knot/src/headless/components/Ledger.tsx new file mode 100644 index 00000000..b8121587 --- /dev/null +++ b/packages/reef-knot/src/headless/components/Ledger.tsx @@ -0,0 +1,14 @@ +import type { ReefKnotUIComponents } from '../../types/ui'; +import { useLedgerFlow } from '../ledger/flow'; + +/** Selects the device, accounts or error view from the active Ledger flow state. */ +export function Ledger({ components }: { components: ReefKnotUIComponents }) { + const state = useLedgerFlow(); + const views = { + connection: components.LedgerConnection, + accounts: components.LedgerAccounts, + error: components.LedgerError, + }; + const View = views[state.screen]; + return ; +} diff --git a/packages/reef-knot/src/headless/components/Terms.tsx b/packages/reef-knot/src/headless/components/Terms.tsx new file mode 100644 index 00000000..1dae0641 --- /dev/null +++ b/packages/reef-knot/src/headless/components/Terms.tsx @@ -0,0 +1,15 @@ +import type { ReefKnotUIComponents } from '../../types/ui'; +import { useTerms } from '../connection'; + +/** Connects the replaceable Terms view to shared consent state and configured links. */ +export function Terms({ components }: { components: ReefKnotUIComponents }) { + const state = useTerms(); + return ( + + ); +} diff --git a/packages/reef-knot/src/headless/components/Wallet.tsx b/packages/reef-knot/src/headless/components/Wallet.tsx new file mode 100644 index 00000000..8dd3d8d1 --- /dev/null +++ b/packages/reef-knot/src/headless/components/Wallet.tsx @@ -0,0 +1,38 @@ +import type { + ReefKnotUIComponents, + ReefKnotTheme, + WalletButtonViewProps, +} from '../../types/ui'; +import { useWalletConnection } from '../connection'; + +/** + * Adapts one wallet to the supplied wallet connection buttons list view. The headless hook owns + * visibility, connection eligibility, loading and the connection action. + */ +export function Wallet({ + id, + components, + theme, + compact, +}: { + id: string; + components: ReefKnotUIComponents; + theme?: ReefKnotTheme; + compact: boolean; +}) { + const state = useWalletConnection(id); + if (!state.isVisible || !state.wallet) return null; + const props: WalletButtonViewProps = { + walletId: id, + name: state.wallet.walletName, + icon: state.wallet.icon, + disabled: state.disabled, + isLoading: state.isLoading, + theme, + compact, + onConnect: () => { + void state.connect(); + }, + }; + return ; +} diff --git a/packages/reef-knot/src/headless/components/WalletPicker.tsx b/packages/reef-knot/src/headless/components/WalletPicker.tsx new file mode 100644 index 00000000..c03a78bf --- /dev/null +++ b/packages/reef-knot/src/headless/components/WalletPicker.tsx @@ -0,0 +1,42 @@ +import type { ReefKnotUIComponents, ReefKnotTheme } from '../../types/ui'; +import type { ReefKnotWalletsModalConfig } from '../../types/reef-knot-wallets-modal'; +import { useWalletPicker } from '../connection'; +import { Terms } from './Terms'; +import { Wallet } from './Wallet'; + +export type WalletPickerProps = { + config: ReefKnotWalletsModalConfig; + components: ReefKnotUIComponents; + theme?: ReefKnotTheme; + buttonsFullWidth?: boolean; +}; + +/** + * Composes the main wallet screen from picker state, shared Terms and wallet + * buttons. Search, ordering and expansion are handled by useWalletPicker. + */ +export function WalletPicker({ + components, + theme, + buttonsFullWidth, +}: WalletPickerProps) { + const state = useWalletPicker(); + return ( + } + theme={theme} + buttonsFullWidth={buttonsFullWidth} + > + {state.wallets.map((wallet) => ( + + ))} + + ); +} diff --git a/packages/reef-knot/src/headless/connection.tsx b/packages/reef-knot/src/headless/connection.tsx new file mode 100644 index 00000000..f62029f4 --- /dev/null +++ b/packages/reef-knot/src/headless/connection.tsx @@ -0,0 +1,623 @@ +import React, { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { + useConfig, + useConnect as useWagmiConnect, + useDisconnect as useWagmiDisconnect, + type CreateConnectorFn, +} from 'wagmi'; +import { injected } from 'wagmi/connectors'; +import { isAddress, isAddressEqual } from 'viem'; +import { + isMobileOrTablet, + type WalletAdapterData, +} from '@reef-knot/wallets-helpers'; +import { + LS_KEY_RECONNECT_WALLET_ID, + useDisconnect, + useEIP6963Providers, + useReefKnotContext, + useReefKnotModal, +} from '../core-react'; +import type { EIP6963ProviderDetail } from '../core-react'; +import { UserFacingError } from '../core-react/helpers/userFacingError'; +import type { ReefKnotWalletsModalConfig } from '../types/reef-knot-wallets-modal'; +import { sortWalletsList } from './helpers/sortWalletsList'; +import { openWindow } from './helpers/openWindow'; +import { suggestApp } from './helpers/suggestApp'; +import { + getConnectionErrorMessage, + isUserRejectedError, + toConnectionError, +} from './helpers/getConnectionErrorMessage'; + +export type WalletPickerState = { + wallets: WalletAdapterData[]; + allWallets: WalletAdapterData[]; + search: string; + expanded: boolean; + showToggle: boolean; + isDiscovering: boolean; + error: Error | null; + /** Safe to show to the user. The original error stays in `error`. */ + errorMessage: string | null; + setSearch: (value: string) => void; + dismissError: () => void; + clearSearch: () => void; + toggleExpanded: () => void; +}; + +type ConnectConnectorOptions = { + /** + * Runs after old wallets finish disconnecting, before the new connector starts. + * Ledger uses this to save the selected derivation path. Saving it earlier + * would let the old Ledger's disconnect() erase the new selection. + */ + beforeConnect?: () => void; + /** + * Currently used only by Ledger: the address chosen in its account picker. + * The connector reads the saved path again when connecting. A lost path or + * a device change can make it return a different account, even if it connects + * successfully. Check the address before saving reconnect data or reporting + * success. Other flows do not select an address in advance and omit this option. + */ + expectedAddress?: string; +}; + +// Ledger handles this separately to reload accounts without an error screen. +// It is thrown only after cleanup succeeds; cleanup failures remain normal errors. +export class AccountMismatchError extends UserFacingError { + constructor() { + super('The connected account does not match the selected account.'); + this.name = 'AccountMismatchError'; + } +} + +type ConnectionContextValue = { + config: ReefKnotWalletsModalConfig; + picker: WalletPickerState; + error: Error | null; + errorMessage: string | null; + busy: boolean; + dismissError: () => void; + connectWallet: (wallet: WalletAdapterData) => Promise; + selectProvider: (provider: EIP6963ProviderDetail) => Promise; + connectConnector: ( + connector: CreateConnectorFn, + options?: ConnectConnectorOptions, + ) => Promise; + completeConnection: (walletId: string, rdns?: string) => Promise; + notifyStart: (id: string) => void; + setConsent: (checked: boolean) => void; + run: (id: string, action: () => Promise) => Promise; +}; +const ConnectionContext = createContext(null); + +export const useConnectionContext = (config?: ReefKnotWalletsModalConfig) => { + const value = useContext(ConnectionContext); + if (!value) + throw new Error('Headless connection hooks require ReefKnotUIProvider.'); + if (config && config !== value.config) + throw new Error( + 'Pass the same config object to headless hooks and ReefKnotUIProvider.', + ); + return value; +}; + +/** One owner for discovery and connection actions, shared by every view. */ +export function ReefKnotUIProvider({ + config: modalConfig, + children, +}: React.PropsWithChildren<{ config: ReefKnotWalletsModalConfig }>) { + const config = useConfig(); + const { mutateAsync: connectAsync } = useWagmiConnect(); + const { mutateAsync: disconnectConnectorAsync } = useWagmiDisconnect(); + const { disconnectAsync } = useDisconnect(); + const { walletDataList, loadingWalletId, setLoadingWalletId } = + useReefKnotContext(); + const { + termsChecked, + setTermsChecked, + currentModal, + modalStack, + closeModal, + openModalAsync, + openModal, + } = useReefKnotModal(); + const allProviders = useEIP6963Providers(); + const [allWallets, setAllWallets] = useState([]); + const [search, setSearch] = useState(''); + const [expanded, setExpanded] = useState(false); + const [isDiscovering, setDiscovering] = useState(false); + const [error, setError] = useState(null); + const dismissError = useCallback(() => setError(null), []); + const errorMessage = useMemo( + () => (error ? getConnectionErrorMessage(error, config.chains) : null), + [error, config.chains], + ); + const locked = useRef(false); + const ledgerOpening = useRef(false); + const providerOpening = useRef(false); + const actionModal = useRef(currentModal); + // Remember the completed screen to prevent duplicate success callbacks and closes. + const completedConnectionModal = useRef(); + const connectedConnectorUid = useRef(); + const alive = useRef(true); + // Refreshed every render, so stable callbacks read the current modal state without re-creating. + const modalStateRef = useRef({ + termsChecked, + modalStack, + closeModal, + modalConfig, + }); + modalStateRef.current = { termsChecked, modalStack, closeModal, modalConfig }; + + useEffect(() => { + alive.current = true; + return () => { + alive.current = false; + }; + }, []); + + const inPicker = currentModal?.type === 'wallet'; + useEffect(() => { + let active = true; + setDiscovering(true); + void sortWalletsList({ + walletDataList, + walletsShown: modalConfig.walletsShown, + walletsPinned: modalConfig.walletsPinned, + }) + .then((wallets) => { + if (active) setAllWallets(wallets); + }) + .catch((e: unknown) => { + if (active) setError(toConnectionError(e)); + }) + .finally(() => { + if (active) setDiscovering(false); + }); + return () => { + active = false; + }; + }, [ + inPicker, + walletDataList, + modalConfig.walletsShown, + modalConfig.walletsPinned, + allProviders, + ]); + + useEffect(() => { + if (currentModal?.type !== 'eip6963') providerOpening.current = false; + if (!currentModal) { + setSearch(''); + setExpanded(false); + setError(null); + } else if (currentModal.type === 'eager') { + const { initialError } = currentModal.props; + setError( + initialError && !isUserRejectedError(initialError) + ? toConnectionError(initialError) + : null, + ); + } + }, [currentModal]); + + // Commit a successful connection: save reconnect, close its screens and notify the app. + // This runs after connecting; it does not initiate a wallet connection. + const completeConnection = useCallback( + async (walletId: string, rdns?: string) => { + const { status, current: uid, connections } = config.state; + const connector = uid ? connections.get(uid)?.connector : undefined; + if ( + status !== 'connected' || + !connector || + (connectedConnectorUid.current + ? uid !== connectedConnectorUid.current + : rdns && connector.id !== rdns) + ) + throw new UserFacingError( + 'The selected wallet is no longer connected. Please retry.', + ); + const target = + actionModal.current ?? + modalStateRef.current.modalStack[ + modalStateRef.current.modalStack.length - 1 + ]; + if (target && completedConnectionModal.current === target) return; + completedConnectionModal.current = target; + // Report success only after the write, so a remount cannot read the previous wallet. + try { + await config.storage?.setItem( + LS_KEY_RECONNECT_WALLET_ID, + rdns ?? walletId, + ); + } catch { + // A storage error must not turn a successful connection into a failure. + } + const stack = modalStateRef.current.modalStack; + // EIP-6963 completes its own screen and the underlying wallet picker. + const nested = stack[stack.length - 1]?.type; + const count = + (nested === 'eip6963' || nested === 'ledger') && + stack[stack.length - 2]?.type === 'wallet' + ? 2 + : 1; + if (stack[stack.length - 1] === target) { + for (let i = 0; i < count; i += 1) + modalStateRef.current.closeModal({ connected: true }); + } + modalStateRef.current.modalConfig.onConnectSuccess?.({ walletId, rdns }); + }, + [config], + ); + + const notifyStart = useCallback((walletId: string) => { + actionModal.current = + modalStateRef.current.modalStack[ + modalStateRef.current.modalStack.length - 1 + ]; + modalStateRef.current.modalConfig.onConnectStart?.({ walletId }); + }, []); + const run = useCallback( + async (id: string, action: () => Promise) => { + if (!modalStateRef.current.termsChecked || locked.current) return; + locked.current = true; + connectedConnectorUid.current = undefined; + const attemptModal = + modalStateRef.current.modalStack[ + modalStateRef.current.modalStack.length - 1 + ]; + actionModal.current = attemptModal; + setLoadingWalletId(id); + setError(null); + try { + await action(); + } catch (e) { + // A late rejection belongs to the screen that started the attempt, + // never to a picker opened after that screen was dismissed. + // A rejection in the wallet is a user choice, so keep the current screen. + const stack = modalStateRef.current.modalStack; + if ( + alive.current && + stack[stack.length - 1] === attemptModal && + !isUserRejectedError(e) + ) + setError(toConnectionError(e)); + } finally { + locked.current = false; + setLoadingWalletId(null); + } + }, + [setLoadingWalletId], + ); + + const connectConnector = useCallback( + async ( + createConnector: CreateConnectorFn, + { beforeConnect, expectedAddress }: ConnectConnectorOptions = {}, + ) => { + await disconnectAsync?.(); + // Ledger disconnect clears the saved path; write the new selection after it. + beforeConnect?.(); + let connectorUid: string | undefined; + const result = await connectAsync({ + connector: (args) => { + connectorUid = args.emitter.uid; + return createConnector(args); + }, + }); + // Track the instance, not its id: two instances can describe the same wallet. + if (!connectorUid) + throw new UserFacingError( + 'The selected wallet connection could not be verified.', + ); + if (expectedAddress !== undefined) { + // The connector UID identifies the connection, but not the chosen account. + // Ledger returns one account, so verify its address against the picker + // selection. The saved path alone cannot prove which account connected. + const address = result.accounts?.[0]; + if ( + !isAddress(expectedAddress, { strict: false }) || + !address || + !isAddress(address, { strict: false }) || + !isAddressEqual(address, expectedAddress) + ) { + // Only disconnect this attempt; another wallet may now be active. + const connector = + config.state.connections.get(connectorUid)?.connector; + try { + if (connector) await disconnectConnectorAsync({ connector }); + } finally { + // Wagmi may rewrite recentConnectorId during disconnect. + // Clear both keys afterward, even if disconnect fails. + await Promise.all([ + config.storage?.removeItem(LS_KEY_RECONNECT_WALLET_ID), + config.storage?.removeItem('recentConnectorId'), + ]); + } + throw new AccountMismatchError(); + } + } + connectedConnectorUid.current = connectorUid; + }, + [disconnectAsync, connectAsync, disconnectConnectorAsync, config], + ); + const connectProvider = useCallback( + async (provider: EIP6963ProviderDetail) => { + await connectConnector( + injected({ + target: { + id: provider.info.rdns, + name: provider.info.name, + provider: () => provider.provider, + }, + }), + ); + }, + [connectConnector], + ); + const selectProvider = useCallback( + async (provider: EIP6963ProviderDetail) => { + await run(provider.info.rdns, async () => { + const screen = + modalStateRef.current.modalStack[ + modalStateRef.current.modalStack.length - 1 + ]; + if (screen?.type === 'eip6963') await screen.props.onSelect(provider); + else await connectProvider(provider); + await completeConnection('browserExtension', provider.info.rdns); + }); + }, + [run, connectProvider, completeConnection], + ); + + const connectWallet = useCallback( + async (wallet: WalletAdapterData) => { + if ( + !modalStateRef.current.termsChecked || + locked.current || + ledgerOpening.current || + providerOpening.current || + loadingWalletId != null + ) + return; + // Mobile deeplinks do not start a wagmi connection. + if ( + wallet.type === 'walletConnect' && + isMobileOrTablet && + wallet.deeplink + ) { + openWindow(wallet.deeplink); + return; + } + modalConfig.onConnectStart?.({ walletId: wallet.walletId }); + if (wallet.type === 'ledgerHID') { + ledgerOpening.current = true; + try { + await openModalAsync({ type: 'ledger' }); + } finally { + ledgerOpening.current = false; + } + return; // The Ledger flow owns completion and the callback. + } + if (wallet.walletId === 'browserExtension') { + const known = new Set(walletDataList.map((w) => w.rdns)); + const providers = allProviders.filter((p) => !known.has(p.info.rdns)); + if (providers.length === 1) { + await selectProvider(providers[0]); + return; + } + if (providers.length > 1) { + providerOpening.current = true; + openModal({ + type: 'eip6963', + props: { providers, onSelect: connectProvider }, + }); + return; + } + if (typeof globalThis.window?.ethereum?.request !== 'function') { + openModal({ + type: 'requirements', + props: { kind: 'no-wallets' }, + }); + return; + } + } + await run(wallet.walletId, async () => { + if ( + wallet.type === 'injected' && + wallet.walletId !== 'metaMask' && + wallet.walletId !== 'browserExtension' && + !(await wallet.detector?.()) + ) { + if (isMobileOrTablet && wallet.deeplink) openWindow(wallet.deeplink); + else if (wallet.downloadURLs) suggestApp(wallet.downloadURLs); + return; + } + await connectConnector(wallet.createConnectorFn); + await completeConnection(wallet.walletId); + }); + }, + [ + loadingWalletId, + modalConfig, + openModalAsync, + walletDataList, + allProviders, + selectProvider, + connectProvider, + openModal, + run, + connectConnector, + completeConnection, + ], + ); + + const clearSearch = useCallback(() => setSearch(''), []); + const setConsent = useCallback( + (checked: boolean) => { + if (modalStateRef.current.termsChecked === checked) return; + modalStateRef.current.termsChecked = checked; + setTermsChecked(checked); + if (checked) + modalStateRef.current.modalConfig.onClickTermsAccept?.({ + isAccepted: checked, + }); + }, + [setTermsChecked], + ); + const toggleExpanded = useCallback(() => { + const next = !expanded; + setExpanded(next); + if (!next) setSearch(''); + if (next) modalConfig.onClickWalletsMore?.(); + else modalConfig.onClickWalletsLess?.(); + }, [expanded, modalConfig]); + const wallets = useMemo( + () => + search + ? allWallets.filter((wallet) => + wallet.walletName.toLowerCase().includes(search.toLowerCase()), + ) + : expanded + ? allWallets + : allWallets.slice(0, modalConfig.walletsDisplayInitialCount ?? 6), + [allWallets, search, expanded, modalConfig.walletsDisplayInitialCount], + ); + const picker = useMemo( + () => ({ + wallets, + allWallets, + search, + expanded, + isDiscovering, + error, + errorMessage, + showToggle: expanded || allWallets.length > wallets.length, + setSearch, + clearSearch, + toggleExpanded, + dismissError, + }), + [ + wallets, + allWallets, + search, + expanded, + isDiscovering, + error, + errorMessage, + toggleExpanded, + clearSearch, + dismissError, + ], + ); + const value = useMemo( + () => ({ + config: modalConfig, + setConsent, + notifyStart, + picker, + error, + errorMessage, + busy: loadingWalletId != null, + dismissError, + connectWallet, + selectProvider, + connectConnector, + completeConnection, + run, + }), + [ + modalConfig, + setConsent, + notifyStart, + picker, + error, + errorMessage, + loadingWalletId, + dismissError, + connectWallet, + selectProvider, + connectConnector, + completeConnection, + run, + ], + ); + return ( + + {children} + + ); +} + +export function useWalletPicker( + config?: ReefKnotWalletsModalConfig, +): WalletPickerState { + return useConnectionContext(config).picker; +} + +export function useWalletConnection( + walletId: string, + config?: ReefKnotWalletsModalConfig, +) { + const flow = useConnectionContext(config); + const { walletDataList, loadingWalletId } = useReefKnotContext(); + const { termsChecked } = useReefKnotModal(); + const wallet = walletDataList.find((entry) => entry.walletId === walletId); + return { + wallet, + isVisible: + !!wallet && + !wallet.autoConnectOnly && + !(wallet.walletId === 'browserExtension' && isMobileOrTablet), + disabled: !termsChecked || flow.busy, + isLoading: + loadingWalletId === walletId || + (walletId === 'browserExtension' && !!loadingWalletId?.includes('.')), + error: flow.error, + errorMessage: flow.errorMessage, + completeConnection: (reconnectId?: string, rdns?: string) => + flow.completeConnection(reconnectId ?? walletId, rdns), + notifyStart: () => flow.notifyStart(walletId), + connect: () => (wallet ? flow.connectWallet(wallet) : Promise.resolve()), + }; +} + +export function useTerms(config?: ReefKnotWalletsModalConfig) { + const flow = useConnectionContext(config); + const { termsChecked } = useReefKnotModal(); + const settings = config ?? flow.config; + return { + checked: termsChecked, + linkTerms: settings.linkTerms, + linkPrivacyNotice: settings.linkPrivacyNotice, + setChecked: flow.setConsent, + }; +} + +export function useEIP6963Picker(config?: ReefKnotWalletsModalConfig) { + const flow = useConnectionContext(config); + const { currentModal } = useReefKnotModal(); + const { loadingWalletId } = useReefKnotContext(); + const { termsChecked } = useReefKnotModal(); + return { + providers: + currentModal?.type === 'eip6963' ? currentModal.props.providers : [], + disabled: !termsChecked || flow.busy, + loadingWalletId, + error: flow.error, + errorMessage: flow.errorMessage, + select: flow.selectProvider, + dismissError: flow.dismissError, + }; +} diff --git a/packages/reef-knot/src/headless/eager.ts b/packages/reef-knot/src/headless/eager.ts new file mode 100644 index 00000000..2f24c4a7 --- /dev/null +++ b/packages/reef-knot/src/headless/eager.ts @@ -0,0 +1,29 @@ +import { useCallback, useRef } from 'react'; +import { useReefKnotModal } from '../core-react'; +import type { ReefKnotWalletsModalConfig } from '../types/reef-knot-wallets-modal'; +import { useConnectionContext } from './connection'; + +export function useEagerConnectScreen(config?: ReefKnotWalletsModalConfig) { + const { currentModal, closeModal, termsChecked } = useReefKnotModal(); + const latest = useRef(currentModal); + latest.current = currentModal; + const props = currentModal?.type === 'eager' ? currentModal.props : undefined; + const connection = useConnectionContext(config); + const error = connection.error; + const isLoading = connection.busy; + const connect = useCallback(async () => { + if (!props || !termsChecked) return; + await connection.run('eager', async () => { + await props.tryConnection(); + // A cancelled request must not close a newly opened screen. + if (latest.current === currentModal) closeModal({ connected: true }); + }); + }, [props, termsChecked, closeModal, connection, currentModal]); + return { + error, + errorMessage: connection.errorMessage ?? undefined, + isLoading, + disabled: !termsChecked || isLoading, + connect, + }; +} diff --git a/packages/reef-knot/src/headless/getDefaultWalletsModalConfig.ts b/packages/reef-knot/src/headless/getDefaultWalletsModalConfig.ts new file mode 100644 index 00000000..40dcd53f --- /dev/null +++ b/packages/reef-knot/src/headless/getDefaultWalletsModalConfig.ts @@ -0,0 +1,29 @@ +import type { ReefKnotWalletsModalConfig } from '../types/reef-knot-wallets-modal'; +import type { WalletIdsEthereum } from '../wallets-list'; + +export const WALLETS_MODAL_DISPLAY_CONFIG_DEFAULT: WalletIdsEthereum[] = [ + 'browserExtension', + 'metaMask', + 'okx', + 'ledgerHID', + 'ledgerLive', + 'walletConnect', + 'coinbaseSmartWallet', + 'bitget', + 'anchorageDigital', + 'imToken', + 'ambire', + 'safe', + 'dappBrowserInjected', +]; +export const WALLETS_MODAL_PINNED_CONFIG_DEFAULT: WalletIdsEthereum[] = [ + 'browserExtension', +]; + +export const getDefaultWalletsModalConfig = + (): ReefKnotWalletsModalConfig => ({ + walletsShown: [...WALLETS_MODAL_DISPLAY_CONFIG_DEFAULT], + walletsPinned: [...WALLETS_MODAL_PINNED_CONFIG_DEFAULT], + linkTerms: 'https://lido.fi/terms-of-use', + linkPrivacyNotice: 'https://lido.fi/privacy-notice', + }); diff --git a/packages/connect-wallet-modal/src/helpers/formatBalance.ts b/packages/reef-knot/src/headless/helpers/formatBalance.ts similarity index 100% rename from packages/connect-wallet-modal/src/helpers/formatBalance.ts rename to packages/reef-knot/src/headless/helpers/formatBalance.ts diff --git a/packages/reef-knot/src/headless/helpers/getConnectionErrorMessage.ts b/packages/reef-knot/src/headless/helpers/getConnectionErrorMessage.ts new file mode 100644 index 00000000..b0e0b340 --- /dev/null +++ b/packages/reef-knot/src/headless/helpers/getConnectionErrorMessage.ts @@ -0,0 +1,157 @@ +import type { Chain } from 'viem'; +import { getUnsupportedChainError } from '../../core-react/helpers/getUnsupportedChainError'; +import { UserFacingError } from '../../core-react/helpers/userFacingError'; + +type Chains = readonly [Chain, ...Chain[]]; +type ErrorFields = Record; +type ErrorMatcher = (value: ErrorFields) => boolean; +type MessageRule = { + matches: ErrorMatcher; + message: string | ((chains?: Chains) => string); +}; + +const FALLBACK_MESSAGE = 'Connection error. Please try again.'; +// EIP-1193 code for a request that the user rejected in the wallet. +const USER_REJECTED_CODE = 4001; +// MetaMask Connect throws "User closed modal" without a code when the user closes its QR modal. +const USER_REJECTED_MESSAGE = /user (rejected|denied|cancel+ed|closed)/i; +// MetaMask text for a request prompt that is already open. +const REQUEST_PENDING_MESSAGE = /already (pending|processing)/i; +// Stop on cyclic cause chains. +const MAX_CAUSE_DEPTH = 10; + +const readString = (value: unknown, key: string): string | undefined => { + if (typeof value !== 'object' || value === null || !(key in value)) + return undefined; + const field = (value as ErrorFields)[key]; + return typeof field === 'string' && field.trim() ? field : undefined; +}; + +/** Wallets wrap errors in other errors, so check each cause. */ +function findInCauseChain( + error: unknown, + predicate: ErrorMatcher, +): ErrorFields | undefined { + let current = error; + for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth += 1) { + if (typeof current !== 'object' || current === null) return undefined; + const value = current as ErrorFields; + if (predicate(value)) return value; + current = value.cause; + } + return undefined; +} + +const matchesCodeOrName = + (codes: readonly unknown[], names: readonly string[]): ErrorMatcher => + (value) => + codes.includes(value.code) || + (typeof value.name === 'string' && names.includes(value.name)); + +/** + * Wagmi connectors wrap wallet rejections in viem UserRejectedRequestError. + * Custom adapters can throw raw EIP-1193 objects, so also check the code and the text. + */ +const isUserRejected: ErrorMatcher = (value) => + matchesCodeOrName( + [USER_REJECTED_CODE, 'ACTION_REJECTED'], + ['UserRejectedRequestError'], + )(value) || USER_REJECTED_MESSAGE.test(readString(value, 'message') ?? ''); + +/** + * Check only the text. Code -32002 and viem ResourceUnavailableRpcError also + * cover other failures: Ledger Live uses them for every error, also for timeouts. + */ +const isRequestPending: ErrorMatcher = (value) => + REQUEST_PENDING_MESSAGE.test(readString(value, 'message') ?? ''); + +/** + * The only errors with a specific message. Error text from wallets and libraries + * is technical, so the UI shows a generic message for all other errors. + */ +const MESSAGE_RULES: readonly MessageRule[] = [ + { + matches: isRequestPending, + message: + 'A connection request is already open in your wallet. Open the wallet to approve or reject it.', + }, + { + matches: isUserRejected, + message: 'The connection request was rejected.', + }, + { + // EIP-1193 code 4902: the wallet does not know the chain. + matches: matchesCodeOrName( + [4902], + [ + 'UnsupportedChainIdError', + 'ChainNotConfiguredError', + 'ConnectorChainMismatchError', + ], + ), + message: (chains) => + chains?.length + ? getUnsupportedChainError(chains).message + : 'Unsupported chain. Please switch to a supported network in your wallet.', + }, + { + matches: matchesCodeOrName( + [], + ['ProviderNotFoundError', 'ConnectorNotFoundError'], + ), + message: 'Wallet not found. Make sure it is installed and enabled.', + }, + { + matches: matchesCodeOrName([4100], ['UnauthorizedProviderError']), + message: + 'The wallet did not authorize this site. Try to connect again and approve the request.', + }, + { + matches: matchesCodeOrName( + [4900, 4901], + ['ProviderDisconnectedError', 'ChainDisconnectedError'], + ), + message: 'The wallet is disconnected. Unlock it and try again.', + }, +]; + +export function isUserRejectedError(error: unknown): boolean { + return !!findInCauseChain(error, isUserRejected); +} + +/** The wallet already shows a prompt for an earlier request from this site. */ +export function isRequestPendingError(error: unknown): boolean { + return !!findInCauseChain(error, isRequestPending); +} + +/** Wallets can throw values that are not Error. Keep their message if it is readable. */ +export function toConnectionError(error: unknown): Error { + if (error instanceof Error) return error; + const message = + typeof error === 'string' ? error : readString(error, 'message'); + return new Error(message ?? FALLBACK_MESSAGE, { cause: error }); +} + +/** + * Returns a message that is safe to show to the user. + * The message of a UserFacingError is shown as is. Known wallet errors get a + * prepared message. All other errors get a generic message. + */ +export function getConnectionErrorMessage( + error: unknown, + chains?: Chains, +): string { + const own = findInCauseChain( + error, + (value) => value instanceof UserFacingError, + ); + const ownMessage = readString(own, 'message'); + if (ownMessage) return ownMessage; + for (const rule of MESSAGE_RULES) { + if (!findInCauseChain(error, rule.matches)) continue; + return typeof rule.message === 'string' + ? rule.message + : rule.message(chains); + } + return FALLBACK_MESSAGE; +} diff --git a/packages/connect-wallet-modal/src/helpers/openWindow.ts b/packages/reef-knot/src/headless/helpers/openWindow.ts similarity index 100% rename from packages/connect-wallet-modal/src/helpers/openWindow.ts rename to packages/reef-knot/src/headless/helpers/openWindow.ts diff --git a/packages/connect-wallet-modal/src/helpers/sortWalletsList.ts b/packages/reef-knot/src/headless/helpers/sortWalletsList.ts similarity index 98% rename from packages/connect-wallet-modal/src/helpers/sortWalletsList.ts rename to packages/reef-knot/src/headless/helpers/sortWalletsList.ts index d70b1cf0..040f04d2 100644 --- a/packages/connect-wallet-modal/src/helpers/sortWalletsList.ts +++ b/packages/reef-knot/src/headless/helpers/sortWalletsList.ts @@ -1,7 +1,7 @@ import type { ReefKnotWalletsModalConfig, WalletAdapterData, -} from '@reef-knot/types'; +} from '../../types/index'; type GetWalletsListArgs = { walletDataList: WalletAdapterData[]; diff --git a/packages/connect-wallet-modal/src/helpers/suggestApp.ts b/packages/reef-knot/src/headless/helpers/suggestApp.ts similarity index 100% rename from packages/connect-wallet-modal/src/helpers/suggestApp.ts rename to packages/reef-knot/src/headless/helpers/suggestApp.ts diff --git a/packages/connect-wallet-modal/src/helpers/validateIcon.ts b/packages/reef-knot/src/headless/helpers/validateIcon.ts similarity index 100% rename from packages/connect-wallet-modal/src/helpers/validateIcon.ts rename to packages/reef-knot/src/headless/helpers/validateIcon.ts diff --git a/packages/reef-knot/src/headless/index.ts b/packages/reef-knot/src/headless/index.ts new file mode 100644 index 00000000..b319942f --- /dev/null +++ b/packages/reef-knot/src/headless/index.ts @@ -0,0 +1,19 @@ +export { + ReefKnotUIProvider, + useWalletPicker, + useWalletConnection, + useTerms, + useEIP6963Picker, +} from './connection'; +export type { WalletPickerState } from './connection'; +export * from './eager'; +export * from './getDefaultWalletsModalConfig'; +export * from './modal/useEscape'; +export * from './modal/useInterceptFocus'; +export * from './modal/useLockScroll'; +export * from './modal/useModalFocus'; +export * from './modal/useModalClose'; +export { validateIcon, FALLBACK_WALLET_ICON } from './helpers/validateIcon'; +export * from './ledger/flow'; +export * from './renderer'; +export * from './providers'; diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerContext.tsx b/packages/reef-knot/src/headless/ledger/LedgerContext.tsx similarity index 77% rename from packages/connect-wallet-modal/src/components/Ledger/LedgerContext.tsx rename to packages/reef-knot/src/headless/ledger/LedgerContext.tsx index a9f66571..05804fe6 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerContext.tsx +++ b/packages/reef-knot/src/headless/ledger/LedgerContext.tsx @@ -10,7 +10,8 @@ import React, { } from 'react'; import type Eth from '@ledgerhq/hw-app-eth'; import type Transport from '@ledgerhq/hw-transport'; -import { helpers } from '@reef-knot/web3-react'; +import { interceptLedgerError } from '../../core-react/helpers'; +import { UserFacingError } from '../../core-react/helpers/userFacingError'; import { getTransport, isHIDSupported } from './helpers'; const USER_ACTIVATION_TIMEOUT = 3000; @@ -25,6 +26,7 @@ export interface LedgerContextProps { } export type LedgerContextValue = { + isActive: boolean; transport: MutableRefObject; ledgerAppEth: MutableRefObject; isTransportConnected: boolean; @@ -43,6 +45,8 @@ export const LedgerContextProvider = ({ isActive, children, }: LedgerContextProps) => { + const active = useRef(isActive); + active.current = isActive; const transport = useRef(null); // isTransportConnecting flag helps with react v18 strict mode in the dev mode, // which re-runs effects extra time, which breaks ledger connection process @@ -53,8 +57,6 @@ export const LedgerContextProvider = ({ const [isUserActivationRequired, setUserActivationRequired] = useState(false); const [isTransportConnected, setIsTransportConnected] = useState(false); const [isLoadingLedgerLibs, setIsLoadingLedgerLibs] = useState(false); - const [activeAccountsRequestsCounter, setActiveAccountsRequestsCounter] = - useState(0); const disconnectTransport = useCallback(async (goingToReconnect = false) => { try { @@ -62,11 +64,11 @@ export const LedgerContextProvider = ({ transport.current = null; ledgerAppEth.current = null; setUserActivationRequired(false); - if (!goingToReconnect) { - setIsTransportConnected(false); - } - } catch (e: any) { - setError(helpers.interceptLedgerError(e)); + // Keep the accounts screen while handing the device over to the connector. + // A regular disconnect resets the screen to the connection step. + if (!goingToReconnect) setIsTransportConnected(false); + } catch (e: unknown) { + setError(interceptLedgerError(e as Error)); } }, []); @@ -79,23 +81,26 @@ export const LedgerContextProvider = ({ }, []); const connectTransport = useCallback(async () => { - if (isTransportConnecting.current || transport.current) return; + if (!active.current || isTransportConnecting.current || transport.current) + return; setError(null); setUserActivationRequired(false); isTransportConnecting.current = true; if (!isHIDSupported()) { setError( - new Error( + new UserFacingError( "Your browser doesn't support direct connection with Ledger. Please, try another browser.", ), ); + isTransportConnecting.current = false; return; } try { const userActivationTime = Date.now(); await loadLedgerLibs(); + if (!active.current) return; const timePassedAfterUserActivation = Date.now() - userActivationTime; if (timePassedAfterUserActivation > USER_ACTIVATION_TIMEOUT) { @@ -103,15 +108,21 @@ export const LedgerContextProvider = ({ return; } - transport.current = await getTransport(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const acquired = await getTransport(); + if (!active.current) { + await acquired.close(); + return; + } + transport.current = acquired; + ledgerAppEth.current = new ledgerLibEth.current!(transport.current); await ledgerAppEth.current.getAppConfiguration(); - setIsTransportConnected(true); - } catch (e: any) { + if (active.current) setIsTransportConnected(true); + else await disconnectTransport(); + } catch (e: unknown) { await disconnectTransport(true); setIsLoadingLedgerLibs(false); - setError(helpers.interceptLedgerError(e)); + setError(interceptLedgerError(e as Error)); } finally { isTransportConnecting.current = false; } @@ -123,14 +134,19 @@ export const LedgerContextProvider = ({ }, [disconnectTransport, connectTransport]); useEffect(() => { + active.current = isActive; if (!isActive) return; void connectTransport(); - return () => void transport?.current?.close(); + return () => { + active.current = false; + void disconnectTransport(); + }; }, [connectTransport, disconnectTransport, isActive]); const value = useMemo( () => ({ + isActive, transport, ledgerAppEth, isTransportConnected, @@ -141,10 +157,9 @@ export const LedgerContextProvider = ({ connectTransport, disconnectTransport, reconnectTransport, - activeAccountsRequestsCounter, - setActiveAccountsRequestsCounter, }), [ + isActive, isTransportConnected, isLoadingLedgerLibs, isUserActivationRequired, @@ -152,7 +167,6 @@ export const LedgerContextProvider = ({ connectTransport, disconnectTransport, reconnectTransport, - activeAccountsRequestsCounter, ], ); diff --git a/packages/connect-wallet-modal/src/components/Ledger/constants.ts b/packages/reef-knot/src/headless/ledger/constants.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/Ledger/constants.ts rename to packages/reef-knot/src/headless/ledger/constants.ts diff --git a/packages/reef-knot/src/headless/ledger/flow.tsx b/packages/reef-knot/src/headless/ledger/flow.tsx new file mode 100644 index 00000000..df5fc822 --- /dev/null +++ b/packages/reef-knot/src/headless/ledger/flow.tsx @@ -0,0 +1,202 @@ +import React, { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { useConfig } from 'wagmi'; +import { idLedgerHid } from '@reef-knot/ledger-connector'; +import { interceptLedgerError } from '../../core-react/helpers'; +import { useReefKnotContext } from '../../core-react'; +import { AccountMismatchError, useConnectionContext } from '../connection'; +import { getConnectionErrorMessage } from '../helpers/getConnectionErrorMessage'; +import { LedgerContextProvider } from './LedgerContext'; +import { useLedgerAccounts, useLedgerContext } from './hooks'; +import { DERIVATION_PATHS } from './constants'; +import { saveLedgerDerivationPath } from './helpers'; +import type { AccountRecord, AccountsStorage } from './types'; + +export type LedgerAccount = AccountRecord; +export type LedgerFlowState = { + screen: 'connection' | 'accounts' | 'error'; + error: Error | null; + /** Safe to show to the user. The original error stays in `error`. */ + errorMessage: string | null; + isLoading: boolean; + isLoadingLedgerLibs: boolean; + isUserActivationRequired: boolean; + accounts: AccountRecord[]; + currentPage: number; + pagesCount: number; + accountsPerPage: number; + derivationPath: string; + derivationPaths: typeof DERIVATION_PATHS; + setPage: (page: number) => void; + setDerivationPath: (path: string) => void; + retry: () => Promise; + selectAccount: (account: AccountRecord) => Promise; +}; +const LedgerFlowContext = createContext(null); +const ACCOUNTS_PER_PAGE = 5; +const PAGES_COUNT = 4; + +function LedgerFlowOwner({ + children, + initialDerivationPath, + restartSession, +}: React.PropsWithChildren<{ + initialDerivationPath: string; + restartSession: (path: string) => void; +}>) { + const transport = useLedgerContext(); + const flow = useConnectionContext(); + const { walletDataList } = useReefKnotContext(); + const { chains } = useConfig(); + const [currentPage, setPage] = useState(1); + const [derivationPath, setPath] = useState(initialDerivationPath); + const [accountsStorage, setStorage] = useState({}); + // Ignore pending results once the Ledger screen is gone. + const alive = useRef(true); + useEffect(() => { + alive.current = true; + return () => { + alive.current = false; + }; + }, []); + const pageAccounts = useLedgerAccounts({ + accountsStorage, + derivationPathTemplate: derivationPath, + currentPage, + accountsPerPage: ACCOUNTS_PER_PAGE, + }); + useEffect(() => { + if (Object.keys(pageAccounts).length !== ACCOUNTS_PER_PAGE) return; + const path = Object.values(pageAccounts)[0].pathTemplate; + setStorage((old) => ({ + ...old, + [path]: { ...old[path], ...pageAccounts }, + })); + }, [pageAccounts]); + const accounts = useMemo(() => { + const first = (currentPage - 1) * ACCOUNTS_PER_PAGE; + return Array.from( + { length: ACCOUNTS_PER_PAGE }, + (_, i) => accountsStorage[derivationPath]?.[first + i], + ).filter((a): a is AccountRecord => !!a); + }, [accountsStorage, derivationPath, currentPage]); + const selectAccount = useCallback( + async (account: AccountRecord) => { + if ( + !accounts.some( + (a) => a.path === account.path && a.address === account.address, + ) + ) + return; + await flow.run(idLedgerHid, async () => { + const wallet = walletDataList.find((w) => w.walletId === idLedgerHid); + if (!wallet) return; + // The picker and connector cannot hold the same HID device at once. + // Release the picker transport, but keep its screen during the switch. + await transport.disconnectTransport(true); + try { + await flow.connectConnector(wallet.createConnectorFn, { + beforeConnect: () => saveLedgerDerivationPath(account.path), + expectedAddress: account.address, + }); + if (!alive.current) return; + await flow.completeConnection(wallet.walletId); + } catch (e) { + if (!alive.current) return; + if (e instanceof AccountMismatchError) { + // The cached list may belong to a different device. Read it again + // so the next selection uses accounts from the current Ledger. + restartSession(derivationPath); + return; + } + transport.setError(interceptLedgerError(e as Error)); + } + }); + }, + [accounts, flow, walletDataList, transport, restartSession, derivationPath], + ); + const value: LedgerFlowState = { + screen: transport.error + ? 'error' + : transport.isTransportConnected + ? 'accounts' + : 'connection', + error: transport.error, + errorMessage: transport.error + ? getConnectionErrorMessage(transport.error, chains) + : null, + isLoading: + flow.busy || + (transport.isTransportConnected && accounts.length < ACCOUNTS_PER_PAGE), + isLoadingLedgerLibs: transport.isLoadingLedgerLibs, + isUserActivationRequired: transport.isUserActivationRequired, + accounts, + currentPage, + pagesCount: PAGES_COUNT, + accountsPerPage: ACCOUNTS_PER_PAGE, + derivationPath, + derivationPaths: DERIVATION_PATHS, + setPage: (page) => { + if (Number.isInteger(page) && page >= 1 && page <= PAGES_COUNT) + setPage(page); + }, + setDerivationPath: (path) => { + if (DERIVATION_PATHS.some((p) => p.template === path)) { + setPath(path); + setPage(1); + } + }, + retry: async () => { + // The device may have changed after the error. Retrying only the transport + // would reuse addresses still cached by LedgerFlowOwner. + await transport.disconnectTransport(); + // A failed close leaves the transport in place and exposes its error. + if (alive.current && !transport.transport.current) + restartSession(derivationPath); + }, + selectAccount, + }; + return ( + + {children} + + ); +} + +export function ReefKnotLedgerProvider({ + children, + isActive = true, +}: React.PropsWithChildren<{ isActive?: boolean }>) { + const [session, setSession] = useState({ + id: 0, + path: DERIVATION_PATHS[0].template, + }); + const restartSession = useCallback((path: string) => { + setSession((previous) => ({ id: previous.id + 1, path })); + }, []); + // Remount both owners so old reads cannot refill the account cache. + // Keep the chosen path template, but load a fresh list from the first page. + return ( + + + {children} + + + ); +} + +export function useLedgerFlow(): LedgerFlowState { + const value = useContext(LedgerFlowContext); + if (!value) throw new Error('useLedgerFlow requires ReefKnotLedgerProvider.'); + return value; +} diff --git a/packages/connect-wallet-modal/src/components/Ledger/helpers.ts b/packages/reef-knot/src/headless/ledger/helpers.ts similarity index 59% rename from packages/connect-wallet-modal/src/components/Ledger/helpers.ts rename to packages/reef-knot/src/headless/ledger/helpers.ts index 3607daf0..b24cf955 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/helpers.ts +++ b/packages/reef-knot/src/headless/ledger/helpers.ts @@ -1,7 +1,5 @@ import type Transport from '@ledgerhq/hw-transport'; import { LS_KEY_DERIVATION_PATH } from '@reef-knot/ledger-connector'; -import { LedgerContextValue } from './LedgerContext'; -import { DERIVATION_PATHS } from './constants'; // The explicit annotation keeps the return type from being inferred through // a potentially nested copy of @ledgerhq/hw-transport (TS2742). @@ -11,19 +9,13 @@ export const getTransport = async (): Promise => { await import('@ledgerhq/hw-transport-webhid') ).default.create(); } catch (e) { - throw new Error('Connection error'); + throw new Error('Connection error', { cause: e }); } }; export const saveLedgerDerivationPath = (path: string) => { - window?.localStorage.setItem(LS_KEY_DERIVATION_PATH, JSON.stringify(path)); -}; - -export const loadLedgerDerivationPath = () => { - if (typeof window === 'undefined') { - return DERIVATION_PATHS[0].template; - } - return window.localStorage.getItem(LS_KEY_DERIVATION_PATH); + if (typeof window === 'undefined') return; + window.localStorage.setItem(LS_KEY_DERIVATION_PATH, JSON.stringify(path)); }; export const getDerivationPathsForPage = ( @@ -39,19 +31,13 @@ export const getDerivationPathsForPage = ( return result; }; -export const isDeviceBusy = (transport: LedgerContextValue['transport']) => { - // _appAPIlock is a flag, used in the @ledgerhq/hw-transport library for indication if a Ledger device is busy - // returns the name of the request, which was being processed, or null or undefined - return transport.current?._appAPIlock; -}; - export const getFirstIndexOnPage = (page: number, accountsPerPage: number) => accountsPerPage * (page - 1); export const isHIDSupported = () => { try { return 'hid' in window.navigator; - } catch (error) { + } catch { return false; } }; diff --git a/packages/connect-wallet-modal/src/components/Ledger/hooks.ts b/packages/reef-knot/src/headless/ledger/hooks.ts similarity index 72% rename from packages/connect-wallet-modal/src/components/Ledger/hooks.ts rename to packages/reef-knot/src/headless/ledger/hooks.ts index a05c3ead..e5476bbf 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/hooks.ts +++ b/packages/reef-knot/src/headless/ledger/hooks.ts @@ -1,15 +1,12 @@ -import { useCallback, useContext, useEffect, useState } from 'react'; +import { useCallback, useContext, useEffect, useRef, useState } from 'react'; import { useConfig } from 'wagmi'; import { getBalance } from 'wagmi/actions'; import { LedgerContext } from './LedgerContext'; import { AccountRecord, AccountsStorage } from './types'; -import { - getDerivationPathsForPage, - getFirstIndexOnPage, - isDeviceBusy, -} from './helpers'; +import { getDerivationPathsForPage, getFirstIndexOnPage } from './helpers'; import { TransportError } from '@ledgerhq/hw-transport'; -import { formatBalance } from '../../helpers/formatBalance'; +import { formatBalance } from '../helpers/formatBalance'; +import { UserFacingError } from '../../core-react/helpers/userFacingError'; export const useLedgerContext = () => useContext(LedgerContext); @@ -26,18 +23,18 @@ export const useLedgerAccounts = ({ currentPage, accountsPerPage, }: LedgerAccountsHookParams) => { - const { ledgerAppEth, connectTransport, transport, setError } = + const { ledgerAppEth, isActive, isTransportConnected, setError } = useLedgerContext(); const config = useConfig(); + const pending = useRef>(Promise.resolve()); const [accounts, setAccounts] = useState>({}); const getAccountRecords = useCallback( - async (params: LedgerAccountsHookParams) => { + async (params: LedgerAccountsHookParams, isCurrent: () => boolean) => { const eth = ledgerAppEth?.current; - // getAccountRecords can be called several times during renders in a short amount of time. - // Multiple parallel requests to Ledger results into an error, so there is a check if a device is busy or not. - if (isDeviceBusy(transport) || !eth) return; + // The owner serializes pages and drops work for screens that have closed. + if (!eth || !isCurrent()) return; const derivationPaths = getDerivationPathsForPage( params.derivationPathTemplate, @@ -55,7 +52,7 @@ export const useLedgerAccounts = ({ accountRecords.push({ index, path, - pathTemplate: derivationPathTemplate, + pathTemplate: params.derivationPathTemplate, address, balance: Number(formatBalance(value)), token: symbol, @@ -67,6 +64,7 @@ export const useLedgerAccounts = ({ // Ledger may become busy during these iterations. // For example, if a user quickly changes pages, there will be several conflicting getAccountRecords requests, // each calling its own cycle of getAddress requests, each of them makes a ledger device busy for a short amount of time. + if (!isCurrent()) return; try { await getAndPushAccount(index, path); } catch (transportErr) { @@ -79,6 +77,7 @@ export const useLedgerAccounts = ({ await new Promise((resolve) => setTimeout(resolve, ATTEMPT_TIMEOUT), ); + if (!isCurrent()) return; try { await getAndPushAccount(index, path); break; @@ -98,25 +97,30 @@ export const useLedgerAccounts = ({ return accountRecords; }, - [derivationPathTemplate, ledgerAppEth, transport, config], + [ledgerAppEth, config], ); useEffect(() => { - void (async () => { - await connectTransport(); - setAccounts({}); + let active = true; + if (!isActive || !isTransportConnected) return; + setAccounts({}); + pending.current = pending.current.then(async () => { + if (!active) return; try { const accountIndex = getFirstIndexOnPage(currentPage, accountsPerPage); if (!accountsStorage?.[derivationPathTemplate]?.[accountIndex]) { // Accounts Storage has no record for the first account on the current page, // so we can assume, that accounts for the page were not loaded and cached before, and we need to load them. - const accountRecords = await getAccountRecords({ - accountsStorage, - derivationPathTemplate, - currentPage, - accountsPerPage, - }); - if (accountRecords?.length) { + const accountRecords = await getAccountRecords( + { + accountsStorage, + derivationPathTemplate, + currentPage, + accountsPerPage, + }, + () => active, + ); + if (active && accountRecords?.length) { setAccounts( accountRecords.reduce( (records, account) => ({ @@ -128,19 +132,25 @@ export const useLedgerAccounts = ({ ); } } - } catch (e) { - console.error(e); + } catch (error) { + console.error(error); + if (!active) return; setError( - new Error( + new UserFacingError( 'An error occurred while loading accounts data. Please, try again.', + { cause: error }, ), ); } - })(); + }); + return () => { + active = false; + }; }, [ accountsPerPage, accountsStorage, - connectTransport, + isActive, + isTransportConnected, currentPage, derivationPathTemplate, getAccountRecords, diff --git a/packages/connect-wallet-modal/src/components/Ledger/types.ts b/packages/reef-knot/src/headless/ledger/types.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/Ledger/types.ts rename to packages/reef-knot/src/headless/ledger/types.ts diff --git a/packages/ui-react/src/components/modal/constants.ts b/packages/reef-knot/src/headless/modal/constants.ts similarity index 100% rename from packages/ui-react/src/components/modal/constants.ts rename to packages/reef-knot/src/headless/modal/constants.ts diff --git a/packages/ui-react/src/hooks/useEscape.ts b/packages/reef-knot/src/headless/modal/useEscape.ts similarity index 86% rename from packages/ui-react/src/hooks/useEscape.ts rename to packages/reef-knot/src/headless/modal/useEscape.ts index 3433a574..c320836b 100644 --- a/packages/ui-react/src/hooks/useEscape.ts +++ b/packages/reef-knot/src/headless/modal/useEscape.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect } from 'react'; export const useEscape = (callback?: () => void): void => { const handleKeyDown = useCallback( (event: KeyboardEvent) => { - if (event.key === 'Escape') { + if (event.key === 'Escape' && !event.defaultPrevented) { callback?.(); } }, diff --git a/packages/ui-react/src/hooks/useInterceptFocus.ts b/packages/reef-knot/src/headless/modal/useInterceptFocus.ts similarity index 100% rename from packages/ui-react/src/hooks/useInterceptFocus.ts rename to packages/reef-knot/src/headless/modal/useInterceptFocus.ts diff --git a/packages/reef-knot/src/headless/modal/useLockScroll.ts b/packages/reef-knot/src/headless/modal/useLockScroll.ts new file mode 100644 index 00000000..029b75e5 --- /dev/null +++ b/packages/reef-knot/src/headless/modal/useLockScroll.ts @@ -0,0 +1,110 @@ +import { useCallback, useLayoutEffect } from 'react'; + +const getScrollbarSize = (): number => { + const tempDiv = document.createElement('div'); + + Object.assign(tempDiv.style, { + position: 'absolute', + left: '-9000px', + width: '100px', + height: '100px', + overflow: 'scroll', + }); + + document.body.appendChild(tempDiv); + const scrollbarSize = tempDiv.offsetWidth - tempDiv.clientWidth; + document.body.removeChild(tempDiv); + + return scrollbarSize; +}; + +const isVerticalScroll = (element: HTMLElement): boolean => { + const isBody = document.body === element; + + return isBody + ? document.documentElement.scrollHeight > window.innerHeight + : element.scrollHeight > element.clientHeight; +}; + +const getPaddingRight = (element: HTMLElement): number => { + return parseInt(window.getComputedStyle(element).paddingRight, 10) || 0; +}; + +const setStyleProperty = ( + element: HTMLElement, + property: string, + value?: string, +): void => { + if (value) { + element.style.setProperty(property, value); + } else { + element.style.removeProperty(property); + } +}; + +// Save the old inline values, so the unlock step can return them. +const setStyles = ( + element: HTMLElement, + styles: Record, +): (() => void) => { + const previous = Object.keys(styles).map( + (property) => [property, element.style.getPropertyValue(property)] as const, + ); + Object.entries(styles).forEach(([property, value]) => + setStyleProperty(element, property, value), + ); + return () => + previous.forEach(([property, value]) => + setStyleProperty(element, property, value), + ); +}; + +const isTouchDevice = (): boolean => + typeof navigator !== 'undefined' && navigator.maxTouchPoints > 0; + +// iOS Safari ignores `overflow: hidden` on body. +// The page scrolls on touch and when the keyboard opens. +// A fixed body cannot scroll. Keep the scroll position in `top` and restore it on unlock. +const pinBody = (): (() => void) => { + const { scrollX, scrollY } = window; + const unlockHtml = setStyles(document.documentElement, { + overflow: 'hidden', + }); + const unlockBody = setStyles(document.body, { + position: 'fixed', + top: `-${scrollY}px`, + left: '0', + right: '0', + }); + + return () => { + unlockBody(); + unlockHtml(); + window.scrollTo({ left: scrollX, top: scrollY, behavior: 'instant' }); + }; +}; + +export const useLockScroll = (element?: HTMLElement): void => { + const lockScroll = useCallback(() => { + const target = + element ?? (typeof document === 'undefined' ? undefined : document.body); + if (!target || !isVerticalScroll(target)) return; + + const unlockTarget = setStyles(target, { + 'padding-right': `${getPaddingRight(target) + getScrollbarSize()}px`, + overflow: 'hidden', + }); + if (target !== document.body || !isTouchDevice()) return unlockTarget; + + const unpinBody = pinBody(); + return () => { + unlockTarget(); + unpinBody(); + }; + }, [element]); + + useLayoutEffect(() => { + const unlockScroll = lockScroll(); + return unlockScroll; + }, [lockScroll]); +}; diff --git a/packages/ui-react/src/components/modal/useModalClose.ts b/packages/reef-knot/src/headless/modal/useModalClose.ts similarity index 71% rename from packages/ui-react/src/components/modal/useModalClose.ts rename to packages/reef-knot/src/headless/modal/useModalClose.ts index a27a6e99..c3c95560 100644 --- a/packages/ui-react/src/components/modal/useModalClose.ts +++ b/packages/reef-knot/src/headless/modal/useModalClose.ts @@ -1,8 +1,8 @@ -import React from 'react'; -import { useCallback, useRef } from 'react'; +import React, { useCallback, useRef } from 'react'; export const useModalClose = ( callback?: () => void, + ignoreOutside?: (target: Element) => boolean, ): { ref: React.RefObject; handleClick: (event: React.MouseEvent) => void; @@ -16,11 +16,14 @@ export const useModalClose = ( if (!contentElement) return; if (!(event.target instanceof Node)) return; + if (event.target instanceof Element && ignoreOutside?.(event.target)) + return; + if (contentElement.contains(event.target)) return; callback?.(); }, - [callback], + [callback, ignoreOutside], ); return { diff --git a/packages/ui-react/src/components/modal/useModalFocus.ts b/packages/reef-knot/src/headless/modal/useModalFocus.ts similarity index 54% rename from packages/ui-react/src/components/modal/useModalFocus.ts rename to packages/reef-knot/src/headless/modal/useModalFocus.ts index 5260b648..752e9427 100644 --- a/packages/ui-react/src/components/modal/useModalFocus.ts +++ b/packages/reef-knot/src/headless/modal/useModalFocus.ts @@ -1,20 +1,33 @@ -import React from 'react'; -import { useCallback, useEffect, useRef } from 'react'; -import { useInterceptFocus } from '../../hooks'; +import React, { useCallback, useEffect, useRef } from 'react'; +import { useInterceptFocus } from './useInterceptFocus'; import { FOCUSABLE_ELEMENTS } from './constants'; -export const useModalFocus = (): React.RefObject => { +export const useModalFocus = (options?: { + getAdditionalContainers?: () => HTMLElement[]; +}): React.RefObject => { + const getAdditionalContainers = options?.getAdditionalContainers; const modalRef = useRef(null); const getFocusableNodes = useCallback(() => { - const nodes = - modalRef.current?.querySelectorAll(FOCUSABLE_ELEMENTS.join(',')) ?? []; + const containers = [ + modalRef.current, + ...(getAdditionalContainers?.() ?? []), + ]; + const nodes = containers.flatMap((container) => + Array.from( + container?.querySelectorAll(FOCUSABLE_ELEMENTS.join(',')) ?? [], + ), + ); return Array.from(nodes).filter( (node): node is HTMLElement => - node && node instanceof HTMLElement && node.offsetParent !== null, + node && + node instanceof HTMLElement && + node.offsetParent !== null && + !node.matches(':disabled') && + !node.closest('[aria-hidden="true"], [inert]'), ); - }, []); + }, [getAdditionalContainers]); const handleRetainFocus = useCallback( (event: KeyboardEvent) => { @@ -27,7 +40,10 @@ export const useModalFocus = (): React.RefObject => { currentElement instanceof HTMLElement && focusableNodes.indexOf(currentElement); - if (event.shiftKey && focusedItemIndex === 0) { + if ( + event.shiftKey && + (focusedItemIndex === 0 || focusedItemIndex === -1) + ) { focusableNodes[focusableNodes.length - 1].focus(); event.preventDefault(); } @@ -35,7 +51,8 @@ export const useModalFocus = (): React.RefObject => { if ( !event.shiftKey && focusableNodes.length > 0 && - focusedItemIndex === focusableNodes.length - 1 + (focusedItemIndex === focusableNodes.length - 1 || + focusedItemIndex === -1) ) { focusableNodes[0].focus(); event.preventDefault(); @@ -46,7 +63,11 @@ export const useModalFocus = (): React.RefObject => { useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { - if (event.code === 'Tab') handleRetainFocus(event); + if ( + (event.code === 'Tab' || event.key === 'Tab') && + !event.defaultPrevented + ) + handleRetainFocus(event); }; document.addEventListener('keydown', handleKeyDown); diff --git a/packages/reef-knot/src/headless/providers.ts b/packages/reef-knot/src/headless/providers.ts new file mode 100644 index 00000000..8060cb05 --- /dev/null +++ b/packages/reef-knot/src/headless/providers.ts @@ -0,0 +1,11 @@ +import { useMemo } from 'react'; +import { useEIP6963Providers, useReefKnotContext } from '../core-react'; + +export function useEIP6963ProvidersWithoutAdapters() { + const { walletDataList } = useReefKnotContext(); + const providers = useEIP6963Providers(); + return useMemo(() => { + const known = new Set(walletDataList.map((wallet) => wallet.rdns)); + return providers.filter((provider) => !known.has(provider.info.rdns)); + }, [walletDataList, providers]); +} diff --git a/packages/reef-knot/src/headless/renderer.tsx b/packages/reef-knot/src/headless/renderer.tsx new file mode 100644 index 00000000..3d6263fb --- /dev/null +++ b/packages/reef-knot/src/headless/renderer.tsx @@ -0,0 +1,165 @@ +import React from 'react'; +import { useReefKnotModal } from '../core-react'; +import type { + ModalStateEntry, + ReefKnotModalContextValue, +} from '../core-react/context/reefKnotModalContext'; +import type { ModalContainerProps } from '../types/ui'; +import { ReefKnotUIProvider, useConnectionContext } from './connection'; +import { ReefKnotLedgerProvider } from './ledger/flow'; +import { + WalletPicker, + type WalletPickerProps, +} from './components/WalletPicker'; +import { EagerConnect } from './components/EagerConnect'; +import { EIP6963Picker } from './components/EIP6963Picker'; +import { Ledger } from './components/Ledger'; + +export type ReefKnotModalRendererProps = WalletPickerProps & { + containerProps?: Partial; +}; + +type ModalPresentation = { + body: React.ReactNode; + containerProps: Pick< + ModalContainerProps, + | 'title' + | 'widthClamp' + | 'center' + | 'omitContentStyle' + | 'onClose' + | 'onBack' + >; +}; + +/** Keeps each screen's content and container/navigation settings together. */ +function getModalPresentation( + modal: ModalStateEntry, + props: ReefKnotModalRendererProps, + { goBack, forceCloseAllModals }: ReefKnotModalContextValue, +): ModalPresentation { + const { components, theme } = props; + const defaults = { + widthClamp: 480, + center: false, + omitContentStyle: false, + onClose: forceCloseAllModals, + onBack: goBack, + }; + + switch (modal.type) { + case 'wallet': + return { + body: , + containerProps: { + ...defaults, + title: 'Connect wallet', + widthClamp: 660, + omitContentStyle: true, + onBack: undefined, + }, + }; + case 'eager': + return { + body: , + containerProps: { + ...defaults, + title: 'Confirm connection', + onClose: undefined, + onBack: undefined, + }, + }; + case 'eip6963': + return { + body: , + containerProps: { + ...defaults, + title: 'Connect wallet', + widthClamp: 660, + omitContentStyle: true, + }, + }; + case 'ledger': + return { + body: ( + + + + ), + containerProps: { + ...defaults, + title: 'Ledger connect', + // Ledger views have their own width. A wider container moves them off center. + widthClamp: undefined, + }, + }; + case 'requirements': + return { + body: , + containerProps: { + ...defaults, + title: modal.props.title, + center: true, + }, + }; + } +} + +/** + * Renders the active screen in the supplied container. Screen-specific settings take + * precedence over caller defaults; portal and focus mechanics belong to the container. + */ +function Renderer(props: ReefKnotModalRendererProps) { + const { components, theme, containerProps } = props; + const modal = useReefKnotModal(); + const { currentModal, forceCloseAllModals } = modal; + const { error, errorMessage, dismissError } = useConnectionContext(); + if (!currentModal) return null; + + // Replace the view, keeping the underlying picker and modal stack intact. + const hasConnectionError = + error && + errorMessage && + (currentModal.type === 'wallet' || currentModal.type === 'eip6963'); + const presentation: ModalPresentation = hasConnectionError + ? { + body: ( + + ), + containerProps: { + title: 'Couldn’t connect', + center: true, + omitContentStyle: false, + widthClamp: 480, + onBack: dismissError, + onClose: forceCloseAllModals, + }, + } + : getModalPresentation(currentModal, props, modal); + return ( + + {presentation.body} + + ); +} + +/** + * Optional composition layer for UI skins and custom interfaces. Provides + * shared headless state from config and renders only caller-supplied views. + */ +export function ReefKnotModalRenderer(props: ReefKnotModalRendererProps) { + return ( + + + + ); +} diff --git a/packages/reef-knot/src/index.ts b/packages/reef-knot/src/index.ts index 7dfd70d4..f36e2ffc 100644 --- a/packages/reef-knot/src/index.ts +++ b/packages/reef-knot/src/index.ts @@ -1,6 +1,6 @@ -export * as ConnectWalletModal from './packages/connect-wallet-modal'; -export * as Web3React from './packages/web3-react'; -export * as UIReact from './packages/ui-react'; -export * as CoreReact from './packages/core-react'; -export * as WalletsList from './packages/wallets'; -export * as Connectors from './packages/connectors'; +export * from './core-react'; +export * from './headless'; +export * from './types'; +export * from './wallets-list'; +export * from '@reef-knot/ledger-connector'; +export * from '@reef-knot/wallets-helpers'; diff --git a/packages/reef-knot/src/packages/connect-wallet-modal.ts b/packages/reef-knot/src/packages/connect-wallet-modal.ts deleted file mode 100644 index 31de94ab..00000000 --- a/packages/reef-knot/src/packages/connect-wallet-modal.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/connect-wallet-modal'; diff --git a/packages/reef-knot/src/packages/connectors.ts b/packages/reef-knot/src/packages/connectors.ts deleted file mode 100644 index 4935b1ef..00000000 --- a/packages/reef-knot/src/packages/connectors.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/ledger-connector'; diff --git a/packages/reef-knot/src/packages/core-react.ts b/packages/reef-knot/src/packages/core-react.ts deleted file mode 100644 index 35dbdb26..00000000 --- a/packages/reef-knot/src/packages/core-react.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/core-react'; diff --git a/packages/reef-knot/src/packages/types.ts b/packages/reef-knot/src/packages/types.ts deleted file mode 100644 index a2dbcb7a..00000000 --- a/packages/reef-knot/src/packages/types.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/types'; diff --git a/packages/reef-knot/src/packages/ui-react.ts b/packages/reef-knot/src/packages/ui-react.ts deleted file mode 100644 index 46742dd8..00000000 --- a/packages/reef-knot/src/packages/ui-react.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/ui-react'; diff --git a/packages/reef-knot/src/packages/wallets.ts b/packages/reef-knot/src/packages/wallets.ts deleted file mode 100644 index 9302457d..00000000 --- a/packages/reef-knot/src/packages/wallets.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/wallets-list'; diff --git a/packages/reef-knot/src/packages/web3-react.ts b/packages/reef-knot/src/packages/web3-react.ts deleted file mode 100644 index c711f65a..00000000 --- a/packages/reef-knot/src/packages/web3-react.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@reef-knot/web3-react'; diff --git a/packages/reef-knot/src/types/index.ts b/packages/reef-knot/src/types/index.ts new file mode 100644 index 00000000..4d61a707 --- /dev/null +++ b/packages/reef-knot/src/types/index.ts @@ -0,0 +1,10 @@ +export * from './reef-knot-wallets-modal'; +export * from './reef-knot-config'; +export * from './ui'; +export type { + WalletAdapterArgs, + WalletAdapterData, + WalletAdapterIcons, + WalletAdapterType, +} from '@reef-knot/wallets-helpers'; +export type { Connector, CreateConnectorFn } from 'wagmi'; diff --git a/packages/types/src/reef-knot-config.ts b/packages/reef-knot/src/types/reef-knot-config.ts similarity index 85% rename from packages/types/src/reef-knot-config.ts rename to packages/reef-knot/src/types/reef-knot-config.ts index 3f7ce199..e4600d61 100644 --- a/packages/types/src/reef-knot-config.ts +++ b/packages/reef-knot/src/types/reef-knot-config.ts @@ -1,4 +1,4 @@ -import { WalletAdapterData } from './walletAdapter'; +import type { WalletAdapterData } from '@reef-knot/wallets-helpers'; export type ReefKnotProviderConfig = { autoConnect: boolean; diff --git a/packages/reef-knot/src/types/reef-knot-wallets-modal.ts b/packages/reef-knot/src/types/reef-knot-wallets-modal.ts new file mode 100644 index 00000000..c67ec2eb --- /dev/null +++ b/packages/reef-knot/src/types/reef-knot-wallets-modal.ts @@ -0,0 +1,12 @@ +export type ReefKnotWalletsModalConfig = { + walletsShown: I[]; + walletsPinned: I[]; + walletsDisplayInitialCount?: number; + linkTerms?: string; + linkPrivacyNotice?: string; + onConnectStart?(this: void, args: { walletId: I }): void; + onConnectSuccess?(this: void, args: { walletId: I; rdns?: string }): void; + onClickTermsAccept?: (args: { isAccepted: boolean }) => void; + onClickWalletsMore?: () => void; + onClickWalletsLess?: () => void; +}; diff --git a/packages/reef-knot/src/types/ui.ts b/packages/reef-knot/src/types/ui.ts new file mode 100644 index 00000000..b0162f89 --- /dev/null +++ b/packages/reef-knot/src/types/ui.ts @@ -0,0 +1,84 @@ +import type { ComponentType, HTMLAttributes, ReactNode } from 'react'; +import type { RequirementsData, EIP6963ProviderDetail } from '../core-react'; +import type { WalletAdapterData } from '@reef-knot/wallets-helpers'; +import type { WalletPickerState } from '../headless/connection'; +import type { useEagerConnectScreen } from '../headless/eager'; +import type { LedgerFlowState } from '../headless/ledger/flow'; + +export type ReefKnotTheme = 'light' | 'dark'; +export type ModalContainerProps = Omit< + HTMLAttributes, + 'title' +> & { + title?: ReactNode; + titleIcon?: ReactNode; + subtitle?: ReactNode; + open?: boolean; + theme?: ReefKnotTheme; + onClose?: () => void; + onBack?: () => void; + onExited?: () => void; + widthClamp?: number; + center?: boolean; + omitContentStyle?: boolean; + clampHeightByWindow?: boolean; + stretchHeightByWindow?: boolean; +}; +export type WalletButtonViewProps = { + walletId?: string; + name: string; + icon?: WalletAdapterData['icon']; + iconUrl?: string; + theme?: ReefKnotTheme; + compact?: boolean; + disabled: boolean; + isLoading: boolean; + onConnect: () => void; +}; +export type TermsViewProps = { + checked: boolean; + linkTerms?: string; + linkPrivacyNotice?: string; + onChange: (checked: boolean) => void; +}; +export type WalletPickerViewProps = { + state: WalletPickerState; + children?: ReactNode; + terms: ReactNode; + theme?: ReefKnotTheme; + buttonsFullWidth?: boolean; +}; +export type EagerConnectViewProps = { + state: ReturnType; + terms: ReactNode; +}; +export type RequirementsViewProps = { requirements: RequirementsData }; +export type ConnectionErrorViewProps = { + error: Error; + /** Safe to show to the user. Unknown errors get a generic message. */ + errorMessage: string; + /** Returns to the wallet list. The container also gets it as its Back action. */ + onBack: () => void; +}; +export type EIP6963PickerViewProps = { + providers: readonly EIP6963ProviderDetail[]; + terms: ReactNode; + children?: ReactNode; + error?: Error | null; + /** Safe to show to the user. Show it instead of `error.message`. */ + errorMessage?: string | null; +}; +export type LedgerViewProps = { state: LedgerFlowState }; +export type ReefKnotUIComponents = { + ModalContainer: ComponentType; + WalletButton: ComponentType; + Terms: ComponentType; + WalletPicker: ComponentType; + EagerConnect: ComponentType; + Requirements: ComponentType; + ConnectionError: ComponentType; + EIP6963Picker: ComponentType; + LedgerConnection: ComponentType; + LedgerAccounts: ComponentType; + LedgerError: ComponentType; +}; diff --git a/packages/wallets-list/src/ethereum.ts b/packages/reef-knot/src/wallets-list/ethereum.ts similarity index 100% rename from packages/wallets-list/src/ethereum.ts rename to packages/reef-knot/src/wallets-list/ethereum.ts diff --git a/packages/wallets-list/src/index.ts b/packages/reef-knot/src/wallets-list/index.ts similarity index 100% rename from packages/wallets-list/src/index.ts rename to packages/reef-knot/src/wallets-list/index.ts diff --git a/packages/reef-knot/test-ui/suite.tsx b/packages/reef-knot/test-ui/suite.tsx new file mode 100644 index 00000000..57bbe368 --- /dev/null +++ b/packages/reef-knot/test-ui/suite.tsx @@ -0,0 +1,488 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest'; +import { mainnet } from 'viem/chains'; +import type { CreateConnectorFn } from 'wagmi'; +import { + BaseError, + UnauthorizedProviderError, + UserRejectedRequestError, +} from 'viem'; +import { + ReefKnotProvider, + useReefKnotModal, + type ReefKnotUIComponents, + type LedgerViewProps, + type ReefKnotWalletsModalConfig, + type WalletAdapterData, +} from 'reef-knot'; + +const GENERIC_ERROR = 'Connection error. Please try again.'; +const mocks = vi.hoisted(() => ({ + connect: vi.fn<(...args: unknown[]) => Promise>(), + setItem: vi.fn(), + state: { + status: 'disconnected', + current: null as string | null, + connections: new Map(), + }, +})); +vi.mock('wagmi', async (importOriginal) => ({ + ...(await importOriginal()), + useConfig: () => ({ + chains: [mainnet], + storage: { setItem: mocks.setItem, removeItem: vi.fn() }, + state: mocks.state, + }), + useConnect: () => ({ + mutateAsync: async ({ connector }: { connector: CreateConnectorFn }) => { + const uid = 'selected'; + const instance = connector({ + emitter: { uid }, + chains: [mainnet], + providers: [], + } as unknown as Parameters[0]); + const result = await mocks.connect({ connector }); + mocks.state.status = 'connected'; + mocks.state.current = uid; + mocks.state.connections.set(uid, { + connector: { id: instance.id ?? 'metaMask', uid }, + }); + return result; + }, + }), + useConnection: () => ({ isConnected: false }), + useDisconnect: () => ({ mutate: vi.fn(), mutateAsync: vi.fn() }), +})); +type TestModalProps = { + config: ReefKnotWalletsModalConfig; + components?: Partial; + dark: boolean; +}; +export function runUISuite( + Modal: React.ComponentType, + wrap: (children: React.ReactNode, dark: boolean) => React.ReactNode = ( + children, + ) => children, + LedgerAccounts?: React.ComponentType, +) { + let root: Root; + let container: HTMLDivElement; + let modal: ReturnType; + function Probe() { + modal = useReefKnotModal(); + return null; + } + async function mount( + dark = false, + components?: Partial, + onConnectSuccess = vi.fn(), + ) { + const config: ReefKnotWalletsModalConfig = { + walletsShown: ['metaMask'], + walletsPinned: [], + linkTerms: 'https://example.com/terms', + linkPrivacyNotice: 'https://example.com/privacy', + onConnectSuccess, + }; + const wallet: WalletAdapterData = { + walletId: 'metaMask', + walletName: 'MetaMask', + type: 'injected', + createConnectorFn: + (() => ({})) as unknown as WalletAdapterData['createConnectorFn'], + }; + await act(async () => + root.render( + wrap( + + + + , + dark, + ), + ), + ); + await act(async () => modal.openModal({ type: 'wallet' })); + return onConnectSuccess; + } + beforeEach(() => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + vi.clearAllMocks(); + mocks.connect.mockResolvedValue({}); + mocks.state.status = 'disconnected'; + mocks.state.current = null; + mocks.state.connections.clear(); + localStorage.clear(); + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); + }); + afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); + document.getElementById('reef-knot-modal-root')?.replaceChildren(); + }); + const walletButton = () => + Array.from(document.querySelectorAll('button')).find((b) => + b.textContent?.includes('MetaMask'), + )!; + const headerButton = (label: 'Go back' | 'Close') => + document.querySelector( + `[role="dialog"] button[aria-label="${label}"]`, + )!; + const acceptTerms = () => + act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + describe.each([false, true])('adapter scenarios (dark=%s)', (dark) => { + it('renders a gated picker, accepts Terms and connects once', async () => { + const success = await mount(dark); + expect(document.querySelector('[role="dialog"]')).not.toBeNull(); + expect(walletButton().disabled).toBe(true); + await act(async () => { + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(); + }); + expect(walletButton().disabled).toBe(false); + await act(async () => walletButton().click()); + expect(mocks.connect).toHaveBeenCalledOnce(); + expect(success).toHaveBeenCalledOnce(); + expect(modal.modalStack).toHaveLength(0); + }); + it('renders connection errors and supports retry', async () => { + mocks.connect.mockRejectedValueOnce(new Error('Connection failed')); + await mount(dark); + await acceptTerms(); + await act(async () => walletButton().click()); + expect(document.querySelector('[role="alert"]')?.textContent).toContain( + GENERIC_ERROR, + ); + expect(modal.currentModal?.type).toBe('wallet'); + expect(walletButton()).toBeUndefined(); + expect(document.querySelector('[role="alert"] button')).toBeNull(); + expect(document.querySelector('[role="dialog"]')?.textContent).toContain( + 'Couldn’t connect', + ); + await act(async () => headerButton('Go back').click()); + expect(walletButton().disabled).toBe(false); + expect(document.querySelector('[role="alert"]')).toBeNull(); + await act(async () => walletButton().click()); + expect(modal.modalStack).toHaveLength(0); + }); + it('closes the whole modal from the error screen', async () => { + mocks.connect.mockRejectedValueOnce(new Error('Connection failed')); + await mount(dark); + await acceptTerms(); + await act(async () => walletButton().click()); + expect(document.querySelector('[role="alert"]')).not.toBeNull(); + await act(async () => headerButton('Close').click()); + expect(modal.modalStack).toHaveLength(0); + }); + it('keeps the picker without an error when the user rejects in the wallet', async () => { + mocks.connect.mockRejectedValueOnce( + new UserRejectedRequestError(new Error('User rejected the request.')), + ); + await mount(dark); + await acceptTerms(); + await act(async () => walletButton().click()); + expect(document.querySelector('[role="alert"]')).toBeNull(); + expect(modal.currentModal?.type).toBe('wallet'); + expect(walletButton().disabled).toBe(false); + }); + it('hides the text of an unknown error', async () => { + mocks.connect.mockRejectedValueOnce( + new BaseError('Connection declined', { + details: 'Technical RPC details', + }), + ); + await mount(dark); + await act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + await act(async () => walletButton().click()); + const alert = document.querySelector('[role="alert"]')?.textContent; + expect(alert).toContain(GENERIC_ERROR); + expect(alert).not.toContain('Connection declined'); + expect(alert).not.toContain('Technical RPC details'); + }); + it('displays a prepared message for a known wallet error', async () => { + mocks.connect.mockRejectedValueOnce( + new UnauthorizedProviderError(new Error('Technical RPC details')), + ); + await mount(dark); + await acceptTerms(); + await act(async () => walletButton().click()); + const alert = document.querySelector('[role="alert"]')?.textContent; + expect(alert).toContain('did not authorize this site'); + expect(alert).not.toContain('Technical RPC details'); + }); + it('preserves picker search, expansion and consent after an error', async () => { + mocks.connect.mockRejectedValueOnce(new Error('Connection failed')); + const success = await mount(dark, { + WalletPicker: ({ state, terms, children }) => ( + <> + {terms} + + {state.search}:{String(state.expanded)} + + + {children} + + ), + }); + await act(async () => + Array.from(document.querySelectorAll('button')) + .find((button) => button.textContent === 'Prepare search')! + .click(), + ); + await act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + await act(async () => walletButton().click()); + expect(success).not.toHaveBeenCalled(); + expect(mocks.setItem).not.toHaveBeenCalled(); + await act(async () => headerButton('Go back').click()); + expect( + document.querySelector('[data-testid="picker-state"]')?.textContent, + ).toBe('Meta:true'); + expect( + (document.querySelector('input[type="checkbox"]') as HTMLInputElement) + .checked, + ).toBe(true); + expect(modal.modalStack).toHaveLength(1); + expect(walletButton().disabled).toBe(false); + }); + it('renders the eager retry screen on the same consent and error contract', async () => { + await mount(dark); + const retry = vi + .fn() + .mockRejectedValueOnce( + new UnauthorizedProviderError(new Error('Retry rejected')), + ) + .mockResolvedValueOnce({}); + await act(async () => + modal.openModal({ + type: 'eager', + props: { + tryConnection: retry, + initialError: new Error('Initial rejection'), + }, + }), + ); + expect(document.querySelector('[role="alert"]')?.textContent).toContain( + GENERIC_ERROR, + ); + await act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + const connect = Array.from(document.querySelectorAll('button')).find( + (button) => button.textContent === 'Connect', + )!; + await act(async () => connect.click()); + expect(document.querySelector('[role="alert"]')?.textContent).toContain( + 'did not authorize this site', + ); + await act(async () => connect.click()); + expect(retry).toHaveBeenCalledTimes(2); + expect(modal.currentModal?.type).toBe('wallet'); + }); + it('selects an EIP-6963 provider and completes both nested screens once', async () => { + const success = await mount(dark); + const select = vi.fn(() => { + mocks.state.status = 'connected'; + mocks.state.current = 'eip6963'; + mocks.state.connections.set('eip6963', { + connector: { id: 'org.example.wallet', uid: 'eip6963' }, + }); + }); + const provider = { + info: { + uuid: 'test-provider', + name: 'Discovered wallet', + rdns: 'org.example.wallet', + icon: 'data:image/png;base64,AA' as const, + }, + provider: { request: vi.fn(), on: vi.fn(), removeListener: vi.fn() }, + }; + await act(async () => + modal.openModal({ + type: 'eip6963', + props: { providers: [provider], onSelect: select }, + }), + ); + await act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + const button = Array.from(document.querySelectorAll('button')).find( + (item) => item.textContent?.includes('Discovered wallet'), + )!; + await act(async () => button.click()); + expect(select).toHaveBeenCalledExactlyOnceWith(provider); + expect(success).toHaveBeenCalledOnce(); + expect(modal.modalStack).toHaveLength(0); + }); + it('returns from an EIP-6963 error without completing either screen', async () => { + const success = await mount(dark); + const select = vi + .fn() + .mockRejectedValueOnce(new Error('Provider failed')); + const provider = { + info: { + uuid: 'failed-provider', + name: 'Discovered wallet', + rdns: 'org.example.wallet', + icon: 'data:image/png;base64,AA' as const, + }, + provider: { request: vi.fn(), on: vi.fn(), removeListener: vi.fn() }, + }; + await act(async () => + modal.openModal({ + type: 'eip6963', + props: { providers: [provider], onSelect: select }, + }), + ); + await act(async () => + ( + document.querySelector('input[type="checkbox"]') as HTMLInputElement + ).click(), + ); + const button = () => + Array.from(document.querySelectorAll('button')).find((item) => + item.textContent?.includes('Discovered wallet'), + )!; + await act(async () => button().click()); + expect(document.querySelector('[role="alert"]')?.textContent).toContain( + GENERIC_ERROR, + ); + await act(async () => headerButton('Go back').click()); + expect(modal.modalStack).toHaveLength(2); + expect(modal.currentModal?.type).toBe('eip6963'); + expect(button().disabled).toBe(false); + expect(success).not.toHaveBeenCalled(); + expect(mocks.setItem).not.toHaveBeenCalled(); + }); + if (LedgerAccounts) + it('uses Ledger Select without dismissing the surrounding dialog', async () => { + const state: LedgerViewProps['state'] = { + screen: 'accounts', + error: null, + errorMessage: null, + isLoading: false, + isLoadingLedgerLibs: false, + isUserActivationRequired: false, + accounts: [], + currentPage: 1, + pagesCount: 4, + accountsPerPage: 5, + derivationPath: "m/44'/60'/x'/0/0", + derivationPaths: [ + { template: "m/44'/60'/x'/0/0", title: 'Ledger Live' }, + { template: "m/44'/60'/0'/x", title: 'Ledger Legacy' }, + ], + setPage: vi.fn(), + setDerivationPath: vi.fn(), + retry: async () => {}, + selectAccount: async () => {}, + }; + await mount(dark, { + WalletPicker: () => , + }); + const input = document.querySelector( + 'input, button[aria-haspopup="listbox"]', + )!; + await act(async () => { + input.click(); + await new Promise((resolve) => setTimeout(resolve, 300)); + }); + const option = Array.from( + document.querySelectorAll('[role="option"], [role="menuitem"]'), + ).find((item) => + item.textContent?.includes('Ledger Legacy'), + ) as HTMLElement; + expect(option).toBeDefined(); + await act(async () => option.click()); + expect(state.setDerivationPath).toHaveBeenCalledExactlyOnceWith( + "m/44'/60'/0'/x", + ); + expect(modal.currentModal?.type).toBe('wallet'); + await act(async () => { + input.click(); + await new Promise((resolve) => setTimeout(resolve, 300)); + }); + await act(async () => + input.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'Escape', + code: 'Escape', + bubbles: true, + }), + ), + ); + expect(modal.currentModal?.type).toBe('wallet'); + }); + it('honors WalletButton and Terms overrides inside the standard picker', async () => { + await mount(dark, { + WalletButton: (props) => ( + + ), + Terms: (props) => ( + + ), + }); + expect(document.querySelector('[data-custom-card]')).not.toBeNull(); + await act(async () => + ( + document.querySelector('[data-custom-terms]') as HTMLButtonElement + ).click(), + ); + await act(async () => walletButton().click()); + expect(mocks.connect).toHaveBeenCalledOnce(); + }); + it('renders an overridden whole screen and closes via the shared modal API', async () => { + await mount(dark, { + WalletPicker: ({ terms }) => ( +
{terms}Custom screen
+ ), + }); + expect(document.querySelector('[data-custom-screen]')).not.toBeNull(); + await act(async () => + ( + document.querySelector( + 'button[aria-label="Close"]', + ) as HTMLButtonElement + ).click(), + ); + expect(modal.modalStack).toHaveLength(0); + }); + }); +} diff --git a/packages/reef-knot/tsconfig.json b/packages/reef-knot/tsconfig.json index 23709e73..8acf31ca 100644 --- a/packages/reef-knot/tsconfig.json +++ b/packages/reef-knot/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "tsconfig/react-library.json", "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], + "exclude": ["node_modules", "dist"], "compilerOptions": { "rootDir": "src", } diff --git a/packages/reef-knot/tsdown.config.ts b/packages/reef-knot/tsdown.config.ts index 57dae503..7faef81a 100644 --- a/packages/reef-knot/tsdown.config.ts +++ b/packages/reef-knot/tsdown.config.ts @@ -1,4 +1,4 @@ import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; +import { defineSvgConfig } from 'build-config'; -export default defineConfig(defineStandardConfig()); +export default defineConfig(defineSvgConfig({ memo: true })); diff --git a/packages/reef-knot/vitest.config.ts b/packages/reef-knot/vitest.config.ts new file mode 100644 index 00000000..44abde88 --- /dev/null +++ b/packages/reef-knot/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; +export default defineConfig({ + test: { + environment: 'happy-dom', + include: ['src/**/*.test.{ts,tsx}'], + server: { deps: { inline: [/@ledgerhq\//] } }, + }, +}); diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json index c2a06f42..cd8a41c1 100644 --- a/packages/tsconfig/base.json +++ b/packages/tsconfig/base.json @@ -13,14 +13,14 @@ "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, - "moduleResolution": "node", + "moduleResolution": "bundler", "noUnusedLocals": false, "noUnusedParameters": false, "skipLibCheck": true, "strict": true, "strictNullChecks": true, "noEmit": true, - "baseUrl": ".", + "types": ["*"], "allowJs": false, "resolveJsonModule": true }, diff --git a/packages/tsconfig/react-library.json b/packages/tsconfig/react-library.json index 0f590236..25c04951 100644 --- a/packages/tsconfig/react-library.json +++ b/packages/tsconfig/react-library.json @@ -12,8 +12,7 @@ "noImplicitAny": true, "noUnusedLocals": false, "noUnusedParameters": false, - "strictFunctionTypes": false, - "baseUrl": "." + "strictFunctionTypes": false }, "include": ["src/*"] } diff --git a/packages/types/.eslintrc.json b/packages/types/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/types/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md deleted file mode 100644 index 43c11ae9..00000000 --- a/packages/types/CHANGELOG.md +++ /dev/null @@ -1,136 +0,0 @@ -# @reef-knot/types - -## 5.2.0 - -- Add `ledgerForceClearSign` to `WalletAdapterArgs` - -## 5.1.0 - -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update peerDependencies requirements: viem >=2.50, wagmi >=3.6 - -## 5.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 4.2.0 - -### Minor Changes - -- Technical version update - -## 4.1.0 - -### Minor Changes - -- Update viem to v2.23 and wagmi to v2.14, so the @coinbase/wallet-sdk would be updated too, which fixes a dependabot issue - -## 4.0.0 - -### Major Changes - -- Metrics config refactored, replaced with certain actions callbacks - -## 3.0.0 - -### Major Changes - -- reef-knot setup rework - -## 2.1.1 - -### Patch Changes - -- accbcde: viem and wagmi versions updated with flexible declarations - -## 2.1.0 - -### Minor Changes - -- Support EIP-6963 - -## 2.0.1 - -### Patch Changes - -- Wagmi version updated - -## 2.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -## 1.8.0 - -### Minor Changes - -- a6ca608: Add deeplinks support - -## 1.7.0 - -### Minor Changes - -- Make it possible for wallet detectors to be async; -- Improve Safe wallet detection; - -## 1.6.0 - -### Minor Changes - -- wallet connectors id exports and typings updated - -## 1.5.0 - -### Minor Changes - -- 1046886: Add autoConnectOnly field to WalletAdapterData - -## 1.4.0 - -### Minor Changes - -- Use Ledger hid wallet adapter, based on wagmi - -## 1.3.0 - -### Minor Changes - -- e654dc5: Remove deprecated "icons" field from Wallet Adapater API - -### Patch Changes - -- 48d8c4b: Update wagmi to 0.12.19 - -## 1.2.2 - -### Patch Changes - -- e6e579e: wagmi 0.12.18 - -## 1.2.1 - -### Patch Changes - -- Update wagmi to v0.12.17 - -## 1.2.0 - -### Minor Changes - -- Explicitly pass chains to wagmi connectors, update wagmi to v0.12.16 - -## 1.1.1 - -### Patch Changes - -- Add walletconnectProjectId to WalletAdapterArgs - -## 1.1.0 - -### Minor Changes - -- faa8815: Update wagmi to v0.12 -- faa8815: Update Wallet Adapter API for WalletConnect diff --git a/packages/types/LICENSE.txt b/packages/types/LICENSE.txt deleted file mode 100644 index 07e71353..00000000 --- a/packages/types/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Lido - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/types/README.md b/packages/types/README.md deleted file mode 100644 index 9e8d4175..00000000 --- a/packages/types/README.md +++ /dev/null @@ -1 +0,0 @@ -# Reef Knot Types diff --git a/packages/types/package.json b/packages/types/package.json deleted file mode 100644 index d1f0bb9a..00000000 --- a/packages/types/package.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "@reef-knot/types", - "version": "0.0.0", - "main": "", - "types": "dist/index.d.ts", - "type": "module", - "files": [ - "dist" - ], - "license": "MIT", - "homepage": "https://github.com/lidofinance/reef-knot", - "repository": { - "type": "git", - "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/types" - }, - "bugs": { - "url": "https://github.com/lidofinance/reef-knot/issues" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public" - }, - "scripts": { - "build": "yarn run -T tsdown", - "dev": "yarn run -T tsdown --watch", - "typecheck": "tsc --noEmit" - }, - "devDependencies": { - "@reef-knot/ui-react": "*", - "build-config": "*", - "react": "18.2.0", - "viem": ">=2.50", - "wagmi": ">=3.6" - }, - "peerDependencies": { - "@reef-knot/ui-react": "*", - "@tanstack/react-query": "^5.29.0", - "react": ">=18", - "viem": ">=2.50", - "wagmi": ">=3.6" - } -} diff --git a/packages/types/src/reef-knot-wallets-modal.ts b/packages/types/src/reef-knot-wallets-modal.ts deleted file mode 100644 index 15373e0e..00000000 --- a/packages/types/src/reef-knot-wallets-modal.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ComponentType } from 'react'; -import type { ModalProps } from '@reef-knot/ui-react'; -import type { ConnectWalletButtonProps } from './wallet-connect-button'; - -export type ButtonComponentsByConnectorId = { - [key: string]: ComponentType; -}; - -export type ReefKnotWalletsModalConfig = { - buttonComponentsByConnectorId: ButtonComponentsByConnectorId; - walletsShown: I[]; - walletsPinned: I[]; - walletsDisplayInitialCount?: number; - linkTerms?: string; - linkPrivacyNotice?: string; - linkDontHaveWallet?: string; - onConnectStart?: (args: { walletId: I }) => void; - onConnectSuccess?: (args: { walletId: I; rdns?: string }) => void; - onClickTermsAccept?: (args: { isAccepted: boolean }) => void; - onClickWalletsMore?: () => void; - onClickWalletsLess?: () => void; -}; - -export type ReefKnotWalletsModalProps = - ModalProps & { - config: ReefKnotWalletsModalConfig; - darkThemeEnabled?: boolean; - buttonsFullWidth?: boolean; - }; diff --git a/packages/types/src/wallet-connect-button.ts b/packages/types/src/wallet-connect-button.ts deleted file mode 100644 index 388742ce..00000000 --- a/packages/types/src/wallet-connect-button.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ButtonProps } from '@reef-knot/ui-react'; -import type { Connector, CreateConnectorFn } from 'wagmi'; -import type { WalletAdapterData } from './walletAdapter'; - -export type ConnectButtonBaseProps = ButtonProps & { - icon?: WalletAdapterData['icon']; - darkThemeEnabled?: boolean; - isCompact?: boolean; - isLoading?: boolean; -}; - -export type ConnectWalletButtonProps = ConnectButtonBaseProps & { - walletId: WalletAdapterData['walletId']; - walletName: WalletAdapterData['walletName']; - detector?: WalletAdapterData['detector']; - deeplink?: WalletAdapterData['deeplink']; - downloadURLs?: WalletAdapterData['downloadURLs']; - walletconnectExtras?: WalletAdapterData['walletconnectExtras']; - connector: Connector | CreateConnectorFn; - disabled: boolean; - onConnectStart?: () => void; - onConnectSuccess?: (args?: { reconnectId?: string; rdns?: string }) => void; -}; diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json deleted file mode 100644 index 23709e73..00000000 --- a/packages/types/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], - "compilerOptions": { - "rootDir": "src", - } -} diff --git a/packages/types/tsdown.config.ts b/packages/types/tsdown.config.ts deleted file mode 100644 index 57dae503..00000000 --- a/packages/types/tsdown.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; - -export default defineConfig(defineStandardConfig()); diff --git a/packages/ui-lido-legacy/CHANGELOG.md b/packages/ui-lido-legacy/CHANGELOG.md new file mode 100644 index 00000000..dea41716 --- /dev/null +++ b/packages/ui-lido-legacy/CHANGELOG.md @@ -0,0 +1,11 @@ +# @reef-knot/ui-lido-legacy + +## 1.0.0 + +- Move the legacy wallet modal and UI components from `@reef-knot/connect-wallet-modal` and `@reef-knot/ui-react` into this package for Reef Knot 9. +- Keep support for `darkThemeEnabled`, `buttonsFullWidth` and legacy modal props. Require Lido UI v3 and styled-components 5. +- Use the shared connection hooks from `reef-knot` and allow component overrides through `components`. +- Show connection errors with a Back action that preserves the picker state. +- Keep wallet icon components stable across renders to avoid flicker. +- Unmount closed transition overlays so they no longer block clicks, keyboard focus or scrolling. Remove the `mountOnEnter` and `unmountOnExit` options. +- Replace the old wallet-button registry with `components.WalletButton`. The `linkDontHaveWallet` option and wallet-specific `Connect*` components are removed. diff --git a/packages/connect-wallet-modal/LICENSE.txt b/packages/ui-lido-legacy/LICENSE.txt similarity index 100% rename from packages/connect-wallet-modal/LICENSE.txt rename to packages/ui-lido-legacy/LICENSE.txt diff --git a/packages/ui-lido-legacy/README.md b/packages/ui-lido-legacy/README.md new file mode 100644 index 00000000..715e036a --- /dev/null +++ b/packages/ui-lido-legacy/README.md @@ -0,0 +1,5 @@ +# @reef-knot/ui-lido-legacy + +Legacy UI skin based on Lido UI v3 for the public reef-knot headless API. + +See [the UI and migration guide](../../docs/headless-ui.md) for setup, peer dependencies and component overrides. diff --git a/packages/ui-react/package.json b/packages/ui-lido-legacy/package.json similarity index 62% rename from packages/ui-react/package.json rename to packages/ui-lido-legacy/package.json index 8ccae1e0..5fbffc44 100644 --- a/packages/ui-react/package.json +++ b/packages/ui-lido-legacy/package.json @@ -1,19 +1,19 @@ { - "name": "@reef-knot/ui-react", + "name": "@reef-knot/ui-lido-legacy", "version": "0.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "exports": { - ".": "./dist/index.js", - "./styled-wrapper": "./dist/utils/styledWrapper.js" + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } }, "typesVersions": { "*": { ".": [ "dist/index.d.ts" - ], - "styled-wrapper": [ - "dist/utils/styledWrapper.d.ts" ] } }, @@ -26,7 +26,7 @@ "repository": { "type": "git", "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/ui-react" + "directory": "packages/ui-lido-legacy" }, "bugs": { "url": "https://github.com/lidofinance/reef-knot/issues" @@ -38,29 +38,36 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit", + "test": "vitest run" }, "dependencies": { "react-transition-group": "4", "use-callback-ref": "1.2.5" }, "peerDependencies": { + "@lidofinance/lido-ui": "^3.18.0", "react": ">=18", "react-dom": ">=18", - "styled-components": "5", - "viem": ">=2.50", - "wagmi": ">=3.6" + "reef-knot": "^9", + "styled-components": "^5.3.5" }, "devDependencies": { - "@tanstack/react-query": "^5.29.0", + "@lidofinance/lido-ui": "^3.18.0", + "@tanstack/react-query": "^5.51.1", + "@types/react": "18.2.45", + "@types/react-dom": "18.2.17", "@types/react-transition-group": "4.4.12", "build-config": "*", - "eslint-config-custom": "*", + "happy-dom": "^20.0.0", "react": "18.2.0", "react-dom": "18.2.0", + "reef-knot": "*", "styled-components": "^5.3.6", + "tsconfig": "*", "viem": ">=2.50", + "vitest": "^4.1.11", "wagmi": ">=3.6" } } diff --git a/packages/ui-lido-legacy/src/__tests__/modal.test.tsx b/packages/ui-lido-legacy/src/__tests__/modal.test.tsx new file mode 100644 index 00000000..36cebc6a --- /dev/null +++ b/packages/ui-lido-legacy/src/__tests__/modal.test.tsx @@ -0,0 +1,45 @@ +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, expect, it } from 'vitest'; +import { ThemeProvider, themeLight } from '@lidofinance/lido-ui'; +import { Modal } from '../ui-react'; + +let root: Root; +let container: HTMLDivElement; + +// Untyped callers can still pass the removed option. +const legacyProps = { unmountOnExit: false } as object; + +async function render(open: boolean) { + await act(async () => + root.render( + + + content + + , + ), + ); +} + +beforeEach(() => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); +}); +afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); +}); + +it('unmounts the overlay after the modal closes', async () => { + await render(true); + expect(document.querySelector('[role="dialog"]')).not.toBeNull(); + + await render(false); + // Let the exit transition finish. + await act(() => new Promise((resolve) => setTimeout(resolve, 10))); + + expect(document.querySelector('[role="dialog"]')).toBeNull(); +}); diff --git a/packages/ui-lido-legacy/src/__tests__/tsconfig.json b/packages/ui-lido-legacy/src/__tests__/tsconfig.json new file mode 100644 index 00000000..1927feb3 --- /dev/null +++ b/packages/ui-lido-legacy/src/__tests__/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "include": ["./**/*", "../**/*.d.ts"], + "exclude": [], + "compilerOptions": { + "rootDir": "../../..", + "noEmit": true + } +} diff --git a/packages/ui-lido-legacy/src/__tests__/ui.test.tsx b/packages/ui-lido-legacy/src/__tests__/ui.test.tsx new file mode 100644 index 00000000..a708d3e3 --- /dev/null +++ b/packages/ui-lido-legacy/src/__tests__/ui.test.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import { ThemeProvider, themeDark, themeLight } from '@lidofinance/lido-ui'; +import { runUISuite } from '../../../reef-knot/test-ui/suite'; +import { ReefKnotWalletsModal, LEGACY_COMPONENTS } from '../index'; +runUISuite( + ({ dark, ...props }) => ( + + ), + (children, dark) => ( + + {children} + + ), + LEGACY_COMPONENTS.LedgerAccounts, +); diff --git a/packages/ui-lido-legacy/src/__tests__/wallet-button.test.tsx b/packages/ui-lido-legacy/src/__tests__/wallet-button.test.tsx new file mode 100644 index 00000000..0a6ff502 --- /dev/null +++ b/packages/ui-lido-legacy/src/__tests__/wallet-button.test.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; +import { act } from 'react-dom/test-utils'; +import { afterEach, beforeEach, expect, it, vi } from 'vitest'; +import { ThemeProvider, themeLight } from '@lidofinance/lido-ui'; +import { FALLBACK_WALLET_ICON, type WalletButtonViewProps } from 'reef-knot'; +import { WalletButton } from '../connect-wallet-modal/views'; + +let root: Root; +let container: HTMLDivElement; +const props: WalletButtonViewProps = { + name: 'Detected wallet', + iconUrl: 'https://example.com/wallet.svg', + disabled: true, + isLoading: false, + onConnect: vi.fn(), +}; +async function render(overrides: Partial = {}) { + await act(async () => + root.render( + + + , + ), + ); +} +beforeEach(() => { + Object.assign(globalThis, { IS_REACT_ACT_ENVIRONMENT: true }); + container = document.createElement('div'); + document.body.append(container); + root = createRoot(container); +}); +afterEach(async () => { + await act(async () => root.unmount()); + container.remove(); +}); + +it('keeps the same image node when consent and loading change', async () => { + await render(); + const image = container.querySelector('img'); + expect(image).not.toBeNull(); + await render({ disabled: false }); + expect(container.querySelector('img')).toBe(image); + await render({ disabled: false, isLoading: true }); + expect(container.querySelector('img')).toBe(image); + await render({ iconUrl: 'https://example.com/other-wallet.svg' }); + expect(container.querySelector('img')?.src).toBe( + 'https://example.com/other-wallet.svg', + ); +}); + +it('preserves the fallback image across unrelated renders', async () => { + await render(); + const image = container.querySelector('img')!; + await act(async () => image.dispatchEvent(new Event('error'))); + expect(image.src).toBe(FALLBACK_WALLET_ICON); + await render({ disabled: false, isLoading: true }); + expect(container.querySelector('img')).toBe(image); + expect(image.src).toBe(FALLBACK_WALLET_ICON); +}); diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx similarity index 91% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx index 81690f14..eda576c0 100644 --- a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/BrowserWalletIconsGrid.tsx @@ -1,12 +1,15 @@ import React, { FC } from 'react'; -import type { EIP6963ProviderDetail } from '@reef-knot/core-react'; +import type { EIP6963ProviderDetail } from 'reef-knot'; import TrustIcon from './icons/trust.svg'; import RabbyIcon from './icons/rabby.svg'; import BraveIcon from './icons/brave.svg'; import ZerionIcon from './icons/zerion.svg'; import { Grid, DefaultSvgIcon, IconImg } from './styles'; -import { validateIcon, FALLBACK_WALLET_ICON } from '../../helpers/validateIcon'; -import { useEIP6963ProvidersWithoutAdapters } from '../../hooks/useEIP6963ProvidersWithoutAdapters'; +import { + validateIcon, + FALLBACK_WALLET_ICON, + useEIP6963ProvidersWithoutAdapters, +} from 'reef-knot'; const DEFAULT_WALLETS = [ { id: 'trust', rdns: 'com.trustwallet.app', Icon: TrustIcon }, diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/brave.svg b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/brave.svg similarity index 100% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/brave.svg rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/brave.svg diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/rabby.svg b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/rabby.svg similarity index 100% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/rabby.svg rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/rabby.svg diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/trust.svg b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/trust.svg similarity index 100% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/trust.svg rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/trust.svg diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/zerion.svg b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/zerion.svg similarity index 100% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/icons/zerion.svg rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/icons/zerion.svg diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/index.ts b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/index.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/index.ts rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/index.ts diff --git a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/styles.tsx similarity index 90% rename from packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/styles.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/styles.tsx index 9272dc5e..be51f8b7 100644 --- a/packages/connect-wallet-modal/src/components/BrowserWalletIconsGrid/styles.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/BrowserWalletIconsGrid/styles.tsx @@ -1,4 +1,4 @@ -import styled from '@reef-knot/ui-react/styled-wrapper'; +import styled from '../../../ui-react/utils/styledWrapper'; export const ICON_SIZE = 20; export const CONTAINER_SIZE = 44; diff --git a/packages/connect-wallet-modal/src/components/ConnectButtonBase/ConnectButtonBase.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/ConnectButtonBase.tsx similarity index 94% rename from packages/connect-wallet-modal/src/components/ConnectButtonBase/ConnectButtonBase.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/ConnectButtonBase.tsx index 5ccb8490..b09c2b06 100644 --- a/packages/connect-wallet-modal/src/components/ConnectButtonBase/ConnectButtonBase.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/ConnectButtonBase.tsx @@ -6,7 +6,7 @@ import { ConnectButtonIconStyle, ConnectButtonTitleStyle, } from './styles'; -import { ConnectButtonBaseProps } from '@reef-knot/types'; +import { ConnectButtonBaseProps } from '../../../types/index'; import { isWalletAdapterIcons } from '../../helpers/isWalletAdapterIcons'; export const ConnectButtonBase: FC = (props) => { diff --git a/packages/connect-wallet-modal/src/components/ConnectButtonBase/index.ts b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/index.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/ConnectButtonBase/index.ts rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/index.ts diff --git a/packages/connect-wallet-modal/src/components/ConnectButtonBase/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/styles.tsx similarity index 94% rename from packages/connect-wallet-modal/src/components/ConnectButtonBase/styles.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/styles.tsx index a0d5b3c1..38eff22f 100644 --- a/packages/connect-wallet-modal/src/components/ConnectButtonBase/styles.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectButtonBase/styles.tsx @@ -1,5 +1,5 @@ -import styled, { css, keyframes } from '@reef-knot/ui-react/styled-wrapper'; -import { Button } from '@reef-knot/ui-react'; +import styled, { css, keyframes } from '../../../ui-react/utils/styledWrapper'; +import { Button } from '../../../ui-react/index'; export const ConnectButtonStyle = styled(Button).attrs({ variant: 'ghost', diff --git a/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx new file mode 100644 index 00000000..9c3064c4 --- /dev/null +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/ConnectWalletModalLayout.tsx @@ -0,0 +1,120 @@ +import React, { useEffect, useRef } from 'react'; + +import type { ReefKnotWalletsModalProps } from '../../../types/index'; +import { EmptyWalletsList } from '../EmptyWalletsList'; +import { + ContentWrapper, + ContentWrapperInner, + WalletsButtonsScrollBox, + WalletsButtonsContainer, + Subtitle, + ContentHeader, + MoreWalletsToggleButton, + MoreWalletsText, + IconMoreWallets, +} from './styles'; + +import { isMobileOrTablet, isIOS, isIPad } from 'reef-knot'; +import { WalletModalInput } from '../WalletModalInput'; + +// Additional check because `@supports selector(::-webkit-scrollbar)` +// passes as true on iOS/iPad devices, but styles will not really apply +const isSupportedCustomScrollbar = !isIOS && !isIPad; + +type ConnectWalletModalLayoutProps = ReefKnotWalletsModalProps & { + terms: React.ReactNode; + inputValue: string; + isEmptyWalletsList: boolean; + isShownOtherWallets: boolean; + isShownWalletsToggleButton: boolean; + onCloseReject?: () => void; + onToggleWalletsList: () => void; + onInputChange: React.ChangeEventHandler; + onInputClear: () => void; +}; + +export const ConnectWalletModalLayout = ({ + config, + terms, + inputValue, + onInputChange, + onInputClear, + onCloseReject, + onToggleWalletsList, + isEmptyWalletsList, + isShownOtherWallets, + isShownWalletsToggleButton, + children, + ...passedDownProps +}: ConnectWalletModalLayoutProps) => { + const { buttonsFullWidth = false, darkThemeEnabled } = passedDownProps; + + const inputRef = useRef(null); + + useEffect(() => { + if (isShownOtherWallets) { + if (!isMobileOrTablet) inputRef.current?.focus(); + } else { + onInputClear(); + } + }, [isShownOtherWallets, onInputClear]); + + return ( + + + + {terms} + + Choose wallet + + {isShownOtherWallets && ( + + )} + + + + {isEmptyWalletsList && ( + + )} + + {!isEmptyWalletsList && ( + + {children} + + )} + + + {isShownWalletsToggleButton && ( + + + + {isShownOtherWallets ? 'Less wallets' : 'More wallets'} + + + )} + + + ); +}; diff --git a/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/index.ts b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/index.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/index.ts rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/index.ts diff --git a/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/styles.tsx similarity index 98% rename from packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/styles.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/styles.tsx index 076e9d3b..0d3fa984 100644 --- a/packages/connect-wallet-modal/src/components/ConnectWalletModalLayout/styles.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectWalletModalLayout/styles.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import styled, { css } from '@reef-knot/ui-react/styled-wrapper'; +import styled, { css } from '../../../ui-react/utils/styledWrapper'; import { Link } from '@lidofinance/lido-ui'; /** diff --git a/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectionError/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectionError/styles.tsx new file mode 100644 index 00000000..2bd2ee01 --- /dev/null +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/ConnectionError/styles.tsx @@ -0,0 +1,21 @@ +import styled, { css } from '../../../ui-react/utils/styledWrapper'; + +export const ConnectionErrorStyle = styled.div` + ${({ theme: { fontSizesMap, spaceMap, colors } }) => css` + display: flex; + flex-direction: column; + align-items: center; + gap: ${spaceMap.xs}px; + padding: ${spaceMap.xs}px 0 ${spaceMap.xxl}px; + text-align: center; + overflow-wrap: anywhere; + color: ${colors.textSecondary}; + font-size: ${fontSizesMap.xxs}px; + line-height: 1.6em; + `} +`; + +export const ConnectionErrorIconStyle = styled.div` + display: flex; + margin-bottom: ${({ theme }) => theme.spaceMap.sm}px; +`; diff --git a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/ArrowBack.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/ArrowBack.tsx similarity index 92% rename from packages/connect-wallet-modal/src/components/EIP6963WalletsList/ArrowBack.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/ArrowBack.tsx index 7e5211b7..31b2f2c1 100644 --- a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/ArrowBack.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/ArrowBack.tsx @@ -1,6 +1,6 @@ import React from 'react'; -const ArrowBack = React.forwardRef(function ArrowBack( +const ArrowBack = React.forwardRef(function ArrowBackRender( props: React.SVGProps, svgRef?: React.Ref, ) { diff --git a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/styles.tsx similarity index 90% rename from packages/connect-wallet-modal/src/components/EIP6963WalletsList/styles.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/styles.tsx index afdb4c04..12144fb4 100644 --- a/packages/connect-wallet-modal/src/components/EIP6963WalletsList/styles.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EIP6963WalletsList/styles.tsx @@ -1,5 +1,5 @@ -import styled, { css } from '@reef-knot/ui-react/styled-wrapper'; -import { ButtonIcon } from '@reef-knot/ui-react'; +import styled, { css } from '../../../ui-react/utils/styledWrapper'; +import { ButtonIcon } from '../../../ui-react/index'; import { ArrowBack } from './ArrowBack'; export const WalletList = styled.ul` diff --git a/packages/connect-wallet-modal/src/components/EagerConnectModal/styles.ts b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EagerConnectModal/styles.ts similarity index 87% rename from packages/connect-wallet-modal/src/components/EagerConnectModal/styles.ts rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EagerConnectModal/styles.ts index 5f52bb47..d8dc592b 100644 --- a/packages/connect-wallet-modal/src/components/EagerConnectModal/styles.ts +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EagerConnectModal/styles.ts @@ -1,4 +1,4 @@ -import styled, { css } from '@reef-knot/ui-react/styled-wrapper'; +import styled, { css } from '../../../ui-react/utils/styledWrapper'; export const ErrorBlock = styled.div` ${({ theme: { fontSizesMap, spaceMap, borderRadiusesMap } }) => css` diff --git a/packages/connect-wallet-modal/src/components/EmptyWalletsList/EmptyWalletsList.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/EmptyWalletsList.tsx similarity index 100% rename from packages/connect-wallet-modal/src/components/EmptyWalletsList/EmptyWalletsList.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/EmptyWalletsList.tsx diff --git a/packages/connect-wallet-modal/src/components/EmptyWalletsList/index.ts b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/index.ts similarity index 100% rename from packages/connect-wallet-modal/src/components/EmptyWalletsList/index.ts rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/index.ts diff --git a/packages/connect-wallet-modal/src/components/EmptyWalletsList/styles.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/styles.tsx similarity index 87% rename from packages/connect-wallet-modal/src/components/EmptyWalletsList/styles.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/styles.tsx index 7e120b8f..384138a2 100644 --- a/packages/connect-wallet-modal/src/components/EmptyWalletsList/styles.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/EmptyWalletsList/styles.tsx @@ -1,5 +1,6 @@ +import { ThemeName } from '@lidofinance/lido-ui'; import React from 'react'; -import styled, { css } from '@reef-knot/ui-react/styled-wrapper'; +import styled, { css } from '../../../ui-react/utils/styledWrapper'; export const Wrap = styled.div` ${({ theme }) => css` @@ -14,7 +15,7 @@ export const Wrap = styled.div` svg { display: block; - fill: ${theme.name === 'dark' ? '#27272E' : '#EFF2F6'}; + fill: ${theme.name === ThemeName.dark ? '#27272E' : '#EFF2F6'}; } `} `; diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerAccountButton.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountButton.tsx similarity index 80% rename from packages/connect-wallet-modal/src/components/Ledger/LedgerAccountButton.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountButton.tsx index 699535d1..5ab2a3ad 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerAccountButton.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountButton.tsx @@ -1,10 +1,18 @@ import React, { FC } from 'react'; import { Address, Text, useBreakpoint } from '@lidofinance/lido-ui'; -import styled, { keyframes } from '@reef-knot/ui-react/styled-wrapper'; +import styled, { keyframes } from '../../../ui-react/utils/styledWrapper'; import { LedgerWalletIcon } from './icons/LedgerWalletIcon'; -import { AccountRecord } from './types'; - -const ButtonStyled = styled.div` +import type { LedgerAccount as AccountRecord } from 'reef-knot'; + +const ButtonStyled = styled.button` + border: 0; + font: inherit; + color: inherit; + text-align: left; + :disabled { + cursor: default; + opacity: 0.6; + } width: 100%; background-color: var(--lido-color-backgroundSecondary); border-radius: 10px; @@ -74,7 +82,7 @@ const BalanceValueWrapper = styled.span` const BalanceTokenWrapper = styled.span``; -type Props = { onClick: () => void } & Pick< +type Props = { onClick: () => void; disabled?: boolean } & Pick< AccountRecord, 'address' | 'balance' | 'token' >; @@ -84,19 +92,20 @@ export const AccountButton: FC = ({ balance, token, onClick, + disabled, }) => { const roundedBalance = balance === undefined || balance === 0 ? '0' : Number(balance).toFixed(4); return ( - +
- + {roundedBalance}  {token} @@ -107,7 +116,7 @@ export const AccountButton: FC = ({ }; export const AccountButtonSkeleton = () => ( - + ); diff --git a/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountScreen.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountScreen.tsx new file mode 100644 index 00000000..7000e3cb --- /dev/null +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerAccountScreen.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { Pagination, Stack, StackItem } from '@lidofinance/lido-ui'; +import type { LedgerViewProps } from 'reef-knot'; +import { AccountButton, AccountButtonSkeleton } from './LedgerAccountButton'; +import { LedgerDerivationPathSelect } from './LedgerDerivationPathSelect'; +import styled from '../../../ui-react/utils/styledWrapper'; +const BoxWrapper = styled.div` + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: 24px; + padding-bottom: 20px; +`; +export function LedgerAccountScreen({ state }: LedgerViewProps) { + return ( + + + + + + {state.accounts.length === state.accountsPerPage + ? state.accounts.map((account) => ( + { + void state.selectAccount(account); + }} + /> + )) + : Array.from({ length: state.accountsPerPage }, (_, i) => ( + + ))} + + + + + + ); +} diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerConnectionScreen.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerConnectionScreen.tsx similarity index 91% rename from packages/connect-wallet-modal/src/components/Ledger/LedgerConnectionScreen.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerConnectionScreen.tsx index 864e2967..6893d664 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerConnectionScreen.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerConnectionScreen.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; import { Loader } from '@lidofinance/lido-ui'; -import { useLedgerContext } from './hooks'; + import { LedgerModalScreen } from './LedgerModalScreen'; import { LedgerImageDefaultAdaptive } from './icons/LedgerImageDefaultAdaptive'; import { LedgerScreenLoadingContainer } from './styles'; @@ -8,14 +8,14 @@ import { LedgerScreenLoadingContainer } from './styles'; type LedgerConnectionScreenProps = { showConnectButton?: boolean; onClickConnect?: () => void; + isLoadingLedgerLibs?: boolean; }; export const LedgerConnectionScreen: FC = ({ showConnectButton, onClickConnect, + isLoadingLedgerLibs, }) => { - const { isLoadingLedgerLibs } = useLedgerContext(); - const message = isLoadingLedgerLibs ? ( diff --git a/packages/connect-wallet-modal/src/components/Ledger/LedgerDerivationPathSelect.tsx b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerDerivationPathSelect.tsx similarity index 74% rename from packages/connect-wallet-modal/src/components/Ledger/LedgerDerivationPathSelect.tsx rename to packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerDerivationPathSelect.tsx index 21cd882e..f11236f8 100644 --- a/packages/connect-wallet-modal/src/components/Ledger/LedgerDerivationPathSelect.tsx +++ b/packages/ui-lido-legacy/src/connect-wallet-modal/components/Ledger/LedgerDerivationPathSelect.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { Box, Option, Select } from '@lidofinance/lido-ui'; -import styled from '@reef-knot/ui-react/styled-wrapper'; -import { DERIVATION_PATHS } from './constants'; +import styled from '../../../ui-react/utils/styledWrapper'; +import type { LedgerFlowState } from 'reef-knot'; const TextStyled = styled.p` color: var(--lido-color-textSecondary); @@ -12,13 +12,14 @@ const TextStyled = styled.p` `; export const LedgerDerivationPathSelect: FC<{ + paths: LedgerFlowState['derivationPaths']; value: string; onChange: (value: string) => void; -}> = ({ onChange, value }) => ( +}> = ({ onChange, value, paths }) => ( Select HD derivation path } + value={state.search} + onChange={(event) => state.setSearch(event.currentTarget.value)} + placeholder="Search wallets" + aria-label="Search wallets" + /> + + )} +
setIsScrolled(event.currentTarget.scrollTop > 0)} + > +
+ {state.isDiscovering && state.wallets.length === 0 && ( +

Discovering wallets…

+ )} + {!state.isDiscovering && state.wallets.length === 0 && ( +
+

No wallets found

+ +
+ )} + {children} +
+ {state.errorMessage && ( +

+ {state.errorMessage} +

+ )} + {state.showToggle && ( + + )} +
+ + + ); +} + +export function EagerConnect({ state, terms }: EagerConnectViewProps) { + return ( +
+ {terms} + {state.errorMessage && ( +

+ {state.errorMessage} +

+ )} + +
+ ); +} + +export function Requirements({ requirements }: RequirementsViewProps) { + const { goBack } = useReefKnotModal(); + const noWallets = requirements.kind === 'no-wallets'; + return ( +
+
+ {requirements.icon} +
+ {noWallets ? NO_WALLETS_TEXT : requirements.text} +
+
+ +
+ ); +} + +// The container shows Back in the header, so this view has no buttons. +export function ConnectionError({ errorMessage }: ConnectionErrorViewProps) { + return ( +
+ +

{errorMessage}

+
+ ); +} + +export function EIP6963Picker({ + terms, + children, + errorMessage, +}: EIP6963PickerViewProps) { + return ( +
+ {terms} +
{children}
+ {errorMessage && ( +

+ {errorMessage} +

+ )} +
+ ); +} + +export function LedgerConnection({ state }: LedgerViewProps) { + return ( +
+ +

+ {state.isLoadingLedgerLibs + ? 'Loading connector…' + : 'Please connect your Ledger and launch Ethereum app on your device'} +

+ {state.isUserActivationRequired && ( + + )} +
+ ); +} + +// Returns [0, 1, …, count - 1]. +const range = (count: number) => + Array.from({ length: count }, (_, index) => index); + +// Same frame as an account button, so the list does not jump when accounts load. +function AccountSkeleton() { + return ( + + ); +} + +export function LedgerAccounts({ state }: LedgerViewProps) { + return ( +
+ {/* Escape only dismisses the focused dropdown; the fieldset remains a semantic group. */} + {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */} +
{ + if (event.key !== 'Escape') return; + const dropdown = event.currentTarget.querySelector( + '[aria-expanded="true"]', + ); + if (!dropdown) return; + event.preventDefault(); + event.stopPropagation(); + dropdown.click(); + }} + > + Select HD derivation path + ({ + value: path.template, + label: {path.title}, + }))} + onChange={state.setDerivationPath} + /> +
+
+ {state.accounts.length < state.accountsPerPage ? ( + <> +

+ Loading accounts… +

+ {range(state.accountsPerPage).map((index) => ( + + ))} + + ) : ( + state.accounts.map((account) => ( + + )) + )} +
+ +
+ ); +} + +export function LedgerError({ state }: LedgerViewProps) { + return ( +
+ +

+ {state.errorMessage} +

+ +
+ ); +} + +export const LIDO_COMPONENTS: ReefKnotUIComponents = { + ModalContainer, + WalletButton, + Terms, + WalletPicker, + EagerConnect, + Requirements, + ConnectionError, + EIP6963Picker, + LedgerConnection, + LedgerAccounts, + LedgerError, +}; + +export type ReefKnotWalletsModalProps = { + config: ReefKnotWalletsModalConfig; + theme: ReefKnotTheme; + components?: Partial; + buttonsFullWidth?: boolean; +}; + +export function ReefKnotWalletsModal({ + config, + theme, + components, + buttonsFullWidth, +}: ReefKnotWalletsModalProps) { + const views = useMemo( + () => ({ ...LIDO_COMPONENTS, ...components }), + [components], + ); + return ( + + ); +} diff --git a/packages/ui-lido/src/styles.css b/packages/ui-lido/src/styles.css new file mode 100644 index 00000000..2ca7a2ef --- /dev/null +++ b/packages/ui-lido/src/styles.css @@ -0,0 +1,568 @@ +/* Styles stay scoped to the UI skin's portal. */ +.rk-lido-overlay { + position: fixed; + inset: 0; + z-index: 300; + display: flex; + padding: 24px; + overflow-y: auto; + /* Do not pass the scroll to the page at the end of the modal content. */ + overscroll-behavior: contain; + box-sizing: border-box; + background: rgb(0 0 0 / 40%); + font-family: var(--lido-app-ui-font-family); + color: var(--lido-app-ui-color-text-default); + font-size: 14px; + line-height: 22px; + letter-spacing: -0.14px; + --rk-lido-wallet-border: var(--lido-app-ui-color-border-default); +} +.rk-lido-overlay[data-lido-theme='light'] { + --rk-lido-wallet-border: #e5e5ea; +} +.rk-lido-dialog-container { + width: 100%; + margin: auto; +} +.rk-lido-dialog-container .rk-lido-dialog { + display: flex; + flex-direction: column; + box-sizing: border-box; + max-width: 100%; + overflow: clip; + background: var(--lido-app-ui-color-background-surface); + width: 100%; + padding: 32px; + border: 0; + border-radius: 20px; + gap: 20px; + outline: none; +} +.rk-lido-header-group { + display: flex; + flex-direction: column; + gap: 8px; +} +.rk-lido-header { + display: flex; + gap: 12px; + align-items: center; +} +/* Fixed side columns keep the title in the dialog center with one or two buttons. */ +.rk-lido-header-center { + display: grid; + grid-template-columns: 36px minmax(0, 1fr) 36px; +} +.rk-lido-header-center > :first-child:not(.rk-lido-title) { + grid-column: 1; +} +.rk-lido-header-center > .rk-lido-title { + grid-column: 2; + justify-content: center; + text-align: center; +} +.rk-lido-header-center > .rk-lido-close { + grid-column: 3; +} +.rk-lido-title { + font-size: 24px; + font-weight: 500; + line-height: 28.8px; + letter-spacing: -0.84px; + margin: 0; + min-width: 0; + flex: 1; + overflow-wrap: anywhere; + display: flex; + align-items: center; + gap: 12px; +} +.rk-lido-subtitle { + color: var(--lido-app-ui-color-text-secondary); + font-size: var(--lido-app-ui-font-size-label); + font-weight: var(--lido-app-ui-font-weight-regular); + line-height: var(--lido-app-ui-line-height-label); + letter-spacing: var(--lido-app-ui-letter-spacing-label); +} +.rk-lido-body { + display: flex; + flex-direction: column; +} +.rk-lido-pagination button { + width: 24px; + height: 24px; + padding: 0; + border: 0; + color: var(--lido-app-ui-color-text-default); +} +.rk-lido-pagination button > span { + width: 24px; + height: 24px; +} +.rk-lido-dialog p { + margin: 0; +} +.rk-lido-dialog a { + color: var(--lido-app-ui-color-text-active); + text-decoration: none; +} +.rk-lido-dialog a:hover { + text-decoration: underline; +} +.rk-lido-terms a { + white-space: nowrap; +} +.rk-lido-terms { + padding: 8px 0; +} +.rk-lido-terms > label { + display: flex; + gap: 16px; + align-items: flex-start; +} +.rk-lido-terms > label > span:last-child { + font-size: 14px; + line-height: 22px; + letter-spacing: -0.14px; +} +.rk-lido-terms input { + inset: 2px; + width: 20px; + height: 20px; + background: transparent; +} +/* The design uses the same blue in both themes. */ +.rk-lido-terms input:checked { + background: var(--lido-app-ui-palette-blue-600); + border-color: var(--lido-app-ui-palette-blue-600); +} +.rk-lido-terms input:checked:not(:disabled):hover { + background: var(--lido-app-ui-palette-blue-700); + border-color: var(--lido-app-ui-palette-blue-700); +} +/* The library tick turns black in the dark theme. Keep it white on blue. */ +.rk-lido-terms input:checked + svg { + color: var(--lido-app-ui-palette-white-a900); +} +.rk-lido-terms input + svg { + inset: 4px; + width: 16px; + height: 16px; +} +.rk-lido-picker { + display: flex; + flex-direction: column; + gap: 20px; +} +.rk-lido-overlay[data-screen='wallet'] .rk-lido-dialog { + padding-bottom: 0; +} +.rk-lido-picker-content { + display: flex; + flex-direction: column; + gap: 16px; + min-height: 0; +} +.rk-lido-picker-list { + max-height: min(466px, calc(100dvh - 210px)); + overflow-y: auto; + overscroll-behavior: contain; + scrollbar-width: none; + padding: 2px 0; + border-top: 1px solid transparent; +} +.rk-lido-picker-list::-webkit-scrollbar { + display: none; +} +.rk-lido-picker-list[data-expanded='true'] { + max-height: min(466px, calc(100dvh - 280px)); +} +.rk-lido-picker-list[data-scrolled='true'] { + border-top-color: var(--rk-lido-wallet-border); +} +.rk-lido-search { + display: flex; + align-items: center; + gap: 12px; +} +.rk-lido-search > :first-child { + flex: 1; + min-width: 0; +} +.rk-lido-wallets, +.rk-lido-accounts { + display: flex; + flex-direction: column; + gap: 8px; +} +.rk-lido-empty { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + padding: 12px 0 24px 0; + text-align: center; +} +.rk-lido-dialog .rk-lido-wallet, +.rk-lido-dialog .rk-lido-account { + width: 100%; + min-width: 0; + height: 56px; + padding: 8px 24px 8px 12px; + border: 1px solid var(--rk-lido-wallet-border); + border-radius: 16px; + color: var(--lido-app-ui-color-text-default); + font-size: 14px; + line-height: 22px; +} +.rk-lido-wallet > span, +.rk-lido-account > span { + width: 100%; + padding: 0; + gap: 12px; +} +.rk-lido-dialog .rk-lido-wallet:focus-visible, +.rk-lido-dialog .rk-lido-account:focus-visible { + outline: 2px solid var(--lido-app-ui-color-border-active); + outline-offset: -2px; +} +.rk-lido-dialog .rk-lido-wallet:disabled, +.rk-lido-dialog .rk-lido-account:disabled { + background: transparent; + color: var(--lido-app-ui-color-text-default); + opacity: 0.5; +} +/* The wallet that connects now has a gray background, so it shows as selected. */ +.rk-lido-dialog .rk-lido-wallet[aria-busy='true'] { + background: var(--lido-app-ui-color-background-default); + opacity: 1; + cursor: wait; +} +.rk-lido-wallet-icon { + display: inline-flex; + flex-shrink: 0; + width: 40px; + height: 40px; + align-items: center; + justify-content: center; +} +.rk-lido-wallet-icon > img, +.rk-lido-wallet-icon > svg { + width: 40px; + height: 40px; + object-fit: contain; +} +.rk-lido-wallet-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.rk-lido-browser-icons { + display: grid; + grid-template-columns: repeat(2, 18px); + grid-template-rows: repeat(2, 18px); + gap: 4px; + width: 40px; + height: 40px; +} +.rk-lido-browser-icons > img, +.rk-lido-browser-icons > svg { + display: block; + width: 18px; + height: 18px; + border-radius: 50%; + object-fit: contain; +} +.rk-lido-connecting { + margin-left: auto; + color: var(--lido-app-ui-color-text-secondary); + font-size: 12px; + font-weight: 400; +} +.rk-lido-dialog .rk-lido-toggle { + display: flex; + width: fit-content; + /* The list adds 2px below. This makes both gaps 16px. */ + margin: 16px auto 14px; + padding: 8px 12px; + font-size: 14px; + line-height: 22px; +} +.rk-lido-toggle > span { + gap: 6px; +} +.rk-lido-toggle svg { + width: 20px; + height: 20px; +} +.rk-lido-wallet-help { + display: block; + text-align: center; + padding-bottom: 24px; +} +.rk-lido-screen { + display: flex; + flex-direction: column; + gap: 20px; +} +.rk-lido-path { + margin: 0; + padding: 0; + min-width: 0; + border: 0; +} +.rk-lido-path legend { + margin-bottom: 8px; + padding: 0; + color: var(--lido-app-ui-color-text-secondary); + font-size: 12px; + line-height: 20px; +} +.rk-lido-path [aria-haspopup='listbox'] { + height: 34px; + border-radius: 8px; + padding: 6px 16px; +} +.rk-lido-path-label { + font-size: 14px; + line-height: 22px; + font-weight: 400; +} +.rk-lido-ledger-accounts { + gap: 24px; +} +.rk-lido-account { + font-weight: 400; +} +.rk-lido-account-icon { + width: 40px; + height: 40px; + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--lido-app-ui-color-text-default); +} +.rk-lido-account-address { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.rk-lido-account-balance { + margin-left: auto; + white-space: nowrap; +} +/* Same size and frame as an account button. */ +.rk-lido-account-skeleton { + display: flex; + align-items: center; + gap: 12px; + box-sizing: border-box; + height: 56px; + padding: 8px 24px 8px 12px; + border: 1px solid var(--rk-lido-wallet-border); + border-radius: 16px; +} +.rk-lido-account-skeleton .rk-lido-account-icon { + opacity: 0.3; +} +.rk-lido-skeleton-bar { + width: 136px; + height: 12px; + border-radius: 6px; + background: linear-gradient( + 90deg, + var(--lido-app-ui-color-background-default) 0%, + var(--lido-app-ui-color-background-default-hover) 50%, + var(--lido-app-ui-color-background-default) 100% + ) + 0 0 / 200% 100%; + animation: rk-lido-shimmer 1.5s ease-in-out infinite; +} +.rk-lido-skeleton-bar-short { + width: 64px; + margin-left: auto; +} +@keyframes rk-lido-shimmer { + to { + background-position: -200% 0; + } +} +@media (prefers-reduced-motion: reduce) { + .rk-lido-skeleton-bar { + animation: none; + } +} +.rk-lido-visually-hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; +} +.rk-lido-pagination { + display: flex; + gap: 16px; + align-items: center; + justify-content: center; +} +.rk-lido-page-label { + display: flex; + align-items: center; + gap: 10px; +} +.rk-lido-page-label input { + box-sizing: border-box; + width: 50px; + height: 34px; + padding: 6px; + background: var(--lido-app-ui-color-background-surface); + color: inherit; + border: 1px solid var(--lido-app-ui-color-border-default); + border-radius: 6px; + font: inherit; + text-align: center; + appearance: textfield; +} +.rk-lido-page-label input::-webkit-inner-spin-button, +.rk-lido-page-label input::-webkit-outer-spin-button { + appearance: none; +} +.rk-lido-page-label input:focus-visible { + outline: 2px solid var(--lido-app-ui-color-border-active); + outline-offset: 2px; +} +.rk-lido-previous-page-icon { + transform: rotate(180deg); +} +.rk-lido-pagination button:disabled { + opacity: 0.3; +} +.rk-lido-ledger-image { + height: 100px; + display: flex; + align-items: center; + justify-content: center; + color: var(--lido-app-ui-color-text-default); +} +.rk-lido-ledger-image svg { + max-width: 100%; +} +.rk-lido-description { + color: var(--lido-app-ui-color-text-secondary); + text-align: center; + font-weight: 400; +} +.rk-lido-dialog .rk-lido-action { + width: 100%; + min-height: 50px; + padding: 13px 24px; + line-height: 24px; +} +.rk-lido-requirements { + display: flex; + flex-direction: column; + gap: 24px; +} +.rk-lido-requirements-content { + display: flex; + flex-direction: column; + gap: 16px; + align-items: center; +} +/* Status screens: title, 24px, icon, 16px, text, 24px, button, 32px padding. */ +.rk-lido-overlay[data-screen='requirements'] .rk-lido-dialog, +.rk-lido-overlay[data-screen='connection-error'] .rk-lido-dialog { + gap: 24px; +} +.rk-lido-error { + color: var(--lido-app-ui-color-text-error); + overflow-wrap: anywhere; +} +.rk-lido-connection-error { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + overflow-wrap: anywhere; +} +.rk-lido-status-icon { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 64px; + height: 64px; + border-radius: 50%; + background: var(--lido-app-ui-color-background-default); + color: var(--lido-app-ui-color-icons-default); +} +.rk-lido-status-icon svg { + width: 32px; + height: 32px; +} +.rk-lido-status-icon-warning { + background: var(--lido-app-ui-color-tint-warning); + color: var(--lido-app-ui-color-icons-warning); +} +@media (max-width: 599px) { + .rk-lido-overlay { + padding: 0; + } + .rk-lido-dialog-container { + margin: 0; + display: flex; + } + .rk-lido-dialog-container .rk-lido-dialog { + padding: 20px; + min-height: 100dvh; + border-radius: 0; + } + .rk-lido-body { + flex: 1; + min-height: 0; + } + .rk-lido-search { + flex-wrap: wrap; + } + /* The wallet list fills the screen and scrolls inside the dialog. */ + .rk-lido-dialog-container .rk-lido-dialog:has(.rk-lido-picker) { + height: 100dvh; + } + .rk-lido-picker, + .rk-lido-picker-content { + flex: 1; + min-height: 0; + } + .rk-lido-picker-list, + .rk-lido-picker-list[data-expanded='true'] { + flex: 1; + max-height: none; + } + .rk-lido-requirements { + flex: 1; + } + .rk-lido-requirements-content { + flex: 1; + justify-content: center; + } + .rk-lido-requirements .rk-lido-action { + margin-bottom: 90px; + } + .rk-lido-connection-error { + flex: 1; + justify-content: center; + padding-bottom: 90px; + } + .rk-lido-ledger-connection { + margin-top: auto; + margin-bottom: auto; + } +} +@media (max-height: 640px) and (min-width: 600px) { + .rk-lido-dialog-container { + margin-top: 0; + margin-bottom: 0; + } +} diff --git a/packages/connect-wallet-modal/tsconfig.json b/packages/ui-lido/tsconfig.json similarity index 100% rename from packages/connect-wallet-modal/tsconfig.json rename to packages/ui-lido/tsconfig.json diff --git a/packages/ui-lido/tsdown.config.ts b/packages/ui-lido/tsdown.config.ts new file mode 100644 index 00000000..53a362dc --- /dev/null +++ b/packages/ui-lido/tsdown.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'tsdown'; +import { defineStandardConfig } from 'build-config'; +const config = defineStandardConfig(); +export default defineConfig({ + ...config, + entry: ['src/index.tsx'], + // Native copy entries are also watched, including files outside the import graph. + copy: ['src/styles.css'], +}); diff --git a/packages/ui-lido/vitest.config.ts b/packages/ui-lido/vitest.config.ts new file mode 100644 index 00000000..8d1846af --- /dev/null +++ b/packages/ui-lido/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; +export default defineConfig({ + test: { + environment: 'happy-dom', + include: ['src/**/*.test.tsx'], + server: { deps: { inline: [/@lidofinance\/lido-app-ui/, /@ledgerhq\//] } }, + }, +}); diff --git a/packages/ui-react/.eslintrc.json b/packages/ui-react/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/ui-react/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/ui-react/CHANGELOG.md b/packages/ui-react/CHANGELOG.md deleted file mode 100644 index fa2921ab..00000000 --- a/packages/ui-react/CHANGELOG.md +++ /dev/null @@ -1,145 +0,0 @@ -# @reef-knot/ui-react - -## 3.2.0 - -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update peerDependencies requirements: viem >=2.50, wagmi >=3.6 - -## 3.1.0 - -- Add accessible labels to modal close and back icon buttons. - -## 3.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 2.3.0 - -### Minor Changes - -- Technical version update - -## 2.2.0 - -### Minor Changes - -- Update viem to v2.23 and wagmi to v2.14, so the @coinbase/wallet-sdk would be updated too, which fixes a dependabot issue - -## 2.1.5 - -### Patch Changes - -- accbcde: viem and wagmi versions updated with flexible declarations - -## 2.1.4 - -### Patch Changes - -- 357e61f: Fix padding in ModalSubtitleStyle - -## 2.1.3 - -### Patch Changes - -- Remove unused react-is from deps - -## 2.1.2 - -### Patch Changes - -- Wallets modal scroll lock condition fixed - -## 2.1.1 - -### Patch Changes - -- Wagmi version updated - -## 2.1.0 - -### Minor Changes - -- Remove WC warning banner - -## 2.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -## 1.1.0 - -### Minor Changes - -- connect-wallet-modal ui and config updated - -## 1.0.8 - -### Patch Changes - -- 253796d: Fix typings - -## 1.0.7 - -### Patch Changes - -- 48d8c4b: Update wagmi to 0.12.19 - -## 1.0.6 - -### Patch Changes - -- e6e579e: wagmi 0.12.18 - -## 1.0.5 - -### Patch Changes - -- WC notification text update - -## 1.0.4 - -### Patch Changes - -- Add a notification about WC v2 issues - -## 1.0.3 - -### Patch Changes - -- Explicitly set `box-sizing: content-box` for Modal - -## 1.0.2 - -### Patch Changes - -- Fix modal width. - -## 1.0.1 - -### Patch Changes - -- Set typescript compilerOptions.jsx = "react" - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes - -## 0.2.0 - -### Minor Changes - -- Improve the modal's styles, rework scroll behavior diff --git a/packages/ui-react/README.md b/packages/ui-react/README.md deleted file mode 100644 index b722f4b9..00000000 --- a/packages/ui-react/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# @reef-knot/ui-react -> React components for Reef Knot diff --git a/packages/ui-react/src/hooks/useLockScroll.ts b/packages/ui-react/src/hooks/useLockScroll.ts deleted file mode 100644 index 30dea860..00000000 --- a/packages/ui-react/src/hooks/useLockScroll.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { useCallback, useLayoutEffect } from 'react'; - -const getScrollbarSize = (): number => { - const tempDiv = document.createElement('div'); - - Object.assign(tempDiv.style, { - position: 'absolute', - left: '-9000px', - width: '100px', - height: '100px', - overflow: 'scroll', - }); - - document.body.appendChild(tempDiv); - const scrollbarSize = tempDiv.offsetWidth - tempDiv.clientWidth; - document.body.removeChild(tempDiv); - - return scrollbarSize; -}; - -const isVerticalScroll = (element: HTMLElement): boolean => { - const isBody = document.body === element; - - return isBody - ? document.documentElement.scrollHeight > window.innerHeight - : element.scrollHeight > element.clientHeight; -}; - -const getPaddingRight = (element: HTMLElement): number => { - return parseInt(window.getComputedStyle(element).paddingRight, 10) || 0; -}; - -const setStyleProperty = ( - element: HTMLElement, - property: string, - value?: string, -): void => { - if (value) { - element.style.setProperty(property, value); - } else { - element.style.removeProperty(property); - } -}; - -export const useLockScroll = (element: HTMLElement = document.body): void => { - const lockScroll = useCallback(() => { - if (!isVerticalScroll(element)) return; - - const previousValues = { - paddingRight: element.style.paddingRight, - overflow: element.style.overflow, - }; - - const newPaddingRight = getPaddingRight(element) + getScrollbarSize(); - setStyleProperty(element, 'padding-right', `${newPaddingRight}px`); - setStyleProperty(element, 'overflow', 'hidden'); - - const unlockScroll = () => { - const { paddingRight, overflow } = previousValues; - - setStyleProperty(element, 'padding-right', paddingRight); - setStyleProperty(element, 'overflow', overflow); - }; - - return unlockScroll; - }, [element]); - - useLayoutEffect(() => { - const unlockScroll = lockScroll(); - return unlockScroll; - }, [lockScroll]); -}; diff --git a/packages/ui-react/tsconfig.json b/packages/ui-react/tsconfig.json deleted file mode 100644 index 23709e73..00000000 --- a/packages/ui-react/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], - "compilerOptions": { - "rootDir": "src", - } -} diff --git a/packages/ui-react/tsdown.config.ts b/packages/ui-react/tsdown.config.ts deleted file mode 100644 index 57dae503..00000000 --- a/packages/ui-react/tsdown.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; - -export default defineConfig(defineStandardConfig()); diff --git a/packages/wallets-helpers/.eslintrc.json b/packages/wallets-helpers/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/wallets-helpers/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/wallets-helpers/CHANGELOG.md b/packages/wallets-helpers/CHANGELOG.md index cfd52550..8f52801e 100644 --- a/packages/wallets-helpers/CHANGELOG.md +++ b/packages/wallets-helpers/CHANGELOG.md @@ -1,5 +1,21 @@ # @reef-knot/wallets-helpers +## 3.2.0 + +### Breaking changes + +- Remove `getWalletConnectUri` and the `walletconnectExtras` adapter option. Use the standard WalletConnect connection flow. + +### Added + +- Export the shared wallet adapter types previously provided by `@reef-knot/types`. +- Include `mipd` as a dependency so the exported provider-store types are available to consumers. + +### Fixed + +- Cache WalletConnect connectors by project ID and QR modal setting so separate configurations do not share the wrong connector. +- Keep EIP-6963 connections tied to the requested wallet when its provider is missing, instead of falling back to another browser wallet. + ## 3.1.0 - Update wagmi to 3.6.21 diff --git a/packages/wallets-helpers/README.md b/packages/wallets-helpers/README.md index b733ceb4..124f949b 100644 --- a/packages/wallets-helpers/README.md +++ b/packages/wallets-helpers/README.md @@ -1,3 +1,14 @@ # Wallets Helpers +Shared runtime helpers and TypeScript contracts for Reef Knot wallet adapters. +```ts +import type { + WalletAdapterArgs, + WalletAdapterData, + WalletAdapterIcons, + WalletAdapterType, +} from '@reef-knot/wallets-helpers'; +``` + +This package is independent of the Reef Knot UI and the default wallet catalog. diff --git a/packages/wallets-helpers/package.json b/packages/wallets-helpers/package.json index 501b2ce4..ecf20cfd 100644 --- a/packages/wallets-helpers/package.json +++ b/packages/wallets-helpers/package.json @@ -34,16 +34,19 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "test": "vitest run", + "typecheck": "yarn run -T tsc --noEmit" }, "dependencies": { "@types/ua-parser-js": "0.7.39", + "mipd": "0.0.7", "ua-parser-js": "1.0.37" }, "devDependencies": { "build-config": "*", - "eslint-config-custom": "*", + "react": "18.2.0", + "vitest": "^4.1.11", "wagmi": ">=3.6" }, "peerDependencies": { diff --git a/packages/wallets-helpers/src/index.ts b/packages/wallets-helpers/src/index.ts index 2526ce9c..afba5974 100644 --- a/packages/wallets-helpers/src/index.ts +++ b/packages/wallets-helpers/src/index.ts @@ -1,2 +1,3 @@ export * from './walletconnect'; export * from './utils'; +export * from './walletAdapter'; diff --git a/packages/wallets-helpers/src/utils/__tests__/eip6963.test.ts b/packages/wallets-helpers/src/utils/__tests__/eip6963.test.ts new file mode 100644 index 00000000..8021c2bf --- /dev/null +++ b/packages/wallets-helpers/src/utils/__tests__/eip6963.test.ts @@ -0,0 +1,67 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import type { EIP6963ProviderDetail, Store } from 'mipd'; +import { injected } from 'wagmi/connectors'; +import { mainnet } from 'wagmi/chains'; +import { getTargetEIP6963 } from '../eip6963'; + +const rdns = 'com.okex.wallet'; +const storeWith = (providers: EIP6963ProviderDetail[]) => + ({ + findProvider: ({ rdns: wanted }: { rdns: string }) => + providers.find((p) => p.info.rdns === wanted), + }) as unknown as Store; + +describe('getTargetEIP6963', () => { + it('targets the announced provider', () => { + const provider = { request: () => {} }; + const detail = { + info: { rdns, name: 'OKX Wallet' }, + provider, + } as unknown as EIP6963ProviderDetail; + const target = getTargetEIP6963(storeWith([detail]), rdns); + expect(target).toMatchObject({ id: rdns, name: 'OKX Wallet' }); + expect(target.provider()).toBe(provider); + }); + + it('returns a target without a provider when the wallet is not announced', () => { + // wagmi treats an undefined target as `window.ethereum`, so it must not be undefined. + const target = getTargetEIP6963(storeWith([]), rdns); + expect(target).toMatchObject({ id: rdns, name: rdns }); + expect(target.provider()).toBeUndefined(); + }); + + it('finds a provider announced after the target is created', () => { + const providers: EIP6963ProviderDetail[] = []; + const target = getTargetEIP6963(storeWith(providers), rdns); + const provider = { request: () => {} }; + providers.push({ + info: { rdns, name: 'OKX Wallet' }, + provider, + } as unknown as EIP6963ProviderDetail); + expect(target.provider()).toBe(provider); + }); +}); + +describe('injected connector with an EIP-6963 target', () => { + afterEach(() => vi.unstubAllGlobals()); + + it('does not authorize another wallet from window.ethereum', async () => { + // Another wallet owns `window.ethereum` and still authorizes the dApp. + const request = vi.fn(async () => [ + '0x0000000000000000000000000000000000000001', + ]); + vi.stubGlobal('window', { ethereum: { request, on: vi.fn() } }); + const createConnector = injected({ + target: () => getTargetEIP6963(storeWith([]), rdns), + }); + const connector = createConnector({ + chains: [mainnet], + emitter: { emit: vi.fn() }, + storage: { getItem: async () => null }, + } as unknown as Parameters[0]); + + expect(await connector.isAuthorized()).toBe(false); + expect(request).not.toHaveBeenCalled(); + expect(connector.id).toBe(rdns); + }); +}); diff --git a/packages/wallets-helpers/src/utils/eip6963.ts b/packages/wallets-helpers/src/utils/eip6963.ts index 6ac56b3a..6c63e948 100644 --- a/packages/wallets-helpers/src/utils/eip6963.ts +++ b/packages/wallets-helpers/src/utils/eip6963.ts @@ -1,12 +1,14 @@ import type { Store, Rdns } from 'mipd'; export const getTargetEIP6963 = (providersStore: Store, rdns: Rdns) => { - const providerDetail = providersStore.findProvider({ rdns }); - if (!providerDetail) return undefined; + const findProviderDetail = () => providersStore.findProvider({ rdns }); + // Never return undefined: wagmi then falls back to `window.ethereum`, + // which can belong to another wallet. return { - id: providerDetail.info.rdns, - name: providerDetail.info.name, - provider: providerDetail.provider, + id: rdns, + name: findProviderDetail()?.info.name ?? rdns, + // Look up again on each call. The wallet can announce after this target is created. + provider: () => findProviderDetail()?.provider, }; }; diff --git a/packages/wallets-helpers/src/utils/isValidHttpUrl.ts b/packages/wallets-helpers/src/utils/isValidHttpUrl.ts index fcf0cf2f..f55b22bd 100644 --- a/packages/wallets-helpers/src/utils/isValidHttpUrl.ts +++ b/packages/wallets-helpers/src/utils/isValidHttpUrl.ts @@ -2,7 +2,7 @@ export const isValidHttpUrl = (string: string) => { let url; try { url = new URL(string); - } catch (_) { + } catch { return false; } return url.protocol === 'http:' || url.protocol === 'https:'; diff --git a/packages/types/src/walletAdapter.ts b/packages/wallets-helpers/src/walletAdapter.ts similarity index 70% rename from packages/types/src/walletAdapter.ts rename to packages/wallets-helpers/src/walletAdapter.ts index 38865ca3..96e0f651 100644 --- a/packages/types/src/walletAdapter.ts +++ b/packages/wallets-helpers/src/walletAdapter.ts @@ -44,23 +44,6 @@ export type WalletAdapterData = { deeplink?: string; createConnectorFn: CreateConnectorFn; - - // Additional options for wallets based on WalletConnect - walletconnectExtras?: { - // Option for direct connection via WalletConnect (WC) URI (without QR code modal) - connectionViaURI?: { - // Should be WC connector with disabled QR code - createConnectorFn: CreateConnectorFn; - // In which case this connection type must be used instead the default connector - condition: boolean; - // Where to redirect when WC URI is ready - // WC URI will be added to then end of this link, - // so it should look similar to "https:///wc?uri=" - redirectLink: string; - // Close the new window, used for redirection, after successful connect - closeRedirectionWindow?: boolean; - }; - }; }; export interface WalletAdapterArgs { diff --git a/packages/wallets-helpers/src/walletconnect/__tests__/getWalletConnectConnector.test.ts b/packages/wallets-helpers/src/walletconnect/__tests__/getWalletConnectConnector.test.ts new file mode 100644 index 00000000..31545d67 --- /dev/null +++ b/packages/wallets-helpers/src/walletconnect/__tests__/getWalletConnectConnector.test.ts @@ -0,0 +1,76 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +const walletConnectMock = vi.hoisted(() => + Object.assign( + vi.fn((parameters: { projectId: string; showQrModal?: boolean }) => + // A fresh function per call, so factory identity is observable + Object.assign(() => ({}), { parameters }), + ), + { type: 'walletConnect' }, + ), +); + +vi.mock('wagmi/connectors', () => ({ walletConnect: walletConnectMock })); + +type Factory = { parameters: { projectId: string; showQrModal?: boolean } }; + +// The cache is module-global, so each test gets a fresh module instance +const load = async () => { + vi.resetModules(); + const mod = await import('../getWalletConnectConnector'); + return mod.getWalletConnectConnector; +}; + +describe('getWalletConnectConnector', () => { + beforeEach(() => { + walletConnectMock.mockClear(); + vi.spyOn(console, 'warn').mockImplementation(() => {}); + }); + + it('reuses the factory for the same projectId and QR mode', async () => { + const getConnector = await load(); + + const first = getConnector({ projectId: 'id-a' }); + const second = getConnector({ projectId: 'id-a' }); + + expect(second).toBe(first); + expect(walletConnectMock).toHaveBeenCalledTimes(1); + }); + + it('creates a new factory with the new projectId when it changes', async () => { + const getConnector = await load(); + + const first = getConnector({ projectId: 'id-a' }); + const second = getConnector({ projectId: 'id-b' }); + + expect(second).not.toBe(first); + expect((second as unknown as Factory).parameters.projectId).toBe('id-b'); + }); + + it('keys QR and non-QR factories separately', async () => { + const getConnector = await load(); + + const qr = getConnector({ projectId: 'id-a', qrcode: true }); + const noQr = getConnector({ projectId: 'id-a', qrcode: false }); + + expect(noQr).not.toBe(qr); + expect((noQr as unknown as Factory).parameters.showQrModal).toBe(false); + }); + + it('does not let an empty projectId shadow a later valid one', async () => { + const getConnector = await load(); + + const empty = getConnector({}); + const valid = getConnector({ projectId: 'id-a' }); + + expect(console.warn).toHaveBeenCalledTimes(1); + expect(valid).not.toBe(empty); + expect((valid as unknown as Factory).parameters.projectId).toBe('id-a'); + }); + + it('does not cache factories for an empty projectId', async () => { + const getConnector = await load(); + + expect(getConnector({})).not.toBe(getConnector({})); + }); +}); diff --git a/packages/wallets-helpers/src/walletconnect/getWalletConnectConnector.ts b/packages/wallets-helpers/src/walletconnect/getWalletConnectConnector.ts index a0f17fb8..c336a19f 100644 --- a/packages/wallets-helpers/src/walletconnect/getWalletConnectConnector.ts +++ b/packages/wallets-helpers/src/walletconnect/getWalletConnectConnector.ts @@ -2,12 +2,21 @@ import { walletConnect } from 'wagmi/connectors'; type WCConnector = ReturnType; -const cache: Record = {}; +// Reusing factories avoids repeated WalletConnect Core initialization. +// The key must include every factory input, otherwise a later config would get +// a factory bound to the first projectId seen in this runtime. +const cache = new Map(); -const memoize = (key: string, getter: () => WCConnector) => { - if (!cache[key]) cache[key] = getter(); - return cache[key]; -}; +const createConnector = (projectId: string, qrcode: boolean) => + walletConnect({ + projectId, + showQrModal: qrcode, + qrModalOptions: { + themeVariables: { + '--wcm-z-index': '1000', + }, + }, + }); getWalletConnectConnector.type = walletConnect.type; export function getWalletConnectConnector({ @@ -21,17 +30,15 @@ export function getWalletConnectConnector({ console.warn( 'No WalletConnect Project ID found, it is required by WalletConnect v2: https://docs.walletconnect.com/2.0/cloud/relay#project-id', ); + // Not cached, so a later config with a valid projectId is not shadowed + return createConnector(projectId, qrcode); } - return memoize(qrcode ? 'qrcode' : 'no-qrcode', () => - walletConnect({ - projectId, - showQrModal: qrcode, - qrModalOptions: { - themeVariables: { - '--wcm-z-index': '1000', - }, - }, - }), - ); + const key = `${projectId}:${qrcode ? 'qrcode' : 'no-qrcode'}`; + let connector = cache.get(key); + if (!connector) { + connector = createConnector(projectId, qrcode); + cache.set(key, connector); + } + return connector; } diff --git a/packages/wallets-helpers/src/walletconnect/getWalletConnectUri.ts b/packages/wallets-helpers/src/walletconnect/getWalletConnectUri.ts deleted file mode 100644 index 9df23002..00000000 --- a/packages/wallets-helpers/src/walletconnect/getWalletConnectUri.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { Connector } from 'wagmi'; - -export const getWalletConnectUri = async (connector: Connector) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const provider: any = await connector.getProvider(); - return new Promise((resolve) => { - provider.once('display_uri', resolve); - }); -}; diff --git a/packages/wallets-helpers/src/walletconnect/index.ts b/packages/wallets-helpers/src/walletconnect/index.ts index f87a4b4e..c2974b3b 100644 --- a/packages/wallets-helpers/src/walletconnect/index.ts +++ b/packages/wallets-helpers/src/walletconnect/index.ts @@ -1,2 +1 @@ export * from './getWalletConnectConnector'; -export * from './getWalletConnectUri'; diff --git a/packages/wallets-helpers/tsconfig.json b/packages/wallets-helpers/tsconfig.json index 23709e73..8acf31ca 100644 --- a/packages/wallets-helpers/tsconfig.json +++ b/packages/wallets-helpers/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "tsconfig/react-library.json", "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], + "exclude": ["node_modules", "dist"], "compilerOptions": { "rootDir": "src", } diff --git a/packages/wallets-helpers/vitest.config.ts b/packages/wallets-helpers/vitest.config.ts new file mode 100644 index 00000000..6ec74eee --- /dev/null +++ b/packages/wallets-helpers/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['src/**/*.test.ts'], + }, +}); diff --git a/packages/wallets-icons/.eslintrc.json b/packages/wallets-icons/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/wallets-icons/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/wallets-icons/CHANGELOG.md b/packages/wallets-icons/CHANGELOG.md deleted file mode 100644 index d947dcb7..00000000 --- a/packages/wallets-icons/CHANGELOG.md +++ /dev/null @@ -1,70 +0,0 @@ -# @reef-knot/wallets-icons - -## 2.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 1.7.0 - -### Minor Changes - -- Technical version update - -## 1.6.0 - -### Minor Changes - -- DEPRECATE - -## 1.5.0 - -### Minor Changes - -- Remove Coinbase related code - -## 1.4.0 - -### Minor Changes - -- Remove XDEFI, Trust, imToken icons - -## 1.3.0 - -### Minor Changes - -- Remove MathWallet related code - -## 1.2.0 - -### Minor Changes - -- Remove Brave, Coin98, Opera, Gamestop wallets unneeded legacy code - -## 1.1.0 - -### Minor Changes - -- Update XDEFI and Trust logo, remove not used logos - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes - -## 0.2.0 - -### Minor Changes - -- Add Zerion wallet diff --git a/packages/wallets-icons/LICENSE.txt b/packages/wallets-icons/LICENSE.txt deleted file mode 100644 index 9a459058..00000000 --- a/packages/wallets-icons/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Lido - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/wallets-icons/README.md b/packages/wallets-icons/README.md deleted file mode 100644 index 3dca2cc8..00000000 --- a/packages/wallets-icons/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Wallets Icons [Deprecated] - -## Deprecation notice -The icons from this package is moved to wallet adapters. -Do not use this package. diff --git a/packages/wallets-icons/package.json b/packages/wallets-icons/package.json deleted file mode 100644 index 0a500c67..00000000 --- a/packages/wallets-icons/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@reef-knot/wallets-icons", - "version": "0.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "exports": { - ".": "./dist/index.js", - "./react": "./dist/react/index.js", - "./svg/*": "./dist/svg/*" - }, - "typesVersions": { - "*": { - ".": [ - "dist/index.d.ts" - ], - "react": [ - "dist/react/index.d.ts" - ], - "svg/*": [ - "dist/svg/*" - ] - } - }, - "type": "module", - "files": [ - "dist" - ], - "license": "MIT", - "homepage": "https://github.com/lidofinance/reef-knot", - "repository": { - "type": "git", - "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/wallets-icons" - }, - "bugs": { - "url": "https://github.com/lidofinance/reef-knot/issues" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public" - }, - "scripts": { - "build": "yarn run -T tsdown && cp src/svg/*.svg dist/svg/", - "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" - }, - "peerDependencies": { - "react": ">=18" - }, - "devDependencies": { - "build-config": "*", - "eslint-config-custom": "*", - "react": "18.2.0" - } -} diff --git a/packages/wallets-icons/src/custom.d.ts b/packages/wallets-icons/src/custom.d.ts deleted file mode 100644 index 006534e2..00000000 --- a/packages/wallets-icons/src/custom.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.svg' { - const content: React.FunctionComponent>; - export default content; -} diff --git a/packages/wallets-icons/src/index.ts b/packages/wallets-icons/src/index.ts deleted file mode 100644 index 3876a4d0..00000000 --- a/packages/wallets-icons/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as WalletsIconsReact from './react'; diff --git a/packages/wallets-icons/src/react/index.ts b/packages/wallets-icons/src/react/index.ts deleted file mode 100644 index 11e801ac..00000000 --- a/packages/wallets-icons/src/react/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { default as Ledger } from '../svg/ledger.svg'; -export { default as LedgerInversion } from '../svg/ledger-inversion.svg'; -export { default as LedgerConfirm } from '../svg/ledger-confirm.svg'; -export { default as LedgerFail } from '../svg/ledger-fail.svg'; -export { default as LedgerLoading } from '../svg/ledger-loading.svg'; -export { default as LedgerSuccess } from '../svg/ledger-success.svg'; -export { default as MetaMask } from '../svg/metamask.svg'; -export { default as MetaMaskCircle } from '../svg/metamask-circle.svg'; -export { default as MetaMaskCircleInversion } from '../svg/metamask-circle-inversion.svg'; diff --git a/packages/wallets-icons/src/svg/ledger-confirm.svg b/packages/wallets-icons/src/svg/ledger-confirm.svg deleted file mode 100644 index 9db59e1a..00000000 --- a/packages/wallets-icons/src/svg/ledger-confirm.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/ledger-fail.svg b/packages/wallets-icons/src/svg/ledger-fail.svg deleted file mode 100644 index fce3a92b..00000000 --- a/packages/wallets-icons/src/svg/ledger-fail.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/ledger-inversion.svg b/packages/wallets-icons/src/svg/ledger-inversion.svg deleted file mode 100644 index f2a31180..00000000 --- a/packages/wallets-icons/src/svg/ledger-inversion.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/wallets-icons/src/svg/ledger-loading.svg b/packages/wallets-icons/src/svg/ledger-loading.svg deleted file mode 100644 index 1515edc5..00000000 --- a/packages/wallets-icons/src/svg/ledger-loading.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/ledger-success.svg b/packages/wallets-icons/src/svg/ledger-success.svg deleted file mode 100644 index ba8aa058..00000000 --- a/packages/wallets-icons/src/svg/ledger-success.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/ledger.svg b/packages/wallets-icons/src/svg/ledger.svg deleted file mode 100644 index 1b3ddb69..00000000 --- a/packages/wallets-icons/src/svg/ledger.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/wallets-icons/src/svg/metamask-circle-inversion.svg b/packages/wallets-icons/src/svg/metamask-circle-inversion.svg deleted file mode 100644 index b0822d37..00000000 --- a/packages/wallets-icons/src/svg/metamask-circle-inversion.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/metamask-circle.svg b/packages/wallets-icons/src/svg/metamask-circle.svg deleted file mode 100644 index 8cd45b8d..00000000 --- a/packages/wallets-icons/src/svg/metamask-circle.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/wallets-icons/src/svg/metamask.svg b/packages/wallets-icons/src/svg/metamask.svg deleted file mode 100644 index 1b2f9a64..00000000 --- a/packages/wallets-icons/src/svg/metamask.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/wallets-icons/tsdown.config.ts b/packages/wallets-icons/tsdown.config.ts deleted file mode 100644 index b9e96431..00000000 --- a/packages/wallets-icons/tsdown.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineSvgConfig } from 'build-config'; - -export default defineConfig( - defineSvgConfig({ ref: true }, { - entry: { - 'index': 'src/index.ts', - 'react/index': 'src/react/index.ts', - }, - }), -); diff --git a/packages/wallets-list/.eslintrc.json b/packages/wallets-list/.eslintrc.json deleted file mode 100644 index 027a4246..00000000 --- a/packages/wallets-list/.eslintrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ] -} diff --git a/packages/wallets-list/CHANGELOG.md b/packages/wallets-list/CHANGELOG.md deleted file mode 100644 index 6edfc688..00000000 --- a/packages/wallets-list/CHANGELOG.md +++ /dev/null @@ -1,533 +0,0 @@ -# @reef-knot/wallets-list - -## 5.2.0 - -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update peerDependencies requirements: viem >=2.50, wagmi >=3.6 - -## 5.1.0 - -- Add support for Anchorage Digital wallet - -## 5.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 4.2.0 - -### Minor Changes - -- Technical version update - -## 4.1.2 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-coinbase-smart-wallet@3.1.0 - - @reef-knot/wallet-adapter-dapp-browser-injected@4.1.0 - - @reef-knot/wallet-adapter-browser-extension@4.1.0 - - @reef-knot/wallet-adapter-binance-wallet@3.1.0 - - @reef-knot/wallet-adapter-walletconnect@4.1.0 - - @reef-knot/wallet-adapter-ledger-live@5.1.0 - - @reef-knot/wallet-adapter-ledger-hid@5.1.0 - - @reef-knot/wallet-adapter-coinbase@4.1.0 - - @reef-knot/wallet-adapter-metamask@4.1.0 - - @reef-knot/wallet-adapter-bitkeep@4.1.0 - - @reef-knot/wallet-adapter-imtoken@4.1.0 - - @reef-knot/wallet-adapter-ambire@5.1.0 - - @reef-knot/wallet-adapter-coin98@4.1.0 - - @reef-knot/wallet-adapter-exodus@4.1.0 - - @reef-knot/wallet-adapter-brave@4.1.0 - - @reef-knot/wallet-adapter-trust@4.1.0 - - @reef-knot/wallet-adapter-ctrl@1.1.0 - - @reef-knot/wallet-adapter-safe@4.1.0 - - @reef-knot/wallet-adapter-okx@4.1.0 - -## 4.1.1 - -### Patch Changes - -- Updated dependencies [c5965d1] - - @reef-knot/wallet-adapter-ambire@5.0.0 - -## 4.1.0 - -### Minor Changes - -- Add Ctrl wallet, rm XDEFI wallet (rebranded into Ctrl) - -## 4.0.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/types@4.0.0 - - @reef-knot/wallet-adapter-ambire@4.0.0 - - @reef-knot/wallet-adapter-binance-wallet@3.0.0 - - @reef-knot/wallet-adapter-bitkeep@4.0.0 - - @reef-knot/wallet-adapter-brave@4.0.0 - - @reef-knot/wallet-adapter-browser-extension@4.0.0 - - @reef-knot/wallet-adapter-coin98@4.0.0 - - @reef-knot/wallet-adapter-coinbase@4.0.0 - - @reef-knot/wallet-adapter-coinbase-smart-wallet@3.0.0 - - @reef-knot/wallet-adapter-dapp-browser-injected@4.0.0 - - @reef-knot/wallet-adapter-exodus@4.0.0 - - @reef-knot/wallet-adapter-imtoken@4.0.0 - - @reef-knot/wallet-adapter-ledger-hid@5.0.0 - - @reef-knot/wallet-adapter-ledger-live@5.0.0 - - @reef-knot/wallet-adapter-metamask@4.0.0 - - @reef-knot/wallet-adapter-okx@4.0.0 - - @reef-knot/wallet-adapter-safe@4.0.0 - - @reef-knot/wallet-adapter-trust@4.0.0 - - @reef-knot/wallet-adapter-walletconnect@4.0.0 - - @reef-knot/wallet-adapter-xdefi@4.0.0 - -## 3.0.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/types@3.0.0 - - @reef-knot/wallet-adapter-ambire@3.0.0 - - @reef-knot/wallet-adapter-binance-wallet@2.0.0 - - @reef-knot/wallet-adapter-bitkeep@3.0.0 - - @reef-knot/wallet-adapter-brave@3.0.0 - - @reef-knot/wallet-adapter-browser-extension@3.0.0 - - @reef-knot/wallet-adapter-coin98@3.0.0 - - @reef-knot/wallet-adapter-coinbase@3.0.0 - - @reef-knot/wallet-adapter-coinbase-smart-wallet@2.0.0 - - @reef-knot/wallet-adapter-dapp-browser-injected@3.0.0 - - @reef-knot/wallet-adapter-exodus@3.0.0 - - @reef-knot/wallet-adapter-imtoken@3.0.0 - - @reef-knot/wallet-adapter-ledger-hid@4.0.0 - - @reef-knot/wallet-adapter-ledger-live@4.0.0 - - @reef-knot/wallet-adapter-metamask@3.0.0 - - @reef-knot/wallet-adapter-okx@3.0.0 - - @reef-knot/wallet-adapter-safe@3.0.0 - - @reef-knot/wallet-adapter-trust@3.0.0 - - @reef-knot/wallet-adapter-walletconnect@3.0.0 - - @reef-knot/wallet-adapter-xdefi@3.0.0 - -## 2.3.1 - -### Patch Changes - -- Updated dependencies [accbcde] - - @reef-knot/wallet-adapter-dapp-browser-injected@2.0.2 - - @reef-knot/wallet-adapter-browser-extension@2.0.2 - - @reef-knot/wallet-adapter-walletconnect@2.0.2 - - @reef-knot/wallet-adapter-ledger-live@3.0.2 - - @reef-knot/wallet-adapter-ledger-hid@3.0.2 - - @reef-knot/wallet-adapter-coinbase@2.2.1 - - @reef-knot/wallet-adapter-metamask@2.1.1 - - @reef-knot/wallet-adapter-bitkeep@2.1.1 - - @reef-knot/wallet-adapter-imtoken@2.0.2 - - @reef-knot/wallet-adapter-ambire@2.0.2 - - @reef-knot/wallet-adapter-coin98@2.1.1 - - @reef-knot/wallet-adapter-exodus@2.1.1 - - @reef-knot/wallet-adapter-brave@2.1.1 - - @reef-knot/wallet-adapter-trust@2.1.1 - - @reef-knot/wallet-adapter-xdefi@2.1.1 - - @reef-knot/wallet-adapter-safe@2.0.2 - - @reef-knot/wallet-adapter-okx@2.1.1 - -## 2.3.0 - -### Minor Changes - -- Coinbase smart wallet connector - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-coinbase-smart-wallet@1.0.0 - - @reef-knot/wallet-adapter-coinbase@2.2.0 - -## 2.2.3 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-binance-wallet@1.0.3 - -## 2.2.2 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-binance-wallet@1.0.2 - -## 2.2.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-binance-wallet@1.0.1 - -## 2.2.0 - -### Minor Changes - -- Add Binance Web3 Wallet - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-binance-wallet@1.1.0 - -## 2.1.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-coinbase@2.1.0 - - @reef-knot/wallet-adapter-metamask@2.1.0 - - @reef-knot/wallet-adapter-bitkeep@2.1.0 - - @reef-knot/wallet-adapter-coin98@2.1.0 - - @reef-knot/wallet-adapter-exodus@2.1.0 - - @reef-knot/wallet-adapter-brave@2.1.0 - - @reef-knot/wallet-adapter-trust@2.1.0 - - @reef-knot/wallet-adapter-xdefi@2.1.0 - - @reef-knot/wallet-adapter-okx@2.1.0 - -## 2.0.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-dapp-browser-injected@2.0.1 - - @reef-knot/wallet-adapter-browser-extension@2.0.1 - - @reef-knot/wallet-adapter-walletconnect@2.0.1 - - @reef-knot/wallet-adapter-ledger-live@3.0.1 - - @reef-knot/wallet-adapter-ledger-hid@3.0.1 - - @reef-knot/wallet-adapter-coinbase@2.0.1 - - @reef-knot/wallet-adapter-metamask@2.0.1 - - @reef-knot/wallet-adapter-bitkeep@2.0.1 - - @reef-knot/wallet-adapter-imtoken@2.0.1 - - @reef-knot/wallet-adapter-ambire@2.0.1 - - @reef-knot/wallet-adapter-coin98@2.0.1 - - @reef-knot/wallet-adapter-exodus@2.0.1 - - @reef-knot/wallet-adapter-brave@2.0.1 - - @reef-knot/wallet-adapter-trust@2.0.1 - - @reef-knot/wallet-adapter-xdefi@2.0.1 - - @reef-knot/wallet-adapter-safe@2.0.1 - - @reef-knot/wallet-adapter-okx@2.0.1 - -## 2.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-dapp-browser-injected@2.0.0 - - @reef-knot/wallet-adapter-browser-extension@2.0.0 - - @reef-knot/wallet-adapter-walletconnect@2.0.0 - - @reef-knot/wallet-adapter-ledger-live@3.0.0 - - @reef-knot/wallet-adapter-ledger-hid@3.0.0 - - @reef-knot/wallet-adapter-coinbase@2.0.0 - - @reef-knot/wallet-adapter-metamask@2.0.0 - - @reef-knot/wallet-adapter-bitkeep@2.0.0 - - @reef-knot/wallet-adapter-imtoken@2.0.0 - - @reef-knot/wallet-adapter-ambire@2.0.0 - - @reef-knot/wallet-adapter-coin98@2.0.0 - - @reef-knot/wallet-adapter-exodus@2.0.0 - - @reef-knot/wallet-adapter-brave@2.0.0 - - @reef-knot/wallet-adapter-trust@2.0.0 - - @reef-knot/wallet-adapter-xdefi@2.0.0 - - @reef-knot/wallet-adapter-safe@2.0.0 - - @reef-knot/wallet-adapter-okx@2.0.0 - - @reef-knot/types@2.0.0 - -## 1.13.3 - -### Patch Changes - -- Updated dependencies [a6ca608] - - @reef-knot/wallet-adapter-metamask@1.2.0 - - @reef-knot/wallet-adapter-bitkeep@1.3.0 - - @reef-knot/wallet-adapter-imtoken@1.2.0 - - @reef-knot/wallet-adapter-coin98@1.2.0 - - @reef-knot/wallet-adapter-trust@1.2.0 - - @reef-knot/wallet-adapter-okx@1.5.0 - -## 1.13.2 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-dapp-browser-injected@1.1.1 - - @reef-knot/wallet-adapter-walletconnect@1.3.1 - - @reef-knot/wallet-adapter-ambire@1.3.1 - -## 1.13.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-safe@1.2.0 - -## 1.13.0 - -### Minor Changes - -- wallet connectors id exports and typings updated - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-dapp-browser-injected@1.1.0 - - @reef-knot/wallet-adapter-browser-extension@1.1.0 - - @reef-knot/wallet-adapter-walletconnect@1.3.0 - - @reef-knot/wallet-adapter-ledger-live@2.1.0 - - @reef-knot/wallet-adapter-ledger-hid@2.1.0 - - @reef-knot/wallet-adapter-coinbase@1.1.0 - - @reef-knot/wallet-adapter-metamask@1.1.0 - - @reef-knot/wallet-adapter-bitkeep@1.2.0 - - @reef-knot/wallet-adapter-imtoken@1.1.0 - - @reef-knot/wallet-adapter-ambire@1.3.0 - - @reef-knot/wallet-adapter-coin98@1.1.0 - - @reef-knot/wallet-adapter-exodus@1.3.0 - - @reef-knot/wallet-adapter-brave@1.1.0 - - @reef-knot/wallet-adapter-trust@1.1.0 - - @reef-knot/wallet-adapter-xdefi@1.1.0 - - @reef-knot/wallet-adapter-safe@1.1.0 - - @reef-knot/wallet-adapter-okx@1.4.0 - -## 1.12.0 - -### Minor Changes - -- 1046886: Add wallet adapters: Ledger Live, dappBrowserInjected, Safe - -### Patch Changes - -- @reef-knot/wallet-adapter-ledger-hid@2.0.0 -- @reef-knot/wallet-adapter-ledger-live@2.0.0 - -## 1.11.1 - -### Patch Changes - -- Fix name of the 'wallet-adapter-browser-extension' package - -## 1.11.0 - -### Minor Changes - -- 253796d: Add MetaMask and generic browser extension wallet adapters - -## 1.10.0 - -### Minor Changes - -- Use Ledger hid wallet adapter, based on wagmi - -## 1.9.0 - -### Minor Changes - -- Rework Coinbase to use Wallet Adapter - -## 1.8.0 - -### Minor Changes - -- Rework XDEFI, Trust, imToken to use Wallet Adapters and wagmi - -## 1.7.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-bitkeep@1.1.1 - - @reef-knot/wallet-adapter-coin98@1.0.1 - - @reef-knot/wallet-adapter-exodus@1.2.4 - - @reef-knot/wallet-adapter-brave@1.0.1 - - @reef-knot/wallet-adapter-okx@1.3.1 - -## 1.7.0 - -### Minor Changes - -- Remove zerion, blockchain.com, phantom, taho, zengo imports - -## 1.6.0 - -### Minor Changes - -- Add Brave wallet - -## 1.5.0 - -### Minor Changes - -- e2074ed: Make Coin98 wallet to use Wallet Adapter API - -### Patch Changes - -- Updated dependencies [e2074ed] - - @reef-knot/wallet-adapter-coin98@1.0.0 - -## 1.4.5 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-bitkeep@1.1.0 - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [e654dc5] -- Updated dependencies [48d8c4b] - - @reef-knot/wallet-adapter-phantom@1.3.0 - - @reef-knot/wallet-adapter-okx@1.3.0 - - @reef-knot/wallet-adapter-blockchaincom@1.2.4 - - @reef-knot/wallet-adapter-walletconnect@1.2.4 - - @reef-knot/wallet-adapter-bitkeep@1.0.1 - - @reef-knot/wallet-adapter-ambire@1.2.4 - - @reef-knot/wallet-adapter-exodus@1.2.3 - - @reef-knot/wallet-adapter-zerion@1.2.4 - - @reef-knot/wallet-adapter-zengo@1.2.4 - - @reef-knot/wallet-adapter-taho@1.2.3 - -## 1.4.3 - -### Patch Changes - -- Updated dependencies [542d5c5] -- Updated dependencies [b8258de] -- Updated dependencies [e6e579e] - - @reef-knot/wallet-adapter-zengo@1.2.3 - - @reef-knot/wallet-adapter-bitkeep@1.0.0 - - @reef-knot/wallet-adapter-phantom@1.2.2 - - @reef-knot/wallet-adapter-blockchaincom@1.2.3 - - @reef-knot/wallet-adapter-walletconnect@1.2.3 - - @reef-knot/wallet-adapter-ambire@1.2.3 - - @reef-knot/wallet-adapter-exodus@1.2.2 - - @reef-knot/wallet-adapter-zerion@1.2.3 - - @reef-knot/wallet-adapter-taho@1.2.2 - - @reef-knot/wallet-adapter-okx@1.2.2 - -## 1.4.2 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-ambire@1.2.2 - - @reef-knot/wallet-adapter-blockchaincom@1.2.2 - - @reef-knot/wallet-adapter-walletconnect@1.2.2 - - @reef-knot/wallet-adapter-zengo@1.2.2 - - @reef-knot/wallet-adapter-zerion@1.2.2 - -## 1.4.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/types@1.2.1 - - @reef-knot/wallet-adapter-ambire@1.2.1 - - @reef-knot/wallet-adapter-blockchaincom@1.2.1 - - @reef-knot/wallet-adapter-exodus@1.2.1 - - @reef-knot/wallet-adapter-okx@1.2.1 - - @reef-knot/wallet-adapter-phantom@1.2.1 - - @reef-knot/wallet-adapter-taho@1.2.1 - - @reef-knot/wallet-adapter-walletconnect@1.2.1 - - @reef-knot/wallet-adapter-zengo@1.2.1 - - @reef-knot/wallet-adapter-zerion@1.2.1 - -## 1.4.0 - -### Patch Changes - -- Updated dependencies - -## 1.3.1 - -### Patch Changes - -- Updated dependencies - - @reef-knot/wallet-adapter-ambire@1.1.1 - - @reef-knot/wallet-adapter-blockchaincom@1.1.1 - - @reef-knot/wallet-adapter-exodus@1.1.1 - - @reef-knot/wallet-adapter-okx@1.1.1 - - @reef-knot/wallet-adapter-phantom@1.1.1 - - @reef-knot/wallet-adapter-taho@1.1.1 - - @reef-knot/wallet-adapter-walletconnect@1.1.1 - - @reef-knot/wallet-adapter-zengo@1.1.1 - - @reef-knot/wallet-adapter-zerion@1.1.1 - - @reef-knot/types@1.1.1 - -## 1.3.0 - -### Minor Changes - -- faa8815: Add adapters: Ambire, Blockchain.com, WalletConnect, ZenGo, Zerion - -### Patch Changes - -- Updated dependencies [faa8815] - - @reef-knot/types@1.1.0 - - @reef-knot/wallet-adapter-exodus@1.1.0 - - @reef-knot/wallet-adapter-okx@1.1.0 - - @reef-knot/wallet-adapter-phantom@1.1.0 - - @reef-knot/wallet-adapter-taho@1.1.0 - - @reef-knot/wallet-adapter-ambire@1.1.0 - - @reef-knot/wallet-adapter-blockchaincom@1.1.0 - - @reef-knot/wallet-adapter-walletconnect@1.1.0 - - @reef-knot/wallet-adapter-zengo@1.1.0 - - @reef-knot/wallet-adapter-zerion@1.1.0 - -## 1.2.0 - -### Minor Changes - -- Enable Phantom wallet - -## 1.1.0 - -### Minor Changes - -- Add OKX wallet - -## 1.0.2 - -### Patch Changes - -- Add Taho wallet - -## 1.0.1 - -### Patch Changes - -- Use @reef-knot/types. -- Updated dependencies - - @reef-knot/wallet-adapter-exodus@1.0.1 - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@1.0.0 - - @reef-knot/wallet-adapter-exodus@1.0.0 diff --git a/packages/wallets-list/LICENSE.txt b/packages/wallets-list/LICENSE.txt deleted file mode 100644 index 07e71353..00000000 --- a/packages/wallets-list/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Lido - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/wallets-list/README.md b/packages/wallets-list/README.md deleted file mode 100644 index cb8f6955..00000000 --- a/packages/wallets-list/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Wallets List - - diff --git a/packages/wallets-list/package.json b/packages/wallets-list/package.json deleted file mode 100644 index 9759dadd..00000000 --- a/packages/wallets-list/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@reef-knot/wallets-list", - "version": "0.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "exports": { - ".": "./dist/index.js" - }, - "typesVersions": { - "*": { - ".": [ - "dist/index.d.ts" - ] - } - }, - "type": "module", - "files": [ - "dist" - ], - "license": "MIT", - "homepage": "https://github.com/lidofinance/reef-knot", - "repository": { - "type": "git", - "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/wallets-list" - }, - "bugs": { - "url": "https://github.com/lidofinance/reef-knot/issues" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public" - }, - "scripts": { - "build": "yarn run -T tsdown", - "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" - }, - "dependencies": { - "@reef-knot/wallet-adapter-ambire": "*", - "@reef-knot/wallet-adapter-anchorage-digital": "*", - "@reef-knot/wallet-adapter-bitkeep": "*", - "@reef-knot/wallet-adapter-browser-extension": "*", - "@reef-knot/wallet-adapter-coinbase-smart-wallet": "*", - "@reef-knot/wallet-adapter-dapp-browser-injected": "*", - "@reef-knot/wallet-adapter-imtoken": "*", - "@reef-knot/wallet-adapter-ledger-hid": "*", - "@reef-knot/wallet-adapter-ledger-live": "*", - "@reef-knot/wallet-adapter-metamask": "*", - "@reef-knot/wallet-adapter-okx": "*", - "@reef-knot/wallet-adapter-safe": "*", - "@reef-knot/wallet-adapter-walletconnect": "*" - }, - "devDependencies": { - "@reef-knot/types": "*", - "build-config": "*", - "eslint-config-custom": "*" - }, - "peerDependencies": { - "@reef-knot/types": "*", - "@tanstack/react-query": "^5.29.0", - "react": ">=18", - "viem": ">=2.50", - "wagmi": ">=3.6" - } -} diff --git a/packages/wallets-list/tsconfig.json b/packages/wallets-list/tsconfig.json deleted file mode 100644 index 23709e73..00000000 --- a/packages/wallets-list/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"], - "compilerOptions": { - "rootDir": "src", - } -} diff --git a/packages/wallets-list/tsdown.config.ts b/packages/wallets-list/tsdown.config.ts deleted file mode 100644 index 57dae503..00000000 --- a/packages/wallets-list/tsdown.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; - -export default defineConfig(defineStandardConfig()); diff --git a/packages/wallets/ambire/.eslintrc.json b/packages/wallets/ambire/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/ambire/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/ambire/CHANGELOG.md b/packages/wallets/ambire/CHANGELOG.md index 7e272970..d3383def 100644 --- a/packages/wallets/ambire/CHANGELOG.md +++ b/packages/wallets/ambire/CHANGELOG.md @@ -1,9 +1,21 @@ # @reef-knot/wallet-adapter-ambire +## 6.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. +- Keep connections tied to the selected EIP-6963 wallet when its provider is missing, instead of falling back to another browser wallet. + +## 6.2.1 + +- Update the `@reef-knot/types` dependency to 5.2.1. + +## 6.2.0 + +- Raise the minimum wagmi version to 3.6. + ## 6.1.0 -- Update wagmi to 3.6.21 -- Update peerDependencies requirements: wagmi >=3.6 +- Expose the wallet's EIP-6963 ID so the Browser Wallet picker can hide duplicate entries. ## 6.0.0 diff --git a/packages/wallets/ambire/package.json b/packages/wallets/ambire/package.json index 06614c30..6cd80578 100644 --- a/packages/wallets/ambire/package.json +++ b/packages/wallets/ambire/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/ambire/src/index.ts b/packages/wallets/ambire/src/index.ts index 02fc81c5..4913d225 100644 --- a/packages/wallets/ambire/src/index.ts +++ b/packages/wallets/ambire/src/index.ts @@ -1,5 +1,5 @@ import { injected } from 'wagmi/connectors'; -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { getTargetEIP6963, isProviderExistsEIP6963, diff --git a/packages/wallets/anchorageDigital/.eslintrc.json b/packages/wallets/anchorageDigital/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/anchorageDigital/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/anchorageDigital/CHANGELOG.md b/packages/wallets/anchorageDigital/CHANGELOG.md new file mode 100644 index 00000000..2eec5d30 --- /dev/null +++ b/packages/wallets/anchorageDigital/CHANGELOG.md @@ -0,0 +1,7 @@ +# @reef-knot/wallet-adapter-anchorage-digital + +## 1.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. +- Keep connections tied to Anchorage Digital when its EIP-6963 provider is missing, instead of falling back to another browser wallet. +- Generate type declarations through the shared build and add a separate TypeScript check. diff --git a/packages/wallets/anchorageDigital/package.json b/packages/wallets/anchorageDigital/package.json index 941a4502..5dbf8699 100644 --- a/packages/wallets/anchorageDigital/package.json +++ b/packages/wallets/anchorageDigital/package.json @@ -32,18 +32,16 @@ "access": "public" }, "scripts": { - "build": "yarn run -T tsdown && yarn run -T tsc --noEmit false --noEmitOnError false --emitDeclarationOnly --outDir dist || true", + "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs ." + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "wagmi": ">=3.6" } diff --git a/packages/wallets/anchorageDigital/src/index.ts b/packages/wallets/anchorageDigital/src/index.ts index db2cfbfc..23601fce 100644 --- a/packages/wallets/anchorageDigital/src/index.ts +++ b/packages/wallets/anchorageDigital/src/index.ts @@ -1,4 +1,4 @@ -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { injected } from 'wagmi/connectors'; import { getTargetEIP6963, diff --git a/packages/wallets/bitkeep/.eslintrc.json b/packages/wallets/bitkeep/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/bitkeep/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/bitkeep/CHANGELOG.md b/packages/wallets/bitkeep/CHANGELOG.md index 92a51607..656bb34e 100644 --- a/packages/wallets/bitkeep/CHANGELOG.md +++ b/packages/wallets/bitkeep/CHANGELOG.md @@ -1,9 +1,17 @@ # @reef-knot/wallet-adapter-bitkeep +## 5.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. +- Keep connections tied to the selected EIP-6963 wallet when its provider is missing, instead of falling back to another browser wallet. + +## 5.2.0 + +- Raise the minimum wagmi version to 3.6. + ## 5.1.0 -- Update wagmi to 3.6.21 -- Update peerDependencies requirements: wagmi >=3.6 +- Expose the wallet's EIP-6963 ID so the Browser Wallet picker can hide duplicate entries. ## 5.0.0 diff --git a/packages/wallets/bitkeep/package.json b/packages/wallets/bitkeep/package.json index 3a506de9..eaa00ea9 100644 --- a/packages/wallets/bitkeep/package.json +++ b/packages/wallets/bitkeep/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/bitkeep/src/index.ts b/packages/wallets/bitkeep/src/index.ts index a10d4dc1..0d45edc8 100644 --- a/packages/wallets/bitkeep/src/index.ts +++ b/packages/wallets/bitkeep/src/index.ts @@ -1,5 +1,5 @@ import { injected } from 'wagmi/connectors'; -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { getTargetEIP6963, isProviderExistsEIP6963, diff --git a/packages/wallets/browserExtension/.eslintrc.json b/packages/wallets/browserExtension/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/browserExtension/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/browserExtension/CHANGELOG.md b/packages/wallets/browserExtension/CHANGELOG.md index d6cdf4eb..09133d06 100644 --- a/packages/wallets/browserExtension/CHANGELOG.md +++ b/packages/wallets/browserExtension/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-browser-extension +## 5.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 5.1.0 - Update viem to 2.51.3, wagmi to 3.6.21 diff --git a/packages/wallets/browserExtension/package.json b/packages/wallets/browserExtension/package.json index a3b29980..85ba81d3 100644 --- a/packages/wallets/browserExtension/package.json +++ b/packages/wallets/browserExtension/package.json @@ -34,17 +34,16 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "build-config": "*", - "eslint-config-custom": "*", "viem": ">=2.50" }, "peerDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "viem": ">=2.50", "wagmi": ">=3.6" diff --git a/packages/wallets/browserExtension/src/index.ts b/packages/wallets/browserExtension/src/index.ts index 7eac2081..dfe775d5 100644 --- a/packages/wallets/browserExtension/src/index.ts +++ b/packages/wallets/browserExtension/src/index.ts @@ -1,5 +1,5 @@ import 'viem/window'; -import { WalletAdapterType } from '@reef-knot/types'; +import { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { injected } from 'wagmi/connectors'; import { WalletIcon } from './icons/index.js'; diff --git a/packages/wallets/coinbase-smart-wallet/.eslintrc.json b/packages/wallets/coinbase-smart-wallet/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/coinbase-smart-wallet/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/coinbase-smart-wallet/CHANGELOG.md b/packages/wallets/coinbase-smart-wallet/CHANGELOG.md index 9828e60e..7274d09e 100644 --- a/packages/wallets/coinbase-smart-wallet/CHANGELOG.md +++ b/packages/wallets/coinbase-smart-wallet/CHANGELOG.md @@ -1,9 +1,16 @@ # @reef-knot/wallet-adapter-coinbase-smart-wallet +## 4.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + +## 4.2.0 + +- Raise the minimum wagmi version to 3.6. + ## 4.1.0 -- Update wagmi to 3.6.21 -- Update peerDependencies requirements: wagmi >=3.6 +- Expose the wallet's EIP-6963 ID so the Browser Wallet picker can hide duplicate entries. ## 4.0.0 diff --git a/packages/wallets/coinbase-smart-wallet/package.json b/packages/wallets/coinbase-smart-wallet/package.json index 25a5837a..7ab52203 100644 --- a/packages/wallets/coinbase-smart-wallet/package.json +++ b/packages/wallets/coinbase-smart-wallet/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/coinbase-smart-wallet/src/index.ts b/packages/wallets/coinbase-smart-wallet/src/index.ts index f3ad73a0..87654b58 100644 --- a/packages/wallets/coinbase-smart-wallet/src/index.ts +++ b/packages/wallets/coinbase-smart-wallet/src/index.ts @@ -1,6 +1,8 @@ -import { WalletAdapterType } from '@reef-knot/types'; +import { + WalletAdapterType, + isProviderExistsEIP6963, +} from '@reef-knot/wallets-helpers'; import { coinbaseWallet } from 'wagmi/connectors'; -import { isProviderExistsEIP6963 } from '@reef-knot/wallets-helpers'; import { WalletIcon } from './icons/index.js'; export const id = 'coinbaseSmartWallet'; diff --git a/packages/wallets/dappBrowserInjected/.eslintrc.json b/packages/wallets/dappBrowserInjected/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/dappBrowserInjected/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/dappBrowserInjected/CHANGELOG.md b/packages/wallets/dappBrowserInjected/CHANGELOG.md index d3fb063d..477f7f02 100644 --- a/packages/wallets/dappBrowserInjected/CHANGELOG.md +++ b/packages/wallets/dappBrowserInjected/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-dapp-browser-injected +## 5.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 5.1.0 - Update viem to 2.51.3, wagmi to 3.6.21 diff --git a/packages/wallets/dappBrowserInjected/package.json b/packages/wallets/dappBrowserInjected/package.json index 467f35fe..79ebfe79 100644 --- a/packages/wallets/dappBrowserInjected/package.json +++ b/packages/wallets/dappBrowserInjected/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "viem": ">=2.50", diff --git a/packages/wallets/dappBrowserInjected/src/index.ts b/packages/wallets/dappBrowserInjected/src/index.ts index e6a74a94..419b266d 100644 --- a/packages/wallets/dappBrowserInjected/src/index.ts +++ b/packages/wallets/dappBrowserInjected/src/index.ts @@ -1,7 +1,9 @@ import 'viem/window'; -import { WalletAdapterType } from '@reef-knot/types'; +import { + WalletAdapterType, + isMobileOrTablet, +} from '@reef-knot/wallets-helpers'; import { injected } from 'wagmi/connectors'; -import { isMobileOrTablet } from '@reef-knot/wallets-helpers'; export const id = 'dappBrowserInjected'; export const name = 'DAppBrowser'; diff --git a/packages/wallets/imtoken/.eslintrc.json b/packages/wallets/imtoken/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/imtoken/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/imtoken/CHANGELOG.md b/packages/wallets/imtoken/CHANGELOG.md index 692f7cb6..4a5a8328 100644 --- a/packages/wallets/imtoken/CHANGELOG.md +++ b/packages/wallets/imtoken/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-imtoken +## 5.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 5.1.0 - Update viem to 2.51.3, wagmi to 3.6.21 diff --git a/packages/wallets/imtoken/package.json b/packages/wallets/imtoken/package.json index 46a440c7..65fe2ef9 100644 --- a/packages/wallets/imtoken/package.json +++ b/packages/wallets/imtoken/package.json @@ -34,17 +34,16 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "build-config": "*", - "eslint-config-custom": "*", "viem": ">=2.50" }, "peerDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "viem": ">=2.50", "wagmi": ">=3.6" diff --git a/packages/wallets/imtoken/src/index.ts b/packages/wallets/imtoken/src/index.ts index 5da133c1..1fc9261e 100644 --- a/packages/wallets/imtoken/src/index.ts +++ b/packages/wallets/imtoken/src/index.ts @@ -1,6 +1,6 @@ import { EIP1193Provider } from 'viem'; import { injected } from 'wagmi/connectors'; -import { WalletAdapterType } from '@reef-knot/types'; +import { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { WalletIcon } from './icons/index.js'; declare global { diff --git a/packages/wallets/ledger-hid/.eslintrc.json b/packages/wallets/ledger-hid/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/ledger-hid/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/ledger-hid/CHANGELOG.md b/packages/wallets/ledger-hid/CHANGELOG.md index b30e820f..54682c16 100644 --- a/packages/wallets/ledger-hid/CHANGELOG.md +++ b/packages/wallets/ledger-hid/CHANGELOG.md @@ -2,6 +2,7 @@ ## 6.2.0 +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. - Pass `ledgerForceClearSign` to the HID connector as `forceClearSign` ## 6.1.0 diff --git a/packages/wallets/ledger-hid/package.json b/packages/wallets/ledger-hid/package.json index 6b0dc771..0c9d8c97 100644 --- a/packages/wallets/ledger-hid/package.json +++ b/packages/wallets/ledger-hid/package.json @@ -34,18 +34,17 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", - "build-config": "*", - "eslint-config-custom": "*" + "@reef-knot/wallets-helpers": "*", + "build-config": "*" }, "peerDependencies": { "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" } diff --git a/packages/wallets/ledger-hid/src/index.ts b/packages/wallets/ledger-hid/src/index.ts index 18cc67d9..e013d1cd 100644 --- a/packages/wallets/ledger-hid/src/index.ts +++ b/packages/wallets/ledger-hid/src/index.ts @@ -1,4 +1,4 @@ -import { WalletAdapterType } from '@reef-knot/types'; +import { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { WalletIcon, WalletIconInverted } from './icons/index.js'; import { ledgerHIDConnector } from '@reef-knot/ledger-connector'; diff --git a/packages/wallets/ledger-live/.eslintrc.json b/packages/wallets/ledger-live/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/ledger-live/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/ledger-live/CHANGELOG.md b/packages/wallets/ledger-live/CHANGELOG.md index 2bd8ebbc..8292d99c 100644 --- a/packages/wallets/ledger-live/CHANGELOG.md +++ b/packages/wallets/ledger-live/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-ledger-live +## 6.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 6.1.0 - Update wagmi to 3.6.21 diff --git a/packages/wallets/ledger-live/package.json b/packages/wallets/ledger-live/package.json index 3518bd5f..22d1d629 100644 --- a/packages/wallets/ledger-live/package.json +++ b/packages/wallets/ledger-live/package.json @@ -34,18 +34,17 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", - "build-config": "*", - "eslint-config-custom": "*" + "@reef-knot/wallets-helpers": "*", + "build-config": "*" }, "peerDependencies": { "@reef-knot/ledger-connector": "*", - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" } diff --git a/packages/wallets/ledger-live/src/index.ts b/packages/wallets/ledger-live/src/index.ts index 8cd0a8ce..c8fdfd9b 100644 --- a/packages/wallets/ledger-live/src/index.ts +++ b/packages/wallets/ledger-live/src/index.ts @@ -1,4 +1,4 @@ -import { WalletAdapterType } from '@reef-knot/types'; +import { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { ledgerLiveConnector, isLedgerLive } from '@reef-knot/ledger-connector'; export const id = 'ledgerLive'; diff --git a/packages/wallets/metamask/.eslintrc.json b/packages/wallets/metamask/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/metamask/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/metamask/CHANGELOG.md b/packages/wallets/metamask/CHANGELOG.md index 06211fd2..f0b6dcb2 100644 --- a/packages/wallets/metamask/CHANGELOG.md +++ b/packages/wallets/metamask/CHANGELOG.md @@ -1,11 +1,17 @@ # @reef-knot/wallet-adapter-metamask +## 5.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + +## 5.2.0 + +- Raise the minimum wagmi version to 3.6. +- Update the MetaMask icon and use the same icon for light and dark themes. + ## 5.1.0 -- Update viem to 2.51.3, wagmi to 3.6.21 -- Update wallet icon to new MetaMask design -- Remove dark mode inverted icon variant (not needed with new design) -- Update peerDependencies requirements: wagmi >=3.6 +- Expose the wallet's EIP-6963 ID so the Browser Wallet picker can hide duplicate entries. ## 5.0.0 diff --git a/packages/wallets/metamask/package.json b/packages/wallets/metamask/package.json index 72928d06..9a7f3342 100644 --- a/packages/wallets/metamask/package.json +++ b/packages/wallets/metamask/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/metamask/src/index.ts b/packages/wallets/metamask/src/index.ts index 9ef13823..ea5a2565 100644 --- a/packages/wallets/metamask/src/index.ts +++ b/packages/wallets/metamask/src/index.ts @@ -1,5 +1,5 @@ import { injected, metaMask } from 'wagmi/connectors'; -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { isProviderExistsEIP6963 } from '@reef-knot/wallets-helpers'; import { WalletIcon } from './icons/index.js'; diff --git a/packages/wallets/okx/.eslintrc.json b/packages/wallets/okx/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/okx/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/okx/CHANGELOG.md b/packages/wallets/okx/CHANGELOG.md index c1d83a73..24a47729 100644 --- a/packages/wallets/okx/CHANGELOG.md +++ b/packages/wallets/okx/CHANGELOG.md @@ -1,9 +1,17 @@ # @reef-knot/wallet-adapter-okx +## 5.3.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. +- Keep the full page URL, including query parameters and fragments, in wallet links. Encode both the page URL and the nested download link. + +## 5.2.0 + +- Raise the minimum wagmi version to 3.6. + ## 5.1.0 -- Update wagmi to 3.6.21 -- Update peerDependencies requirements: wagmi >=3.6 +- Expose the wallet's EIP-6963 ID so the Browser Wallet picker can hide duplicate entries. ## 5.0.0 diff --git a/packages/wallets/okx/package.json b/packages/wallets/okx/package.json index 08f7aa6f..9ee92e4d 100644 --- a/packages/wallets/okx/package.json +++ b/packages/wallets/okx/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/okx/src/index.ts b/packages/wallets/okx/src/index.ts index c51d66ea..874a0543 100644 --- a/packages/wallets/okx/src/index.ts +++ b/packages/wallets/okx/src/index.ts @@ -1,4 +1,4 @@ -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { injected } from 'wagmi/connectors'; import WalletIcon from './icons/okx.svg'; import WalletIconInverted from './icons/okx-inverted.svg'; @@ -11,11 +11,12 @@ export const id = 'okx'; export const name = 'OKX Wallet'; export const rdns = 'com.okex.wallet'; -const deeplinkDAppUrl = globalThis.window - ? globalThis.window.location.host + globalThis.window.location.pathname +// Encode both levels, so the page URL can't add query params to the link. +const currentHref = globalThis.window + ? encodeURIComponent(globalThis.window.location.href) : ''; -const deeplink = 'okx://wallet/dapp/url?dappUrl=' + deeplinkDAppUrl; -const urlWithDeeplink = 'https://www.okx.com/download?deeplink=' + deeplink; +const deeplink = `okx://wallet/dapp/url?dappUrl=${currentHref}`; +const urlWithDeeplink = `https://www.okx.com/download?deeplink=${encodeURIComponent(deeplink)}`; export const Okx: WalletAdapterType = ({ providersStore }) => ({ walletName: name, diff --git a/packages/wallets/okx/tsconfig.json b/packages/wallets/okx/tsconfig.json index a326c979..ef9de677 100644 --- a/packages/wallets/okx/tsconfig.json +++ b/packages/wallets/okx/tsconfig.json @@ -1,5 +1,8 @@ { "extends": "tsconfig/react-library.json", "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"] + "exclude": ["node_modules", "dist", "**/*.test.*"], + "compilerOptions": { + "rootDir": "src" + } } diff --git a/packages/wallets/safe/.eslintrc.json b/packages/wallets/safe/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/safe/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/safe/CHANGELOG.md b/packages/wallets/safe/CHANGELOG.md index 6bb8f45c..09de8cfa 100644 --- a/packages/wallets/safe/CHANGELOG.md +++ b/packages/wallets/safe/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-safe +## 5.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 5.1.1 - Harden default allowed Safe domains diff --git a/packages/wallets/safe/package.json b/packages/wallets/safe/package.json index 9c74a333..532a8ba9 100644 --- a/packages/wallets/safe/package.json +++ b/packages/wallets/safe/package.json @@ -34,21 +34,20 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", + "lint": "yarn run -T eslint .", "test": "vitest run", - "typecheck": "tsc --noEmit" + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@safe-global/safe-apps-provider": "^0.18.6", "@safe-global/safe-apps-sdk": "^9.1.0", "build-config": "*", - "eslint-config-custom": "*", "happy-dom": "^20.0.0", "vitest": "^4.1.11" }, "peerDependencies": { - "@reef-knot/types": "*", + "@reef-knot/wallets-helpers": "*", "@safe-global/safe-apps-provider": "^0.18.6", "@safe-global/safe-apps-sdk": "^9.1.0", "@tanstack/react-query": "^5.29.0", diff --git a/packages/wallets/safe/src/index.ts b/packages/wallets/safe/src/index.ts index 0d23e807..50573f7a 100644 --- a/packages/wallets/safe/src/index.ts +++ b/packages/wallets/safe/src/index.ts @@ -1,6 +1,6 @@ import { safe } from 'wagmi/connectors'; import { withTimeout } from 'viem'; -import type { WalletAdapterType } from '@reef-knot/types'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; export const id = 'safe'; export const name = 'Safe'; @@ -51,16 +51,20 @@ export const Safe: WalletAdapterType = ({ safeAllowedDomains }) => ({ try { // It is a dependency of @wagmi/connectors - // eslint-disable-next-line import/no-extraneous-dependencies + const { default: SafeAppsSDK } = await import('@safe-global/safe-apps-sdk'); let SDK: typeof SafeAppsSDK; + // The package can expose a nested default export under CommonJS interop. + const wrappedSDK = SafeAppsSDK as unknown as { + default?: typeof SafeAppsSDK; + }; if ( typeof SafeAppsSDK !== 'function' && - typeof (SafeAppsSDK as any).default === 'function' + typeof wrappedSDK.default === 'function' ) { - SDK = (SafeAppsSDK as any).default; + SDK = wrappedSDK.default; } else { SDK = SafeAppsSDK; } @@ -77,7 +81,7 @@ export const Safe: WalletAdapterType = ({ safeAllowedDomains }) => ({ if (!safeSdk) return false; // It is a dependency of @wagmi/connectors - // eslint-disable-next-line import/no-extraneous-dependencies + const { SafeAppProvider } = await import('@safe-global/safe-apps-provider'); const provider = new SafeAppProvider(safeSdk, sdk); diff --git a/packages/wallets/walletconnect/.eslintrc.json b/packages/wallets/walletconnect/.eslintrc.json deleted file mode 100644 index 06342be5..00000000 --- a/packages/wallets/walletconnect/.eslintrc.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/packages/wallets/walletconnect/CHANGELOG.md b/packages/wallets/walletconnect/CHANGELOG.md index 6120d261..f35a9cac 100644 --- a/packages/wallets/walletconnect/CHANGELOG.md +++ b/packages/wallets/walletconnect/CHANGELOG.md @@ -1,5 +1,9 @@ # @reef-knot/wallet-adapter-walletconnect +## 5.2.0 + +- Replace the `@reef-knot/types` peer dependency with `@reef-knot/wallets-helpers` for shared wallet adapter types. + ## 5.1.0 - Update wagmi to 3.6.21 diff --git a/packages/wallets/walletconnect/package.json b/packages/wallets/walletconnect/package.json index 32b4dcb0..92a86b33 100644 --- a/packages/wallets/walletconnect/package.json +++ b/packages/wallets/walletconnect/package.json @@ -34,17 +34,14 @@ "scripts": { "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", "@tanstack/react-query": "^5.29.0", "wagmi": ">=3.6" diff --git a/packages/wallets/walletconnect/src/index.ts b/packages/wallets/walletconnect/src/index.ts index fb23293f..24b1895a 100644 --- a/packages/wallets/walletconnect/src/index.ts +++ b/packages/wallets/walletconnect/src/index.ts @@ -1,5 +1,7 @@ -import { WalletAdapterType } from '@reef-knot/types'; -import { getWalletConnectConnector } from '@reef-knot/wallets-helpers'; +import { + WalletAdapterType, + getWalletConnectConnector, +} from '@reef-knot/wallets-helpers'; import WalletIcon from './icons/wallet-connect-circle.svg'; export const id = 'walletConnect'; diff --git a/packages/web3-react/.eslintrc.json b/packages/web3-react/.eslintrc.json deleted file mode 100644 index bacef55e..00000000 --- a/packages/web3-react/.eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "ignorePatterns": ["test/**/*.test.*"] -} diff --git a/packages/web3-react/CHANGELOG.md b/packages/web3-react/CHANGELOG.md deleted file mode 100644 index 25d86003..00000000 --- a/packages/web3-react/CHANGELOG.md +++ /dev/null @@ -1,343 +0,0 @@ -# @reef-knot/web3-react - -## 7.1.0 - -- Update wagmi to 3.6.21 -- Update peerDependencies requirements: wagmi >=3.6 - -## 7.0.0 - -- Build using node 24, yarn 3.8.7 -- Replace rollup bundler with tsdown based on rolldown, all packages are rebuild -- Update dependencies: wagmi 3.3.4 (BREAKING), viem 2.44.4, typescript 5.7.3, tslib 2.8.1, turbo 2.7.5 - -## 6.2.0 - -### Minor Changes - -- Technical version update - -## 6.1.0 - -### Minor Changes - -- Update viem to v2.23 and wagmi to v2.14, so the @coinbase/wallet-sdk would be updated too, which fixes a dependabot issue - -## 6.0.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@6.0.0 - -## 5.0.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@5.0.0 - -## 4.0.2 - -### Patch Changes - -- accbcde: viem and wagmi versions updated with flexible declarations - -## 4.0.1 - -### Patch Changes - -- Wagmi version updated - -## 4.0.0 - -### Major Changes - -- Wagmi version updated and corresponding changes applied - -### Patch Changes - -- Updated dependencies - - @reef-knot/ledger-connector@4.0.0 - - @reef-knot/wallets-helpers@2.0.0 - - @reef-knot/core-react@4.0.0 - -## 3.0.1 - -### Patch Changes - -- Updated dependencies - -## 3.0.0 - -### Patch Changes - -- Updated dependencies - - @reef-knot/core-react@3.0.0 - -## 2.1.0 - -### Minor Changes - -- 85b3f79: - - rework getUnsupportedChainError, hide mumbai network in the error - - (web3-react) fix logic of useConnectorError - - (web3-react) deprecate useConnectorInfo, useDisconnect - - (core-react) rework and add hooks: useConnectorInfo, useDisconnect, useEagerConnect - - (reef-knot) add connectors export as "Connectors" - -## 2.0.0 - -### Major Changes - -- 1046886: Remove legacy code, based on lido-sdk and web3-react - -### Patch Changes - -- Updated dependencies [1046886] - - @reef-knot/ledger-connector@3.0.0 - - @reef-knot/core-react@2.0.0 - -## 1.13.1 - -### Patch Changes - -- fix: return isLedger to useConnectorInfo - -## 1.13.0 - -### Minor Changes - -- 253796d: Remove unused MetaMask-related code - -## 1.12.0 - -### Minor Changes - -- Use Ledger hid wallet adapter, based on wagmi - -### Patch Changes - -- Updated dependencies - - @reef-knot/ledger-connector@2.0.0 - -## 1.11.0 - -### Minor Changes - -- Remove Coinbase related code - -## 1.10.0 - -### Minor Changes - -- Remove XDEFI, Trust, imToken related code - -## 1.9.1 - -### Patch Changes - -- Fix an issue with the terms modal not closing until page restart. - -## 1.9.0 - -### Minor Changes - -- Remove MathWallet related code - -## 1.8.0 - -### Minor Changes - -- Add holesky to wagmiChainsArray, handle connection errors in AcceptTermsModal - -## 1.7.0 - -### Minor Changes - -- Remove Brave, Coin98, Opera, Gamestop wallets unneeded legacy code - -## 1.6.1 - -### Patch Changes - -- Add workaround: await timeout before ledger connector "activate" - -## 1.6.0 - -### Minor Changes - -- Rework direct Ledger hardware connection UI - -## 1.5.0 - -### Minor Changes - -- Update lido-js-sdk deps and move them to peer deps - -## 1.4.2 - -### Patch Changes - -- fix: connection rejection logic during mobile browser autoconnect - -## 1.4.1 - -### Patch Changes - -- Open Terms modal only if terms were not accepted earlier - -## 1.4.0 - -### Minor Changes - -- 217c144: Show "Accept Terms" Modal for Ledger Live, Safe, dapp browsers - -### Patch Changes - -- 48d8c4b: Update wagmi to 0.12.19 - -## 1.3.1 - -### Patch Changes - -- e6e579e: wagmi 0.12.18 -- e6e579e: Update lido-sdk packages - -## 1.3.0 - -### Minor Changes - -- Use ledger connectors from reef-knot, pass supportedChainsId in LedgerHQFrameConnector - -### Patch Changes - -- Updated dependencies - - @reef-knot/ledger-connector@1.0.0 - -## 1.2.2 - -### Patch Changes - -- remove walletconnect v1 leftovers - -## 1.2.1 - -### Patch Changes - -- Update wagmi to v0.12.17 -- Updated dependencies - - @reef-knot/core-react@1.4.1 - -## 1.2.0 - -### Minor Changes - -- Explicitly pass chains to wagmi connectors, update wagmi to v0.12.16 - -### Patch Changes - -- Updated dependencies - -## 1.1.1 - -### Patch Changes - -- Remove circular deps -- Pass through WalletConnect project ID to the ReefKnot context -- Updated dependencies - - @reef-knot/core-react@1.3.1 - -## 1.1.0 - -### Minor Changes - -- faa8815: Update wagmi to v0.12 -- faa8815: Update Wallet Adapter API for WalletConnect - -### Patch Changes - -- Updated dependencies [faa8815] - - @reef-knot/core-react@1.3.0 - -## 1.0.7 - -### Patch Changes - -- Do not detect providerName if isDappBrowser; -- Fix switching between web3 providers; - -## 1.0.6 - -### Patch Changes - -- Fix setting a Web3Provider for web3-react -- If the chain is unsupported and connected via wagmi, handle it the same way as web3-react does - -## 1.0.5 - -### Patch Changes - -- Replace Tally legacy connector with Taho wallet adapter - -## 1.0.4 - -### Patch Changes - -- 1. Call wagmi disconnect into useForceDisconnect. - 2. Remove old Exodus code and other unused code. - 3. Use custom wagmi connectors to get providerName. - 4. Export isConnectedViaWagmi from useConnectorInfo. - 5. Check for isConnectedViaWagmi in useAutoConnect. - -## 1.0.3 - -### Patch Changes - -- - Get account address from the shimmed `useWeb3` hook - - Fix setting `providerWeb3` when a wallet is connected via wagmi - -## 1.0.2 - -### Patch Changes - -- Set typescript compilerOptions.jsx = "react" - -## 1.0.1 - -### Patch Changes - -- Shim useWeb3, useSupportedChains to also support wagmi data - -## 1.0.0 - -### Major Changes - -- #### v1.0 is an update starting migration to wagmi - - Update TS to 4.9.5, tslib to 2.5.0, rollup to 3.15.0 - - Update build config: generate ESM modules only, update tsconfig, change packages exports - - Workaround styled-components ESM issue - - Add wagmi dependency - - Use wagmi controllers for all WalletConnect wallets (WC v2 support) - - Add a modular wallet adapter API - - Use a wallet adapter API with wagmi injected controller for Exodus wallet - - Remove most of @lido-sdk dependencies - - Cleanup and other minor changes - -## 0.3.0 - -### Minor Changes - -- Add Zerion wallet detection - -## 0.2.0 - -### Minor Changes - -- Add Metrics Events support - -## 0.1.0 - -### Minor Changes - -- Support Trust Wallet browser extension diff --git a/packages/web3-react/LICENSE.txt b/packages/web3-react/LICENSE.txt deleted file mode 100644 index 9a459058..00000000 --- a/packages/web3-react/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Lido - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/web3-react/README.md b/packages/web3-react/README.md deleted file mode 100644 index 8fdf7748..00000000 --- a/packages/web3-react/README.md +++ /dev/null @@ -1,5 +0,0 @@ -### @reef-knot/web3-react -This is a legacy package, which previously included various helpers and wrappers for the `web3-react` library. - -The `web3-react` library is not used in Reef Knot anymore, so `@reef-knot/web3-react` was reworked to use wagmi -and now contains a few hooks and helpers for backwards compatibility. diff --git a/packages/web3-react/babel.config.json b/packages/web3-react/babel.config.json deleted file mode 100644 index 943afac2..00000000 --- a/packages/web3-react/babel.config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "presets": [ - ["@babel/preset-env", { "targets": { "node": "current", "esmodules": true } }], - ["@babel/preset-react", { "runtime": "automatic" }], - "@babel/preset-typescript" - ] -} diff --git a/packages/web3-react/package.json b/packages/web3-react/package.json deleted file mode 100644 index 0be844da..00000000 --- a/packages/web3-react/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "@reef-knot/web3-react", - "version": "0.0.0", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "exports": { - ".": "./dist/index.js" - }, - "typesVersions": { - "*": { - ".": [ - "dist/index.d.ts" - ] - } - }, - "type": "module", - "files": [ - "dist" - ], - "license": "MIT", - "homepage": "https://github.com/lidofinance/reef-knot", - "repository": { - "type": "git", - "url": "git+https://github.com/lidofinance/reef-knot.git", - "directory": "packages/web3-react" - }, - "bugs": { - "url": "https://github.com/lidofinance/reef-knot/issues" - }, - "publishConfig": { - "registry": "https://registry.npmjs.org/", - "access": "public" - }, - "scripts": { - "build": "yarn run -T tsdown", - "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs .", - "typecheck": "tsc --noEmit" - }, - "devDependencies": { - "@babel/cli": "7.29.7", - "@babel/core": "7.29.7", - "@babel/plugin-proposal-class-properties": "7.18.6", - "@babel/plugin-proposal-private-methods": "7.18.6", - "@babel/plugin-proposal-private-property-in-object": "7.21.11", - "@babel/preset-env": "7.29.7", - "@babel/preset-react": "7.29.7", - "@babel/preset-typescript": "7.29.7", - "@reef-knot/core-react": "*", - "@reef-knot/ledger-connector": "*", - "@reef-knot/wallets-helpers": "*", - "@testing-library/react": "^12.1.5", - "@testing-library/react-hooks": "^7.0.2", - "@types/react": "18.2.45", - "babel-loader": "8.4.1", - "babel-plugin-styled-components": "1.13.3", - "build-config": "*", - "eslint-config-custom": "*", - "react": "18.2.0" - }, - "dependencies": { - "tiny-invariant": "^1.1.0" - }, - "peerDependencies": { - "@reef-knot/core-react": "*", - "@reef-knot/ledger-connector": "*", - "@reef-knot/wallets-helpers": "*", - "@tanstack/react-query": "^5.29.0", - "react": ">=18", - "wagmi": ">=3.6" - } -} diff --git a/packages/web3-react/src/helpers/index.ts b/packages/web3-react/src/helpers/index.ts deleted file mode 100644 index 89268275..00000000 --- a/packages/web3-react/src/helpers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './interceptLedgerError'; diff --git a/packages/web3-react/src/hooks/index.ts b/packages/web3-react/src/hooks/index.ts deleted file mode 100644 index 3e528619..00000000 --- a/packages/web3-react/src/hooks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useSupportedChains'; -export * from './useWeb3'; diff --git a/packages/web3-react/src/hooks/useSupportedChains.ts b/packages/web3-react/src/hooks/useSupportedChains.ts deleted file mode 100644 index d98aa9bb..00000000 --- a/packages/web3-react/src/hooks/useSupportedChains.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useMemo } from 'react'; -import { useConnection, useConfig } from 'wagmi'; - -// Kept shape-compatible with the ethers `Network` type this hook used to return -export type Network = { - chainId: number; - name: string; -}; - -export const useSupportedChains = (): { - isUnsupported: boolean; - supportedChains: Network[]; -} => { - const { chainId } = useConnection(); - const { chains } = useConfig(); - - const isUnsupported = useMemo(() => { - return !chainId || !chains?.find((c) => c.id === chainId); - }, [chainId, chains]); - - const supportedChains = useMemo(() => { - return chains.map((c) => ({ chainId: c.id, name: c.name })); - }, [chains]); - - return { - isUnsupported, - supportedChains, - }; -}; diff --git a/packages/web3-react/src/hooks/useWeb3.ts b/packages/web3-react/src/hooks/useWeb3.ts deleted file mode 100644 index e32c9b56..00000000 --- a/packages/web3-react/src/hooks/useWeb3.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { useConnection, useConnect } from 'wagmi'; -import { useSupportedChains } from './useSupportedChains'; - -export interface Web3ReactManagerFunctions { - activate: ( - connector: undefined, // AbstractConnector changed to undefined here - onError?: (error: Error) => void, - throwErrors?: boolean, - ) => Promise; - setError: (error: Error) => void; - deactivate: () => void; -} - -export interface Web3ReactContextInterface< - T = any, -> extends Web3ReactManagerFunctions { - connector?: undefined; // AbstractConnector changed to undefined here - library?: T; - chainId?: number; - account?: null | string; - active: boolean; - error?: Error; -} - -// This is a legacy hook for getting data and methods from web3-react library. -// Because of migration to wagmi library, this method now returns values from wagmi and is left here for backwards compatibility. -export function useWeb3(_key?: string): Web3ReactContextInterface { - const wagmiAccount = useConnection(); - const { error: wagmiError } = useConnect(); - const account = wagmiAccount?.address; - - // web3-react and wagmi have different logic around unsupported chains. - // If a chain is not supported: - // web3-react sets: - // `chainId` === undefined - // `error` === UnsupportedChainIdError - // `active` === false - // wagmi sets: - // `chain.id` === actual value from wallet - // `chain.unsupported` === true - // `error` === null - // `isConnected` === true (connects via default chain) - // These differences break our widgets, because the widgets don't expect - // chainId to be unsupported, they expect chainId === undefined in that case. - // Making wagmi's logic to be the same as web3-react here, except setting an error: - const { isUnsupported } = useSupportedChains(); - const chainId = isUnsupported ? undefined : wagmiAccount?.chainId; - const active = isUnsupported ? false : wagmiAccount?.isConnected; - - // wagmi error can be null, but historically we need `Error | undefined` here - const error: Error | undefined = wagmiError || undefined; - - return { - chainId, - account, - active, - error, - - // Web3Provider from ethers.js, we pass it to Web3ReactProvider via getLibrary() - library: undefined, - - // AbstractConnector from @web3-react, used by @reef-knot/web3-react only for - // useDisconnect, useConnectorInfo and useSupportedChains - connector: undefined, - activate: () => { - console.error('"activate" method is deprecated and does nothing.'); - return Promise.resolve(); - }, - setError: () => { - console.error('"setError" method is deprecated and does nothing.'); - }, - deactivate: () => { - console.error('"deactivate" method is deprecated and does nothing.'); - }, - }; -} diff --git a/packages/web3-react/src/index.ts b/packages/web3-react/src/index.ts deleted file mode 100644 index 03a05620..00000000 --- a/packages/web3-react/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './hooks'; -export * as helpers from './helpers'; diff --git a/packages/web3-react/tsconfig.json b/packages/web3-react/tsconfig.json deleted file mode 100644 index a326c979..00000000 --- a/packages/web3-react/tsconfig.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "tsconfig/react-library.json", - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*"] -} diff --git a/packages/web3-react/tsdown.config.ts b/packages/web3-react/tsdown.config.ts deleted file mode 100644 index 57dae503..00000000 --- a/packages/web3-react/tsdown.config.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { defineConfig } from 'tsdown'; -import { defineStandardConfig } from 'build-config'; - -export default defineConfig(defineStandardConfig()); diff --git a/playwright-tests/.eslintignore b/playwright-tests/.eslintignore deleted file mode 100644 index d21957a8..00000000 --- a/playwright-tests/.eslintignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules -dist -playwright-report -test-results - -/.jest - -/.yarn/* -/.pnp.* diff --git a/playwright-tests/.eslintrc.json b/playwright-tests/.eslintrc.json deleted file mode 100644 index 909e83f9..00000000 --- a/playwright-tests/.eslintrc.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "env": { - "es2021": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module", - "project": "./tsconfig.json" - }, - "plugins": ["@typescript-eslint", "import"], - "rules": { - "@typescript-eslint/ban-ts-comment": "off", - "prettier/prettier": ["error", {}, { "usePrettierrc": true }], - "no-irregular-whitespace": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unnecessary-type-constraint": "off", - "@typescript-eslint/no-empty-interface": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { "ignoreRestSiblings": true } - ] - }, - "overrides": [ - { - "files": ["*.js"], - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off" - } - } - ], - "settings": { - "import/resolver": { - "typescript": { - "alwaysTryTypes": true, - "project": "./tsconfig.json" - } - } - } -} diff --git a/playwright-tests/.gitignore b/playwright-tests/.gitignore index 3082fa39..3f186698 100644 --- a/playwright-tests/.gitignore +++ b/playwright-tests/.gitignore @@ -12,3 +12,6 @@ logs/ !.yarn/releases !.yarn/sdks !.yarn/versions + +# local secrets +.env diff --git a/playwright-tests/config/env.config.ts b/playwright-tests/config/env.config.ts index 3de6f2f6..72ca6c4c 100644 --- a/playwright-tests/config/env.config.ts +++ b/playwright-tests/config/env.config.ts @@ -1,5 +1,7 @@ -import { NetworkConfig } from '@lidofinance/wallets-testing-wallets'; -import { NETWORKS_CONFIG } from '@lidofinance/wallets-testing-wallets'; +import { + NetworkConfig, + NETWORKS_CONFIG, +} from '@lidofinance/wallets-testing-wallets'; import { ENV_CONFIG } from './env.validation'; export interface StandConfig { diff --git a/playwright-tests/eslint.config.mjs b/playwright-tests/eslint.config.mjs new file mode 100644 index 00000000..00feb204 --- /dev/null +++ b/playwright-tests/eslint.config.mjs @@ -0,0 +1,66 @@ +import js from '@eslint/js'; +import { defineConfig, globalIgnores } from 'eslint/config'; +import imports from 'eslint-plugin-import'; +import playwright from 'eslint-plugin-playwright'; +import prettier from 'eslint-plugin-prettier/recommended'; +import globals from 'globals'; +import ts from 'typescript-eslint'; + +export default defineConfig( + globalIgnores([ + '**/node_modules/**', + '**/dist/**', + '**/.yarn/**', + '**/.pnp.*', + '**/playwright-report/**', + '**/test-results/**', + '**/.jest/**', + ]), + { + files: ['**/*.{js,mjs,cjs,ts}'], + extends: [js.configs.recommended], + languageOptions: { globals: globals.node }, + }, + { + files: ['**/*.ts'], + extends: [ts.configs.recommendedTypeChecked], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + plugins: { import: imports }, + settings: { + 'import/resolver': { + typescript: { + project: `${import.meta.dirname}/tsconfig.json`, + alwaysTryTypes: true, + }, + }, + }, + rules: { + ...imports.flatConfigs.recommended.rules, + ...imports.flatConfigs.typescript.rules, + 'import/no-named-as-default': 'off', + 'import/no-named-as-default-member': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, + ], + '@typescript-eslint/switch-exhaustiveness-check': 'error', + }, + }, + { + files: ['tests/**/*.ts'], + extends: [playwright.configs['flat/recommended']], + rules: { + // Qase wraps the string title in qase(id, title). + 'playwright/valid-title': ['error', { ignoreTypeOfTestName: true }], + }, + }, + prettier, +); diff --git a/playwright-tests/package.json b/playwright-tests/package.json index 94527797..4b2e758a 100644 --- a/playwright-tests/package.json +++ b/playwright-tests/package.json @@ -3,7 +3,9 @@ "version": "0.0.1", "private": true, "scripts": { - "test:reef-knot": "yarn playwright test" + "test:reef-knot": "yarn playwright test", + "lint": "eslint .", + "typecheck": "tsc --noEmit --tsBuildInfoFile node_modules/.cache/reef-knot.tsbuildinfo" }, "dependencies": { "@lidofinance/browser-service": "1.11.2", @@ -18,6 +20,21 @@ }, "packageManager": "yarn@4.17.1", "devDependencies": { - "dotenv": "^16.6.1" + "@eslint/js": "10.0.1", + "@typescript/native": "npm:typescript@7.0.2", + "dotenv": "^16.6.1", + "eslint": "10.12.0", + "eslint-config-prettier": "10.1.8", + "eslint-import-resolver-typescript": "4.4.5", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-playwright": "2.12.1", + "eslint-plugin-prettier": "5.5.6", + "globals": "17.13.0", + "prettier": "3.9.6", + "typescript": "npm:@typescript/typescript6@6.0.2", + "typescript-eslint": "8.71.1" + }, + "engines": { + "node": ">=24.0.0" } } diff --git a/playwright-tests/services/helpers.ts b/playwright-tests/services/helpers.ts index 56bcbe38..4a2a1fc3 100644 --- a/playwright-tests/services/helpers.ts +++ b/playwright-tests/services/helpers.ts @@ -10,7 +10,7 @@ import { ConsoleLogger } from '@nestjs/common'; * ``` */ export function toCutDecimalsDigit( - amount: any, + amount: string | number | bigint, decimalPlaces: number, removeZero = false, ) { @@ -35,27 +35,31 @@ export function toCutDecimalsDigit( * * @template T - The type of the arguments to be passed to the callback function. */ -export async function waitForCallback( - callback: (args: T) => Promise, +export async function waitForCallback( + callback: (args: T) => Promise, args: T, timeout: number, -): Promise { +): Promise> { let shouldTerminate = false; - setTimeout(() => { + const timeoutId = setTimeout(() => { shouldTerminate = true; }, timeout); - let result; - while (!shouldTerminate) { - result = await callback(args).catch(() => { - new ConsoleLogger('waitForCallback').log('Callback failed'); - }); - if (result) return result; - } + let result: TResult | void; + try { + while (!shouldTerminate) { + result = await callback(args).catch(() => { + new ConsoleLogger('waitForCallback').log('Callback failed'); + }); + if (result) return result; + } - throw new Error( - `callback still not done after ${ - timeout / 1000 - } sec.\nCallback result: ${result}`, - ); + throw new Error( + `callback still not done after ${ + timeout / 1000 + } sec.\nCallback result: ${String(result)}`, + ); + } finally { + clearTimeout(timeoutId); + } } diff --git a/playwright-tests/services/sdk.service.ts b/playwright-tests/services/sdk.service.ts index 4629136e..8d28777e 100644 --- a/playwright-tests/services/sdk.service.ts +++ b/playwright-tests/services/sdk.service.ts @@ -1,10 +1,17 @@ import { LidoSDK, VIEM_CHAINS } from '@lidofinance/lido-ethereum-sdk'; -import { createWalletClient, formatEther, http, type Address } from 'viem'; +import { + createWalletClient, + formatEther, + http, + type Address, + type Chain, +} from 'viem'; import { ENV_CONFIG, REEF_KNOT_CONFIG } from '@config'; import { toCutDecimalsDigit } from './helpers'; import { mnemonicToAccount } from 'viem/accounts'; global.fetch = fetch; +const sdkChains: Partial> = VIEM_CHAINS; export enum sdkToken { ETH = 'ETH', @@ -19,7 +26,7 @@ export class SdkService extends LidoSDK { rpcUrls: [REEF_KNOT_CONFIG.STAND_CONFIG.networkConfig.rpcUrl], web3Provider: createWalletClient({ account: mnemonicToAccount(ENV_CONFIG.WALLET_SECRET_PHRASE), - chain: VIEM_CHAINS[REEF_KNOT_CONFIG.STAND_CONFIG.networkConfig.chainId], + chain: sdkChains[REEF_KNOT_CONFIG.STAND_CONFIG.networkConfig.chainId], transport: http(REEF_KNOT_CONFIG.STAND_CONFIG.networkConfig.rpcUrl), }), logMode: 'none', @@ -50,14 +57,14 @@ export class SdkService extends LidoSDK { return toCutDecimalsDigit(balance, decimalPlaces, true); } - async exchangeStEthToWstEth(amount: any) { + async exchangeStEthToWstEth(amount: string) { const wstethRate = formatEther( await this.wrap.convertStethToWsteth(1000000000000000000n), ); return parseFloat(wstethRate) * parseFloat(amount); } - async exchangeWstEthToStEth(amount: any) { + async exchangeWstEthToStEth(amount: string) { const wstethRate = formatEther( await this.wrap.convertWstethToSteth(1000000000000000000n), ); diff --git a/playwright-tests/tests/matomo-event-connected-wallet.spec.ts b/playwright-tests/tests/matomo-event-connected-wallet.spec.ts index 13f5b1dc..175dd971 100644 --- a/playwright-tests/tests/matomo-event-connected-wallet.spec.ts +++ b/playwright-tests/tests/matomo-event-connected-wallet.spec.ts @@ -10,7 +10,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Matomo events (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { let browserService: BrowserService; let reefKnotService: ReefKnotService; let reefKnotPage: ReefKnotPage; @@ -55,7 +55,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Matomo events (Browser)`, { tag: [Tags.connectedWallet, '@browser'] }, - async () => { + () => { let browserService: BrowserService; let reefKnotService: ReefKnotService; let reefKnotPage: ReefKnotPage; diff --git a/playwright-tests/tests/matomo-event.spec.ts b/playwright-tests/tests/matomo-event.spec.ts index 068a8869..0c34d233 100644 --- a/playwright-tests/tests/matomo-event.spec.ts +++ b/playwright-tests/tests/matomo-event.spec.ts @@ -3,7 +3,7 @@ import { CONFIG_MATOMO_CLICK_TO_WALLET_EVENTS } from '@test-data'; import { test, expect } from '@playwright/test'; import { qase } from 'playwright-qase-reporter'; -test.describe('ReefKnot. Matomo events', async () => { +test.describe('ReefKnot. Matomo events', () => { let reefKnotPage: ReefKnotPage; test.beforeAll(async ({ browser }) => { diff --git a/playwright-tests/tests/transactions/stake-tx.spec.ts b/playwright-tests/tests/transactions/stake-tx.spec.ts index f3995cf2..11e14913 100644 --- a/playwright-tests/tests/transactions/stake-tx.spec.ts +++ b/playwright-tests/tests/transactions/stake-tx.spec.ts @@ -14,7 +14,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Stake ETH transaction (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { const stakeAmount = '0.0003'; let browserService: BrowserService; let reefKnotService: ReefKnotService; diff --git a/playwright-tests/tests/transactions/unwrap-tx.spec.ts b/playwright-tests/tests/transactions/unwrap-tx.spec.ts index b09f9394..905aa663 100644 --- a/playwright-tests/tests/transactions/unwrap-tx.spec.ts +++ b/playwright-tests/tests/transactions/unwrap-tx.spec.ts @@ -14,7 +14,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Unwrap transaction (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { const unwrapAmount = '0.0003'; let browserService: BrowserService; let reefKnotService: ReefKnotService; diff --git a/playwright-tests/tests/transactions/withdrawal-tx.spec.ts b/playwright-tests/tests/transactions/withdrawal-tx.spec.ts index 2b3a2ffe..c30f7c6d 100644 --- a/playwright-tests/tests/transactions/withdrawal-tx.spec.ts +++ b/playwright-tests/tests/transactions/withdrawal-tx.spec.ts @@ -14,7 +14,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Request withdraw transaction (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { const txAmount = '0.0003'; let browserService: BrowserService; let reefKnotService: ReefKnotService; diff --git a/playwright-tests/tests/transactions/wrap-tx.spec.ts b/playwright-tests/tests/transactions/wrap-tx.spec.ts index 12c9e303..80c59125 100644 --- a/playwright-tests/tests/transactions/wrap-tx.spec.ts +++ b/playwright-tests/tests/transactions/wrap-tx.spec.ts @@ -14,7 +14,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Wrap transaction (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { const wrapAmount = '0.0003'; let browserService: BrowserService; let reefKnotService: ReefKnotService; @@ -91,6 +91,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { }); await test.step('Set up correct allowance before test', async () => { + // eslint-disable-next-line playwright/no-conditional-in-test -- Reset an existing allowance only when approval would otherwise be skipped. if ( (await reefKnotService.sdkService.getStEthAllowance()) >= parseFloat(wrapAmount) @@ -128,15 +129,14 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { 'The Wrap button should be disabled', ).toBeDisabled(); - reefKnotPage.toast.successToast.waitFor({ + await reefKnotPage.toast.successToast.waitFor({ state: 'visible', timeout: TIMEOUT.RPC_WAIT, }); - await test.step('Wait for the toast to be disappeared', async () => { - await reefKnotPage.toast.successToast.waitFor({ - state: 'hidden', - timeout: TIMEOUT.HIGH, - }); + + await reefKnotPage.toast.successToast.waitFor({ + state: 'hidden', + timeout: TIMEOUT.HIGH, }); }); diff --git a/playwright-tests/tests/wallet-connection.spec.ts b/playwright-tests/tests/wallet-connection.spec.ts index c67493d7..d39f71d8 100644 --- a/playwright-tests/tests/wallet-connection.spec.ts +++ b/playwright-tests/tests/wallet-connection.spec.ts @@ -10,7 +10,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Wallet connection (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { test.describe.configure({ mode: 'serial' }); // Serial mode is used because the tests in this test.describe are related to each other. let browserService: BrowserService; let reefKnotService: ReefKnotService; @@ -36,13 +36,15 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { await expect( reefKnotPage.statsBlock.mainComponent, 'The statistic block should not be visible before the wallet is connected', - ).not.toBeVisible(); + ).toBeHidden(); await expect( reefKnotPage.header.accountButton, 'The account button should not be visible before the wallet is connected', - ).not.toBeVisible(); + ).toBeHidden(); }); + await reefKnotService.connectWallet(); + await test.step('Check the stand appearance after wallet connection', async () => { await expect( reefKnotPage.statsBlock.mainComponent, @@ -53,6 +55,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { 'The account button should be visible after the wallet is connected', ).toBeVisible(); }); + await test.step('Check local storage with connected', async () => { expect( await reefKnotPage.getStorageData('wagmi.recentConnectorId'), @@ -92,16 +95,18 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { await qase.parameters({ wallet: wallet.name }); await reefKnotPage.disconnectWallet(); + await test.step('Check the stand appearance after wallet disconnection', async () => { await expect( reefKnotPage.statsBlock.mainComponent, 'The statistic block should not be visible after the wallet is disconnected', - ).not.toBeVisible(); + ).toBeHidden(); await expect( reefKnotPage.header.accountButton, 'The account button should not be visible after the wallet is disconnected', - ).not.toBeVisible(); + ).toBeHidden(); }); + await test.step('Check local storage with connected', async () => { expect( await reefKnotPage.getStorageData('wagmi.recentConnectorId'), @@ -117,7 +122,9 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { const storageValue = await reefKnotPage.getStorageData( connectedWalletStorageData.get(wallet.name).disconnectWalletKey, ); + // eslint-disable-next-line playwright/no-conditional-in-test -- Some wallets do not persist a disconnection marker. if (storageValue) { + // eslint-disable-next-line playwright/no-conditional-expect -- Check the marker when the wallet supports it. expect( storageValue, 'The recent wallet disconnection status should be "true"', @@ -138,11 +145,11 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { await expect( reefKnotPage.header.accountButton, 'The account button should not be visible after the page is reloaded', - ).not.toBeVisible(); + ).toBeHidden(); await expect( reefKnotPage.statsBlock.mainComponent, 'The statistic block should not be visible after the page is reloaded', - ).not.toBeVisible(); + ).toBeHidden(); }, ); }, diff --git a/playwright-tests/tests/wallet-list.spec.ts b/playwright-tests/tests/wallet-list.spec.ts index 00edc38c..15618a0e 100644 --- a/playwright-tests/tests/wallet-list.spec.ts +++ b/playwright-tests/tests/wallet-list.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test'; import { ReefKnotPage } from '@pages'; import { qase } from 'playwright-qase-reporter'; -test.describe(`ReefKnot. Wallet list`, async () => { +test.describe(`ReefKnot. Wallet list`, () => { let reefKnotPage: ReefKnotPage; const expectedWalletCount = 10; @@ -24,11 +24,10 @@ test.describe(`ReefKnot. Wallet list`, async () => { }); await test.step('Check the count of the available options to connect wallet', async () => { - const walletCount = await reefKnotPage.walletListModal.walletList - .getByRole('button') - .count(); + const walletCount = + reefKnotPage.walletListModal.walletList.getByRole('button'); - expect(walletCount).toBe(expectedWalletCount); + await expect(walletCount).toHaveCount(expectedWalletCount); }); }, ); diff --git a/playwright-tests/tests/wallet-stats.spec.ts b/playwright-tests/tests/wallet-stats.spec.ts index 43cc010c..2c1f41da 100644 --- a/playwright-tests/tests/wallet-stats.spec.ts +++ b/playwright-tests/tests/wallet-stats.spec.ts @@ -10,7 +10,7 @@ REEF_KNOT_CONFIG.WALLETS.forEach((wallet) => { test.describe( `ReefKnot. Check statistic (${wallet.name})`, { tag: [Tags.connectedWallet, `@${wallet.name}`] }, - async () => { + () => { let browserService: BrowserService; let reefKnotService: ReefKnotService; let reefKnotPage: ReefKnotPage; diff --git a/playwright-tests/tsconfig.json b/playwright-tests/tsconfig.json index 25718e7c..50350948 100644 --- a/playwright-tests/tsconfig.json +++ b/playwright-tests/tsconfig.json @@ -14,8 +14,8 @@ "declarationMap": true, "incremental": true, "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", - "module": "commonjs", + "moduleResolution": "NodeNext", + "module": "NodeNext", "target": "ES2020", "resolveJsonModule": true, "composite": true, @@ -24,13 +24,13 @@ "ES2020", "dom" ], - "baseUrl": ".", + "types": ["*"], "paths": { - "@test-data": ["test-data"], - "@config": ["config"], - "@pages": ["pages"], - "@services": ["services"], - "@browser": ["services/browser"] + "@test-data": ["./test-data"], + "@config": ["./config"], + "@pages": ["./pages"], + "@services": ["./services"], + "@browser": ["./services/browser"] } }, } diff --git a/playwright-tests/yarn.lock b/playwright-tests/yarn.lock index f6e5dcd1..2e2f9837 100644 --- a/playwright-tests/yarn.lock +++ b/playwright-tests/yarn.lock @@ -30,6 +30,132 @@ __metadata: languageName: node linkType: hard +"@cacheable/memory@npm:^2.2.0": + version: 2.2.0 + resolution: "@cacheable/memory@npm:2.2.0" + dependencies: + "@cacheable/utils": "npm:^2.5.0" + "@keyv/bigmap": "npm:^1.3.1" + hookified: "npm:^1.15.1" + keyv: "npm:^5.6.0" + checksum: 10/97db83d7a74979accca9de56cf278e42c22b4273e752d7e23c44fbec4a47450716c4920903424fd19184a7bee6325064b6c453afc6f96bf92b39eecfe0b40648 + languageName: node + linkType: hard + +"@cacheable/utils@npm:^2.5.0": + version: 2.5.0 + resolution: "@cacheable/utils@npm:2.5.0" + dependencies: + hashery: "npm:^1.5.1" + keyv: "npm:^5.6.0" + checksum: 10/a77a7e682926b984cb28b6993f4595638ce8799de3223dbdcdb796a077a02de763687bdc5669779019aba44d27693260ef92d860a19330d7eaa4dfcca3433c3b + languageName: node + linkType: hard + +"@emnapi/core@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/core@npm:1.10.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.1" + tslib: "npm:^2.4.0" + checksum: 10/d32f386084e64deaf2609aabb8295d1ad5af6144d0f46d2060b76cc53f1f3b486df54bec9b0f33c37d85a3822e1193ebcd4e3deb4a5f0e4cd650aa2ffc631715 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:1.10.0": + version: 1.10.0 + resolution: "@emnapi/runtime@npm:1.10.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/d21083d07fa0c2da171c142e78ef986b66b07d45b06accc0bcaf49fcc61bb4dbc10e1c1760813070165b9f49b054376a931045347f21c0f42ff1eb2d2040faac + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.2.1": + version: 1.2.1 + resolution: "@emnapi/wasi-threads@npm:1.2.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/57cd4292be81c05d26aa886d68a9e4c449ff666e8503fed6463dfc6b64a4e4213f03c152d53296b7cda32840271e38cd33347332070658f01befeb9bf4e59f36 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": + version: 4.10.1 + resolution: "@eslint-community/eslint-utils@npm:4.10.1" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10/61059b9f0192df5a86c441c03e0eedbda8c3810bb788775839afe4c5ec6bbdaa6433ac18001046b319390552435da3f6b8f5e18cca255993b3df37fe97a42b90 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.12.2": + version: 4.12.2 + resolution: "@eslint-community/regexpp@npm:4.12.2" + checksum: 10/049b280fddf71dd325514e0a520024969431dc3a8b02fa77476e6820e9122f28ab4c9168c11821f91a27982d2453bcd7a66193356ea84e84fb7c8d793be1ba0c + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.23.5": + version: 0.23.5 + resolution: "@eslint/config-array@npm:0.23.5" + dependencies: + "@eslint/object-schema": "npm:^3.0.5" + debug: "npm:^4.3.1" + minimatch: "npm:^10.2.4" + checksum: 10/0e05be2b5c8b9f9fb8094948fd2d35591a32091b9d39205181f2ed9bec0e2c8b2969f019f40a0388755a025408b98929e2d0beccb4fbd6609c1c0d6c9e9a14f0 + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.7.0": + version: 0.7.0 + resolution: "@eslint/config-helpers@npm:0.7.0" + dependencies: + "@eslint/core": "npm:^1.2.1" + checksum: 10/57f9cdf303fd56f0da6712e7d6da350c18a332f7d1dc0f5a5f8a9c357f0d5ab9ff9e7515be4726ad4b0fc41c297570a118d7ede02246c5b7a37932c3df46271e + languageName: node + linkType: hard + +"@eslint/core@npm:^1.2.1": + version: 1.2.1 + resolution: "@eslint/core@npm:1.2.1" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10/e1f9f5534f495b74a4c13c372e8f2feaf0c67f5dd666111c849c97c221d4ba730c98333a2ca94dd28cd7c24e3b1016bd868ca03c42e070732c047053f854cb13 + languageName: node + linkType: hard + +"@eslint/js@npm:10.0.1": + version: 10.0.1 + resolution: "@eslint/js@npm:10.0.1" + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/27ff77b8f0aab350b2f7a69d974eabb816bb9f4cab986b1538782269d6bfdc29e351803fa7a62c22c0b786341324f1a28b86bc83956ddfa189aa6bead1a87758 + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^3.0.5": + version: 3.0.5 + resolution: "@eslint/object-schema@npm:3.0.5" + checksum: 10/42e9ec2551d7cafe1825f20494576c9a867dfd26e728b66620f55d954cd5c4c9c4987755d147893985b8d39b49dace31117e59e7bc9564eb411b397e579a50e7 + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.7.3": + version: 0.7.3 + resolution: "@eslint/plugin-kit@npm:0.7.3" + dependencies: + "@eslint/core": "npm:^1.2.1" + levn: "npm:^0.4.1" + checksum: 10/bd603f0438d6829a5b0c8cbb90383e3b0fda3aac3a87faa22c80124ce4121f5dcfe8ef9b933c3308cbed70a27c4f51036403e3f0cb64ca2743e595dd865ccef6 + languageName: node + linkType: hard + "@ethersproject/abi@npm:5.8.0, @ethersproject/abi@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/abi@npm:5.8.0" @@ -457,6 +583,47 @@ __metadata: languageName: node linkType: hard +"@humanfs/core@npm:^0.19.2": + version: 0.19.2 + resolution: "@humanfs/core@npm:0.19.2" + dependencies: + "@humanfs/types": "npm:^0.15.0" + checksum: 10/c6c0273721ec8df3d36a57c390a11a168d0a2f513d78bceb25165bded4fcb73609b1a317edc6c8f331cefd4b47285dde0b1e6679e08ef7f062232ec14fe05312 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.8 + resolution: "@humanfs/node@npm:0.16.8" + dependencies: + "@humanfs/core": "npm:^0.19.2" + "@humanfs/types": "npm:^0.15.0" + "@humanwhocodes/retry": "npm:^0.4.0" + checksum: 10/ed01b3c066d9cec7526d139b9e71ca00ee4a30b3b5f5f5c198eb069c3509a3e167e180ba7e1e5a83b9571e906c4908bd20402b47586887452311af7354995e95 + languageName: node + linkType: hard + +"@humanfs/types@npm:^0.15.0": + version: 0.15.0 + resolution: "@humanfs/types@npm:0.15.0" + checksum: 10/dea3cc7fd8f8d4d088ed8d0a9921cf12bd8e1cdf40a6133106b03a6e2aebcc9a6f1771b3643b7ec71baae90d08245db34069dfcc861da8d678662741e6c3c986 + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10/e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10/0b32cfd362bea7a30fbf80bb38dcaf77fee9c2cae477ee80b460871d03590110ac9c77d654f04ec5beaf71b6f6a89851bdf6c1e34ccdf2f686bd86fcd97d9e61 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -512,6 +679,25 @@ __metadata: languageName: node linkType: hard +"@keyv/bigmap@npm:^1.3.1": + version: 1.3.1 + resolution: "@keyv/bigmap@npm:1.3.1" + dependencies: + hashery: "npm:^1.4.0" + hookified: "npm:^1.15.0" + peerDependencies: + keyv: ^5.6.0 + checksum: 10/9745786a94729117460b5399a964ec151e94a89db0e5ed573419c4c620f0595f05d7ad87d596bb7e212a4f3ad2335271694fddcfaa8400013f7b64e11669a884 + languageName: node + linkType: hard + +"@keyv/serialize@npm:^1.1.1": + version: 1.1.1 + resolution: "@keyv/serialize@npm:1.1.1" + checksum: 10/e3b2cb1377863342acedd5ff785af3e69269bee9b44707c617d1c8bc14eeb5ac763159d6455903ffe92f143c2238e1e783c4f113f9c8910eacccf172894472da + languageName: node + linkType: hard + "@lidofinance/browser-service@npm:1.11.2": version: 1.11.2 resolution: "@lidofinance/browser-service@npm:1.11.2" @@ -608,6 +794,18 @@ __metadata: languageName: node linkType: hard +"@napi-rs/wasm-runtime@npm:^1.1.4": + version: 1.2.5 + resolution: "@napi-rs/wasm-runtime@npm:1.2.5" + dependencies: + "@tybys/wasm-util": "npm:^0.10.3" + peerDependencies: + "@emnapi/core": ^1.7.1 || ^2.0.0-alpha.4 + "@emnapi/runtime": ^1.7.1 || ^2.0.0-alpha.4 + checksum: 10/b8367e6d47ff12b429efeefdfe42e316e920ca2fa4478d7bb926c50d101be43302084c89a519cb54d0ca1719d798b64e7d579dc2df8448d311aae999f44dfdd7 + languageName: node + linkType: hard + "@nestjs/common@npm:^10.0.0": version: 10.4.19 resolution: "@nestjs/common@npm:10.4.19" @@ -748,6 +946,13 @@ __metadata: languageName: node linkType: hard +"@pkgr/core@npm:^0.3.6": + version: 0.3.6 + resolution: "@pkgr/core@npm:0.3.6" + checksum: 10/29082aa13d36f13fc41cdc64cb1feb36b630de0d6ebde84e2ff68e3d7a7f1dce4462cca91f76176c46e50bbca6b1e7f1fd9cf907af12d5d70da83bc981ca4ccf + languageName: node + linkType: hard + "@playwright/test@npm:^1.57.0": version: 1.57.0 resolution: "@playwright/test@npm:1.57.0" @@ -759,6 +964,13 @@ __metadata: languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 10/17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + "@scure/base@npm:1.2.6, @scure/base@npm:~1.2.5": version: 1.2.6 resolution: "@scure/base@npm:1.2.6" @@ -868,6 +1080,29 @@ __metadata: languageName: node linkType: hard +"@tybys/wasm-util@npm:^0.10.3": + version: 0.10.4 + resolution: "@tybys/wasm-util@npm:0.10.4" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/da910a0439afad49a6427e4d16fcd5a52199cb471e07c262e1dd5ed7664908e6f142f4dca1b09895c53f4ca4402663042d760f41c9fa7ff33f76c662739646df + languageName: node + linkType: hard + +"@types/esrecurse@npm:^4.3.1": + version: 4.3.1 + resolution: "@types/esrecurse@npm:4.3.1" + checksum: 10/ada5798554b76ac466e90fff26a769b65f905666f32988dcd1b6cf8288896e0fb53080843fd644bf731d16719a6e09b155d623ce36545b75abdd99bb6dcec114 + languageName: node + linkType: hard + +"@types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": + version: 1.0.9 + resolution: "@types/estree@npm:1.0.9" + checksum: 10/16aabfa703b5bdac83f719b07ce92a11b2d3c9b8628eacc92889d8af46cab2d78fc45c7b5378de383d0500585cea5c2f79125eeddfe5fbc6bd6a27eb0c8ccee5 + languageName: node + linkType: hard + "@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" @@ -893,6 +1128,20 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 + languageName: node + linkType: hard + +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: 10/4e5aed58cabb2bbf6f725da13421aa50a49abb6bc17bfab6c31b8774b073fa7b50d557c61f961a09a85f6056151190f8ac95f13f5b48136ba5841f7d4484ec56 + languageName: node + linkType: hard + "@types/node@npm:*": version: 22.9.1 resolution: "@types/node@npm:22.9.1" @@ -925,156 +1174,670 @@ __metadata: languageName: node linkType: hard -"@walletconnect/core@npm:2.23.4": - version: 2.23.4 - resolution: "@walletconnect/core@npm:2.23.4" +"@typescript-eslint/eslint-plugin@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/eslint-plugin@npm:8.71.1" dependencies: - "@walletconnect/heartbeat": "npm:1.2.2" - "@walletconnect/jsonrpc-provider": "npm:1.0.14" - "@walletconnect/jsonrpc-types": "npm:1.0.4" - "@walletconnect/jsonrpc-utils": "npm:1.0.8" - "@walletconnect/jsonrpc-ws-connection": "npm:1.0.16" - "@walletconnect/keyvaluestorage": "npm:1.1.1" - "@walletconnect/logger": "npm:3.0.2" - "@walletconnect/relay-api": "npm:1.0.11" - "@walletconnect/relay-auth": "npm:1.1.0" - "@walletconnect/safe-json": "npm:1.0.2" - "@walletconnect/time": "npm:1.0.2" - "@walletconnect/types": "npm:2.23.4" - "@walletconnect/utils": "npm:2.23.4" - "@walletconnect/window-getters": "npm:1.0.1" - es-toolkit: "npm:1.44.0" - events: "npm:3.3.0" - uint8arrays: "npm:3.1.1" - checksum: 10/cb2291eacefbf6dda518eda124e4f7ba1dbc66aae38647976e68e08e771795684187f9724adb14eb7565df857882902d205480954d6a931e4c5d71ef94f77957 + "@eslint-community/regexpp": "npm:^4.12.2" + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/type-utils": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + ignore: "npm:^7.0.5" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + "@typescript-eslint/parser": ^8.71.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/dc117ca7be83d17b41d3298165b336d46797da247a8388614f3f65afc7875fb4fe23ffe28eb0c37a4e83deacd4ec8e94624a2c8de151ba6b41b58f9207e5c164 languageName: node linkType: hard -"@walletconnect/environment@npm:^1.0.1": - version: 1.0.1 - resolution: "@walletconnect/environment@npm:1.0.1" +"@typescript-eslint/parser@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/parser@npm:8.71.1" dependencies: - tslib: "npm:1.14.1" - checksum: 10/f6a1e3456e50cc7cfa58d99fd513ecac75573d0b8bcbbedcb1d7ec04ca9108df16b471afd40761b2a5cb4f66d8e33b7ba25f02c62c8365d68b1bd1ef52c1813e + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + debug: "npm:^4.4.3" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/8ce699481f3cec81292889f77f1cffbef68d5f011b0fe1f71150d973794b6d2da89971b80b94824d7fa8bc54ff007a5e632ad6cfb66c595ce8fc1b852cac0c10 languageName: node linkType: hard -"@walletconnect/events@npm:1.0.1, @walletconnect/events@npm:^1.0.1": - version: 1.0.1 - resolution: "@walletconnect/events@npm:1.0.1" +"@typescript-eslint/project-service@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/project-service@npm:8.71.1" dependencies: - keyvaluestorage-interface: "npm:^1.0.0" - tslib: "npm:1.14.1" - checksum: 10/b5a105e9ac4d7d0a500085afd77b71e71a8ab78fd38b033e4ce91f8626fd8c254b1ba49a59c8c0ed8a00a7e8b93995163f414eda73c58694f8f830e453a902b6 + "@typescript-eslint/tsconfig-utils": "npm:^8.71.1" + "@typescript-eslint/types": "npm:^8.71.1" + debug: "npm:^4.4.3" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/9de11189629df886d456d2e80d1541060e5598f512ba42231953445a94764aa863fbc32b652735ee0694543fd6b0012b0807cda6b92d751a46fcd5fbcb481e3b languageName: node linkType: hard -"@walletconnect/heartbeat@npm:1.2.2": - version: 1.2.2 - resolution: "@walletconnect/heartbeat@npm:1.2.2" +"@typescript-eslint/scope-manager@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/scope-manager@npm:8.71.1" dependencies: - "@walletconnect/events": "npm:^1.0.1" - "@walletconnect/time": "npm:^1.0.2" - events: "npm:^3.3.0" - checksum: 10/f3a1c3c255ac9bd374b25e1ef65a61b1f623b9118d48471acaac1f9ee4ee1438d8d8cbc77733cdd980809b468443c046328fe5ac4084e01e0892f8c699cf44e7 + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + checksum: 10/59b0ee05006c4be44eb939ee8a1c0ed60d79fdabe7211f6adc30989541c306b07934144c51ec454ad8252cbe95ab8b38400ffe123977ae2ce512e76d460e5e98 languageName: node linkType: hard -"@walletconnect/jsonrpc-provider@npm:1.0.14": - version: 1.0.14 - resolution: "@walletconnect/jsonrpc-provider@npm:1.0.14" - dependencies: - "@walletconnect/jsonrpc-utils": "npm:^1.0.8" - "@walletconnect/safe-json": "npm:^1.0.2" - events: "npm:^3.3.0" - checksum: 10/c3c78f00148043b70213f5174d537b210f1fb231d96103cbf7d0101626578d3c13fe99ac080df7a0056c7128ce488b0523eda0e3d1deed75754672848b4909a5 +"@typescript-eslint/tsconfig-utils@npm:8.71.1, @typescript-eslint/tsconfig-utils@npm:^8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.71.1" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/7a3a71b00f898d8ef53a3aed992597ae6bc56f8b6310cb8180b8f226979877afcb2628fbdc7a4b6f59db8ced5f6779b1fa684c0785e63a99b545f60de31ece51 languageName: node linkType: hard -"@walletconnect/jsonrpc-types@npm:1.0.4, @walletconnect/jsonrpc-types@npm:^1.0.2, @walletconnect/jsonrpc-types@npm:^1.0.3": - version: 1.0.4 - resolution: "@walletconnect/jsonrpc-types@npm:1.0.4" +"@typescript-eslint/type-utils@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/type-utils@npm:8.71.1" dependencies: - events: "npm:^3.3.0" - keyvaluestorage-interface: "npm:^1.0.0" - checksum: 10/8cdc9f7b5e3ae0d702a44a6fc4c388a2b627188df758ffd103ba9aac6596a787d2f319aa8f6928a03d990c71c17d9b876028f36b8e0c37bd5c9026231ed9ba45 + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" + debug: "npm:^4.4.3" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/56b5b433062b9005c1c627aec3cae4bfe6b3647bb08d826ec82fb4279c5f2c781028ce2e6274d38440eea53d348f393ad6b40a5e82825cf057de32fb813cb2f3 languageName: node linkType: hard -"@walletconnect/jsonrpc-utils@npm:1.0.8, @walletconnect/jsonrpc-utils@npm:^1.0.6, @walletconnect/jsonrpc-utils@npm:^1.0.8": - version: 1.0.8 - resolution: "@walletconnect/jsonrpc-utils@npm:1.0.8" - dependencies: - "@walletconnect/environment": "npm:^1.0.1" - "@walletconnect/jsonrpc-types": "npm:^1.0.3" - tslib: "npm:1.14.1" - checksum: 10/4687b4582a5c33883d94e87ca8bb22d129a2a47b6e1d9e2c3210b74f02d9677723b3bf2283d2f0fa69866b0a66a80cdfada9a2f1c204d485fbd10d2baed1f0a6 +"@typescript-eslint/types@npm:8.71.1, @typescript-eslint/types@npm:^8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/types@npm:8.71.1" + checksum: 10/e719c89af197092fe69bee725582013e57b661d14f2edbdf0637811216e207139876d57631708d544ede41e52b1a01200e0511c8d9c46742d408cc70f3edc7a1 languageName: node linkType: hard -"@walletconnect/jsonrpc-ws-connection@npm:1.0.16": - version: 1.0.16 - resolution: "@walletconnect/jsonrpc-ws-connection@npm:1.0.16" +"@typescript-eslint/typescript-estree@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.71.1" dependencies: - "@walletconnect/jsonrpc-utils": "npm:^1.0.6" - "@walletconnect/safe-json": "npm:^1.0.2" - events: "npm:^3.3.0" - ws: "npm:^7.5.1" - checksum: 10/98e06097588f895c4ba14b6feb64ed9b5c125d57a4ea3ad3fa6f52fd090fccce60808252c8cefaddc022cfa7fde7551a3aec3bb36e6b08c622207d7554d93e40 + "@typescript-eslint/project-service": "npm:8.71.1" + "@typescript-eslint/tsconfig-utils": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/73cd8debfea2ffe582f689a615cdc875f0e97f0430eef55db7158443b37bedbf1ed76559e7ddfd445ad9b4d5de9cee3afe54dda1512cca0d4e31d1dcc6a12c41 languageName: node linkType: hard -"@walletconnect/keyvaluestorage@npm:1.1.1": - version: 1.1.1 - resolution: "@walletconnect/keyvaluestorage@npm:1.1.1" +"@typescript-eslint/utils@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/utils@npm:8.71.1" dependencies: - "@walletconnect/safe-json": "npm:^1.0.1" - idb-keyval: "npm:^6.2.1" - unstorage: "npm:^1.9.0" + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" peerDependencies: - "@react-native-async-storage/async-storage": 1.x - peerDependenciesMeta: - "@react-native-async-storage/async-storage": - optional: true - checksum: 10/fd9c275b3249d8e9f722866703b5c040eb35d0670c92a297428ffb700ac36c6b9978242beac5d2cfe97eb522ae01307cacd9c79ecf95640878804fce0f13c5e7 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/8427c5634502be65a149cdc1681986fc306332f2309fc6525d85e3b44d5b35fd2d35ee51989a71277d722455a06455154dc267796218723af384776d6b2f289e languageName: node linkType: hard -"@walletconnect/logger@npm:3.0.2": - version: 3.0.2 - resolution: "@walletconnect/logger@npm:3.0.2" +"@typescript-eslint/visitor-keys@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.71.1" dependencies: - "@walletconnect/safe-json": "npm:^1.0.2" - pino: "npm:10.0.0" - checksum: 10/786626556ab11483cf56f0819ccc287639128142029b7b327e09cfbad2d03839c9e2e4f80194d54f4bbf6e501a85864f0fcf1011adc62df0eecb067ff320ac84 + "@typescript-eslint/types": "npm:8.71.1" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10/9abc7b1a266eb65b16ac16d99e334d06e0539241e5ae9b6721a11a6a1d2736a9f564dc5e5dc37e7d0bfce5e260da6495bab9d594a1317d01624d239286bd12c2 languageName: node linkType: hard -"@walletconnect/relay-api@npm:1.0.11": - version: 1.0.11 - resolution: "@walletconnect/relay-api@npm:1.0.11" - dependencies: - "@walletconnect/jsonrpc-types": "npm:^1.0.2" - checksum: 10/d85f88b9744917ee5b36d2df23bf4012819b14b73229f9bdca942bee11dd3b3428808c7528c2b1f6b3d91fa1d34a22b1e20b46533e402301318cbd4ab59b9c17 +"@typescript/native@npm:typescript@7.0.2": + version: 7.0.2 + resolution: "typescript@npm:7.0.2" + dependencies: + "@typescript/typescript-aix-ppc64": "npm:7.0.2" + "@typescript/typescript-darwin-arm64": "npm:7.0.2" + "@typescript/typescript-darwin-x64": "npm:7.0.2" + "@typescript/typescript-freebsd-arm64": "npm:7.0.2" + "@typescript/typescript-freebsd-x64": "npm:7.0.2" + "@typescript/typescript-linux-arm": "npm:7.0.2" + "@typescript/typescript-linux-arm64": "npm:7.0.2" + "@typescript/typescript-linux-loong64": "npm:7.0.2" + "@typescript/typescript-linux-mips64el": "npm:7.0.2" + "@typescript/typescript-linux-ppc64": "npm:7.0.2" + "@typescript/typescript-linux-riscv64": "npm:7.0.2" + "@typescript/typescript-linux-s390x": "npm:7.0.2" + "@typescript/typescript-linux-x64": "npm:7.0.2" + "@typescript/typescript-netbsd-arm64": "npm:7.0.2" + "@typescript/typescript-netbsd-x64": "npm:7.0.2" + "@typescript/typescript-openbsd-arm64": "npm:7.0.2" + "@typescript/typescript-openbsd-x64": "npm:7.0.2" + "@typescript/typescript-sunos-x64": "npm:7.0.2" + "@typescript/typescript-win32-arm64": "npm:7.0.2" + "@typescript/typescript-win32-x64": "npm:7.0.2" + dependenciesMeta: + "@typescript/typescript-aix-ppc64": + optional: true + "@typescript/typescript-darwin-arm64": + optional: true + "@typescript/typescript-darwin-x64": + optional: true + "@typescript/typescript-freebsd-arm64": + optional: true + "@typescript/typescript-freebsd-x64": + optional: true + "@typescript/typescript-linux-arm": + optional: true + "@typescript/typescript-linux-arm64": + optional: true + "@typescript/typescript-linux-loong64": + optional: true + "@typescript/typescript-linux-mips64el": + optional: true + "@typescript/typescript-linux-ppc64": + optional: true + "@typescript/typescript-linux-riscv64": + optional: true + "@typescript/typescript-linux-s390x": + optional: true + "@typescript/typescript-linux-x64": + optional: true + "@typescript/typescript-netbsd-arm64": + optional: true + "@typescript/typescript-netbsd-x64": + optional: true + "@typescript/typescript-openbsd-arm64": + optional: true + "@typescript/typescript-openbsd-x64": + optional: true + "@typescript/typescript-sunos-x64": + optional: true + "@typescript/typescript-win32-arm64": + optional: true + "@typescript/typescript-win32-x64": + optional: true + bin: + tsc: bin/tsc + checksum: 10/b0179005349b43dc1febb35c4e79162cdf89b84eae60f6deac142429109041e07582e69a6aacf5a897e085869686d4512ea444a10acf5b5aa2b60910f82a19ca languageName: node linkType: hard -"@walletconnect/relay-auth@npm:1.1.0": - version: 1.1.0 - resolution: "@walletconnect/relay-auth@npm:1.1.0" - dependencies: - "@noble/curves": "npm:1.8.0" - "@noble/hashes": "npm:1.7.0" - "@walletconnect/safe-json": "npm:^1.0.1" - "@walletconnect/time": "npm:^1.0.2" - uint8arrays: "npm:^3.0.0" - checksum: 10/0fd6c2e05ced76fbc8e6a84c0a8e73458779662aea55568f51cd9066c337d8a12f2869f0bd717024bbe5955cc605241e68505ebac40406ed2a1bdacba42431b1 +"@typescript/old@npm:typescript@^6": + version: 6.0.3 + resolution: "typescript@npm:6.0.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/0ef2357a4cffd916b52b683a021cdab0f81eea4e9aa35f2d254581c9a5106da02224e3392e1b0ed42b7a48f80c966e5f52b8e1a27941fa0523c1705a9c2e0330 languageName: node linkType: hard -"@walletconnect/safe-json@npm:1.0.2, @walletconnect/safe-json@npm:^1.0.1, @walletconnect/safe-json@npm:^1.0.2": - version: 1.0.2 - resolution: "@walletconnect/safe-json@npm:1.0.2" +"@typescript/typescript-aix-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-aix-ppc64@npm:7.0.2" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@typescript/typescript-darwin-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-arm64@npm:7.0.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-darwin-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-x64@npm:7.0.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-freebsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-arm64@npm:7.0.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-freebsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-x64@npm:7.0.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm64@npm:7.0.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm@npm:7.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@typescript/typescript-linux-loong64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-loong64@npm:7.0.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-mips64el@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-mips64el@npm:7.0.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@typescript/typescript-linux-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-ppc64@npm:7.0.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-riscv64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-riscv64@npm:7.0.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-s390x@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-s390x@npm:7.0.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@typescript/typescript-linux-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-x64@npm:7.0.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-arm64@npm:7.0.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-x64@npm:7.0.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-arm64@npm:7.0.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-x64@npm:7.0.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-sunos-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-sunos-x64@npm:7.0.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-arm64@npm:7.0.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-x64@npm:7.0.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm-eabi@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.12.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm64@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-android-arm64@npm:1.12.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-arm64@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.12.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-x64@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-darwin-x64@npm:1.12.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-freebsd-x64@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.12.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.12.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.12.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.12.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-musl@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.12.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-loong64-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-loong64-gnu@npm:1.12.2" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-loong64-musl@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-loong64-musl@npm:1.12.2" + conditions: os=linux & cpu=loong64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.12.2" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.12.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-musl@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.12.2" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-s390x-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.12.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-gnu@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.12.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-musl@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.12.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-openharmony-arm64@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-openharmony-arm64@npm:1.12.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-wasm32-wasi@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.12.2" + dependencies: + "@emnapi/core": "npm:1.10.0" + "@emnapi/runtime": "npm:1.10.0" + "@napi-rs/wasm-runtime": "npm:^1.1.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-arm64-msvc@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.12.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-ia32-msvc@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.12.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-x64-msvc@npm:1.12.2": + version: 1.12.2 + resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.12.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@walletconnect/core@npm:2.23.4": + version: 2.23.4 + resolution: "@walletconnect/core@npm:2.23.4" + dependencies: + "@walletconnect/heartbeat": "npm:1.2.2" + "@walletconnect/jsonrpc-provider": "npm:1.0.14" + "@walletconnect/jsonrpc-types": "npm:1.0.4" + "@walletconnect/jsonrpc-utils": "npm:1.0.8" + "@walletconnect/jsonrpc-ws-connection": "npm:1.0.16" + "@walletconnect/keyvaluestorage": "npm:1.1.1" + "@walletconnect/logger": "npm:3.0.2" + "@walletconnect/relay-api": "npm:1.0.11" + "@walletconnect/relay-auth": "npm:1.1.0" + "@walletconnect/safe-json": "npm:1.0.2" + "@walletconnect/time": "npm:1.0.2" + "@walletconnect/types": "npm:2.23.4" + "@walletconnect/utils": "npm:2.23.4" + "@walletconnect/window-getters": "npm:1.0.1" + es-toolkit: "npm:1.44.0" + events: "npm:3.3.0" + uint8arrays: "npm:3.1.1" + checksum: 10/cb2291eacefbf6dda518eda124e4f7ba1dbc66aae38647976e68e08e771795684187f9724adb14eb7565df857882902d205480954d6a931e4c5d71ef94f77957 + languageName: node + linkType: hard + +"@walletconnect/environment@npm:^1.0.1": + version: 1.0.1 + resolution: "@walletconnect/environment@npm:1.0.1" + dependencies: + tslib: "npm:1.14.1" + checksum: 10/f6a1e3456e50cc7cfa58d99fd513ecac75573d0b8bcbbedcb1d7ec04ca9108df16b471afd40761b2a5cb4f66d8e33b7ba25f02c62c8365d68b1bd1ef52c1813e + languageName: node + linkType: hard + +"@walletconnect/events@npm:1.0.1, @walletconnect/events@npm:^1.0.1": + version: 1.0.1 + resolution: "@walletconnect/events@npm:1.0.1" + dependencies: + keyvaluestorage-interface: "npm:^1.0.0" + tslib: "npm:1.14.1" + checksum: 10/b5a105e9ac4d7d0a500085afd77b71e71a8ab78fd38b033e4ce91f8626fd8c254b1ba49a59c8c0ed8a00a7e8b93995163f414eda73c58694f8f830e453a902b6 + languageName: node + linkType: hard + +"@walletconnect/heartbeat@npm:1.2.2": + version: 1.2.2 + resolution: "@walletconnect/heartbeat@npm:1.2.2" + dependencies: + "@walletconnect/events": "npm:^1.0.1" + "@walletconnect/time": "npm:^1.0.2" + events: "npm:^3.3.0" + checksum: 10/f3a1c3c255ac9bd374b25e1ef65a61b1f623b9118d48471acaac1f9ee4ee1438d8d8cbc77733cdd980809b468443c046328fe5ac4084e01e0892f8c699cf44e7 + languageName: node + linkType: hard + +"@walletconnect/jsonrpc-provider@npm:1.0.14": + version: 1.0.14 + resolution: "@walletconnect/jsonrpc-provider@npm:1.0.14" + dependencies: + "@walletconnect/jsonrpc-utils": "npm:^1.0.8" + "@walletconnect/safe-json": "npm:^1.0.2" + events: "npm:^3.3.0" + checksum: 10/c3c78f00148043b70213f5174d537b210f1fb231d96103cbf7d0101626578d3c13fe99ac080df7a0056c7128ce488b0523eda0e3d1deed75754672848b4909a5 + languageName: node + linkType: hard + +"@walletconnect/jsonrpc-types@npm:1.0.4, @walletconnect/jsonrpc-types@npm:^1.0.2, @walletconnect/jsonrpc-types@npm:^1.0.3": + version: 1.0.4 + resolution: "@walletconnect/jsonrpc-types@npm:1.0.4" + dependencies: + events: "npm:^3.3.0" + keyvaluestorage-interface: "npm:^1.0.0" + checksum: 10/8cdc9f7b5e3ae0d702a44a6fc4c388a2b627188df758ffd103ba9aac6596a787d2f319aa8f6928a03d990c71c17d9b876028f36b8e0c37bd5c9026231ed9ba45 + languageName: node + linkType: hard + +"@walletconnect/jsonrpc-utils@npm:1.0.8, @walletconnect/jsonrpc-utils@npm:^1.0.6, @walletconnect/jsonrpc-utils@npm:^1.0.8": + version: 1.0.8 + resolution: "@walletconnect/jsonrpc-utils@npm:1.0.8" + dependencies: + "@walletconnect/environment": "npm:^1.0.1" + "@walletconnect/jsonrpc-types": "npm:^1.0.3" + tslib: "npm:1.14.1" + checksum: 10/4687b4582a5c33883d94e87ca8bb22d129a2a47b6e1d9e2c3210b74f02d9677723b3bf2283d2f0fa69866b0a66a80cdfada9a2f1c204d485fbd10d2baed1f0a6 + languageName: node + linkType: hard + +"@walletconnect/jsonrpc-ws-connection@npm:1.0.16": + version: 1.0.16 + resolution: "@walletconnect/jsonrpc-ws-connection@npm:1.0.16" + dependencies: + "@walletconnect/jsonrpc-utils": "npm:^1.0.6" + "@walletconnect/safe-json": "npm:^1.0.2" + events: "npm:^3.3.0" + ws: "npm:^7.5.1" + checksum: 10/98e06097588f895c4ba14b6feb64ed9b5c125d57a4ea3ad3fa6f52fd090fccce60808252c8cefaddc022cfa7fde7551a3aec3bb36e6b08c622207d7554d93e40 + languageName: node + linkType: hard + +"@walletconnect/keyvaluestorage@npm:1.1.1": + version: 1.1.1 + resolution: "@walletconnect/keyvaluestorage@npm:1.1.1" + dependencies: + "@walletconnect/safe-json": "npm:^1.0.1" + idb-keyval: "npm:^6.2.1" + unstorage: "npm:^1.9.0" + peerDependencies: + "@react-native-async-storage/async-storage": 1.x + peerDependenciesMeta: + "@react-native-async-storage/async-storage": + optional: true + checksum: 10/fd9c275b3249d8e9f722866703b5c040eb35d0670c92a297428ffb700ac36c6b9978242beac5d2cfe97eb522ae01307cacd9c79ecf95640878804fce0f13c5e7 + languageName: node + linkType: hard + +"@walletconnect/logger@npm:3.0.2": + version: 3.0.2 + resolution: "@walletconnect/logger@npm:3.0.2" + dependencies: + "@walletconnect/safe-json": "npm:^1.0.2" + pino: "npm:10.0.0" + checksum: 10/786626556ab11483cf56f0819ccc287639128142029b7b327e09cfbad2d03839c9e2e4f80194d54f4bbf6e501a85864f0fcf1011adc62df0eecb067ff320ac84 + languageName: node + linkType: hard + +"@walletconnect/relay-api@npm:1.0.11": + version: 1.0.11 + resolution: "@walletconnect/relay-api@npm:1.0.11" + dependencies: + "@walletconnect/jsonrpc-types": "npm:^1.0.2" + checksum: 10/d85f88b9744917ee5b36d2df23bf4012819b14b73229f9bdca942bee11dd3b3428808c7528c2b1f6b3d91fa1d34a22b1e20b46533e402301318cbd4ab59b9c17 + languageName: node + linkType: hard + +"@walletconnect/relay-auth@npm:1.1.0": + version: 1.1.0 + resolution: "@walletconnect/relay-auth@npm:1.1.0" + dependencies: + "@noble/curves": "npm:1.8.0" + "@noble/hashes": "npm:1.7.0" + "@walletconnect/safe-json": "npm:^1.0.1" + "@walletconnect/time": "npm:^1.0.2" + uint8arrays: "npm:^3.0.0" + checksum: 10/0fd6c2e05ced76fbc8e6a84c0a8e73458779662aea55568f51cd9066c337d8a12f2869f0bd717024bbe5955cc605241e68505ebac40406ed2a1bdacba42431b1 + languageName: node + linkType: hard + +"@walletconnect/safe-json@npm:1.0.2, @walletconnect/safe-json@npm:^1.0.1, @walletconnect/safe-json@npm:^1.0.2": + version: 1.0.2 + resolution: "@walletconnect/safe-json@npm:1.0.2" dependencies: tslib: "npm:1.14.1" checksum: 10/b9d031dab3916d20fa5241d7ad2be425368ae489995ba3ba18d6ad88e81ad3ed093b8e867b8a4fc44759099896aeb5afee5635858cb80c4819ebc7ebb71ed5a6 @@ -1220,6 +1983,24 @@ __metadata: languageName: node linkType: hard +"acorn-jsx@npm:^5.3.2": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10/d4371eaef7995530b5b5ca4183ff6f062ca17901a6d3f673c9ac011b01ede37e7a1f7f61f8f5cfe709e88054757bb8f3277dc4061087cdf4f2a1f90ccbcdb977 + languageName: node + linkType: hard + +"acorn@npm:^8.16.0": + version: 8.19.0 + resolution: "acorn@npm:8.19.0" + bin: + acorn: bin/acorn + checksum: 10/99307d577b38d6a441cd478456633b5b669d32bc722633ff84f1f3c88d361735d7cf01d04ecbf1113c70f1f39e5ceceb95cd5bf93b15bacaddc8fca1ea5e7496 + languageName: node + linkType: hard + "aes-js@npm:3.0.0": version: 3.0.0 resolution: "aes-js@npm:3.0.0" @@ -1243,6 +2024,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^6.14.0": + version: 6.15.0 + resolution: "ajv@npm:6.15.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10/0916dda09c152fb5857bc1cc7ce61718e9cec5b7faeff44a74f5e324eed8a556e1a84856724ea322a067b436ecad9f74ac8295fd395449788cca52f0c25bd5fb + languageName: node + linkType: hard + "ajv@npm:^8.0.0": version: 8.18.0 resolution: "ajv@npm:8.18.0" @@ -1308,9 +2101,89 @@ __metadata: version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: - normalize-path: "npm:^3.0.0" - picomatch: "npm:^2.0.4" - checksum: 10/3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 10/3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + +"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "array-buffer-byte-length@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + is-array-buffer: "npm:^3.0.5" + checksum: 10/0ae3786195c3211b423e5be8dd93357870e6fb66357d81da968c2c39ef43583ef6eece1f9cb1caccdae4806739c65dea832b44b8593414313cd76a89795fca63 + languageName: node + linkType: hard + +"array-includes@npm:^3.1.9": + version: 3.2.0 + resolution: "array-includes@npm:3.2.0" + dependencies: + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.24.2" + es-object-atoms: "npm:^1.1.2" + es-shim-unscopables: "npm:^1.1.0" + is-string: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + checksum: 10/c6b00774aa3f0100dbc5443722b69b0aa7ff5e31e28d2fc9ac69adc394c9fba4bc5cfea292bfbb20369a9657a8a67e0e9a128863cc0f9c426852e7cb11f6715e + languageName: node + linkType: hard + +"array.prototype.findlastindex@npm:^1.2.6": + version: 1.2.6 + resolution: "array.prototype.findlastindex@npm:1.2.6" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.9" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + es-shim-unscopables: "npm:^1.1.0" + checksum: 10/5ddb6420e820bef6ddfdcc08ce780d0fd5e627e97457919c27e32359916de5a11ce12f7c55073555e503856618eaaa70845d6ca11dcba724766f38eb1c22f7a2 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flat@npm:1.3.3" + dependencies: + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/f9b992fa0775d8f7c97abc91eb7f7b2f0ed8430dd9aeb9fdc2967ac4760cdd7fc2ef7ead6528fef40c7261e4d790e117808ce0d3e7e89e91514d4963a531cd01 + languageName: node + linkType: hard + +"array.prototype.flatmap@npm:^1.3.3": + version: 1.3.3 + resolution: "array.prototype.flatmap@npm:1.3.3" + dependencies: + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-shim-unscopables: "npm:^1.0.2" + checksum: 10/473534573aa4b37b1d80705d0ce642f5933cccf5617c9f3e8a56686e9815ba93d469138e86a1f25d2fe8af999c3d24f54d703ec1fc2db2e6778d46d0f4ac951e + languageName: node + linkType: hard + +"arraybuffer.prototype.slice@npm:^1.0.4": + version: 1.0.4 + resolution: "arraybuffer.prototype.slice@npm:1.0.4" + dependencies: + array-buffer-byte-length: "npm:^1.0.1" + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.5" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + is-array-buffer: "npm:^3.0.4" + checksum: 10/4821ebdfe7d699f910c7f09bc9fa996f09b96b80bccb4f5dd4b59deae582f6ad6e505ecef6376f8beac1eda06df2dbc89b70e82835d104d6fcabd33c1aed1ae9 languageName: node linkType: hard @@ -1351,6 +2224,15 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10/6c9da3a66caddd83c875010a1ca8ef11eac02ba15fb592dc9418b2b5e7b77b645fa7729380a92d9835c2f05f2ca1b6251f39b993e0feb3f1517c74fa1af02cab + languageName: node + linkType: hard + "axios-retry@npm:^4.5.0": version: 4.5.0 resolution: "axios-retry@npm:4.5.0" @@ -1381,6 +2263,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10/fb07bb66a0959c2843fc055838047e2a95ccebb837c519614afb067ebfdf2fa967ca8d712c35ced07f2cd26fc6f07964230b094891315ad74f11eba3d53178a0 + languageName: node + linkType: hard + "base-x@npm:^5.0.0": version: 5.0.1 resolution: "base-x@npm:5.0.1" @@ -1466,6 +2355,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^5.0.8": + version: 5.0.12 + resolution: "brace-expansion@npm:5.0.12" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10/65b550f1836e3b43f512f12afbc3be96616eee5c353e16d70181b7dffec8c08beabffb51d69a3bbdb27d675840725cbab025fda9d10716b5cda7dd864dc7bc4a + languageName: node + linkType: hard + "braces@npm:^3.0.3": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -1525,6 +2423,19 @@ __metadata: languageName: node linkType: hard +"cacheable@npm:^2.5.0": + version: 2.5.0 + resolution: "cacheable@npm:2.5.0" + dependencies: + "@cacheable/memory": "npm:^2.2.0" + "@cacheable/utils": "npm:^2.5.0" + hookified: "npm:^1.15.0" + keyv: "npm:^5.6.0" + qified: "npm:^0.10.1" + checksum: 10/216a896e17dfa9c598a69e2fff31216126e94286f6c0ceb1bfab1d34e6c1a8791e8dc34dbd28660ec72a84f1d370c3733a9fc481e00a5512fd4e0cfc35775db6 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -1535,6 +2446,28 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8, call-bind@npm:^1.0.9": + version: 1.0.9 + resolution: "call-bind@npm:1.0.9" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + get-intrinsic: "npm:^1.3.0" + set-function-length: "npm:^1.2.2" + checksum: 10/25b1a98d6158f0adf9fface594ca82be4e3ed481d8ff7f36ad1fccb0c8377e38c6a04ff3248693723222d378677e93077c739defc8a6741c82b7e00bcee1245d + languageName: node + linkType: hard + +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10/ef2b96e126ec0e58a7ff694db43f4d0d44f80e641370c21549ed911fecbdbc2df3ebc9bddad918d6bbdefeafb60bb3337902006d5176d72bcd2da74820991af7 + languageName: node + linkType: hard + "chainsaw@npm:~0.1.0": version: 0.1.0 resolution: "chainsaw@npm:0.1.0" @@ -1652,6 +2585,39 @@ __metadata: languageName: node linkType: hard +"data-view-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-buffer@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.2" + checksum: 10/c10b155a4e93999d3a215d08c23eea95f865e1f510b2e7748fcae1882b776df1afe8c99f483ace7fc0e5a3193ab08da138abebc9829d12003746c5a338c4d644 + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.2": + version: 1.0.2 + resolution: "data-view-byte-length@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.2" + checksum: 10/2a47055fcf1ab3ec41b00b6f738c6461a841391a643c9ed9befec1117c1765b4d492661d97fb7cc899200c328949dca6ff189d2c6537d96d60e8a02dfe3c95f7 + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-offset@npm:1.0.1" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-data-view: "npm:^1.0.1" + checksum: 10/fa3bdfa0968bea6711ee50375094b39f561bce3f15f9e558df59de9c25f0bdd4cddc002d9c1d70ac7772ebd36854a7e22d1761e7302a934e6f1c2263bcf44aa2 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.3.4": version: 4.4.0 resolution: "debug@npm:4.4.0" @@ -1664,6 +2630,27 @@ __metadata: languageName: node linkType: hard +"debug@npm:^3.2.7": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10/d86fd7be2b85462297ea16f1934dc219335e802f629ca9a69b63ed8ed041dda492389bb2ee039217c02e5b54792b1c51aa96ae954cf28634d363a2360c7a1639 + languageName: node + linkType: hard + +"debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.4.1, debug@npm:^4.4.3": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10/9ada3434ea2993800bd9a1e320bd4aa7af69659fb51cca685d390949434bc0a8873c21ed7c9b852af6f2455a55c6d050aa3937d52b3c69f796dab666f762acad + languageName: node + linkType: hard + "debug@npm:^4.4.0": version: 4.4.1 resolution: "debug@npm:4.4.1" @@ -1676,6 +2663,35 @@ __metadata: languageName: node linkType: hard +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10/ec12d074aef5ae5e81fa470b9317c313142c9e8e2afe3f8efa124db309720db96d1d222b82b84c834e5f87e7a614b44a4684b6683583118b87c833b3be40d4d8 + languageName: node + linkType: hard + +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10/abdcb2505d80a53524ba871273e5da75e77e52af9e15b3aa65d8aad82b8a3a424dad7aee2cc0b71470ac7acf501e08defac362e8b6a73cdb4309f028061df4ae + languageName: node + linkType: hard + +"define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10/b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + "defu@npm:^6.1.6": version: 6.1.7 resolution: "defu@npm:6.1.7" @@ -1711,6 +2727,15 @@ __metadata: languageName: node linkType: hard +"doctrine@npm:^2.1.0": + version: 2.1.0 + resolution: "doctrine@npm:2.1.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10/555684f77e791b17173ea86e2eea45ef26c22219cb64670669c4f4bebd26dbc95cd90ec1f4159e9349a6bb9eb892ce4dde8cd0139e77bedd8bf4518238618474 + languageName: node + linkType: hard + "dotenv-expand@npm:^10.0.0": version: 10.0.0 resolution: "dotenv-expand@npm:10.0.0" @@ -1732,7 +2757,7 @@ __metadata: languageName: node linkType: hard -"dunder-proto@npm:^1.0.1": +"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" dependencies: @@ -1822,7 +2847,81 @@ __metadata: languageName: node linkType: hard -"es-define-property@npm:^1.0.1": +"es-abstract-get@npm:^1.0.0": + version: 1.0.0 + resolution: "es-abstract-get@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.2" + is-callable: "npm:^1.2.7" + object-inspect: "npm:^1.13.4" + checksum: 10/a2bfa7536529a21c8590670a69c0c4583e531f92dbc420c13f680bf906215f510d9d14b18e2e4a26e8b07100ab28719811dbce822e43fe87305a5a9069cda24e + languageName: node + linkType: hard + +"es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.2": + version: 1.24.2 + resolution: "es-abstract@npm:1.24.2" + dependencies: + array-buffer-byte-length: "npm:^1.0.2" + arraybuffer.prototype.slice: "npm:^1.0.4" + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + data-view-buffer: "npm:^1.0.2" + data-view-byte-length: "npm:^1.0.2" + data-view-byte-offset: "npm:^1.0.1" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + es-set-tostringtag: "npm:^2.1.0" + es-to-primitive: "npm:^1.3.0" + function.prototype.name: "npm:^1.1.8" + get-intrinsic: "npm:^1.3.0" + get-proto: "npm:^1.0.1" + get-symbol-description: "npm:^1.1.0" + globalthis: "npm:^1.0.4" + gopd: "npm:^1.2.0" + has-property-descriptors: "npm:^1.0.2" + has-proto: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + internal-slot: "npm:^1.1.0" + is-array-buffer: "npm:^3.0.5" + is-callable: "npm:^1.2.7" + is-data-view: "npm:^1.0.2" + is-negative-zero: "npm:^2.0.3" + is-regex: "npm:^1.2.1" + is-set: "npm:^2.0.3" + is-shared-array-buffer: "npm:^1.0.4" + is-string: "npm:^1.1.1" + is-typed-array: "npm:^1.1.15" + is-weakref: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + object-inspect: "npm:^1.13.4" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.7" + own-keys: "npm:^1.0.1" + regexp.prototype.flags: "npm:^1.5.4" + safe-array-concat: "npm:^1.1.3" + safe-push-apply: "npm:^1.0.0" + safe-regex-test: "npm:^1.1.0" + set-proto: "npm:^1.0.0" + stop-iteration-iterator: "npm:^1.1.0" + string.prototype.trim: "npm:^1.2.10" + string.prototype.trimend: "npm:^1.0.9" + string.prototype.trimstart: "npm:^1.0.8" + typed-array-buffer: "npm:^1.0.3" + typed-array-byte-length: "npm:^1.0.3" + typed-array-byte-offset: "npm:^1.0.4" + typed-array-length: "npm:^1.0.7" + unbox-primitive: "npm:^1.1.0" + which-typed-array: "npm:^1.1.19" + checksum: 10/e2c97263d87b7faf65102d887074af421db7e48cd92b8b3cd308216cdd2547b647e8f61bf51429bdb13adc463bb7f421989544cbfd2e7f7469ef7a69ae8a4205 + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": version: 1.0.1 resolution: "es-define-property@npm:1.0.1" checksum: 10/f8dc9e660d90919f11084db0a893128f3592b781ce967e4fccfb8f3106cb83e400a4032c559184ec52ee1dbd4b01e7776c7cd0b3327b1961b1a4a7008920fe78 @@ -1845,6 +2944,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.1.2": + version: 1.1.2 + resolution: "es-object-atoms@npm:1.1.2" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10/70041de72ab8996df74c17775cdedb8a0c36eb09a4111921d974f7d018af963023bb035a328b5772c2851daa40fb49f52313be0418763a975cb42cb6fe723255 + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.1.0": version: 2.1.0 resolution: "es-set-tostringtag@npm:2.1.0" @@ -1857,6 +2965,29 @@ __metadata: languageName: node linkType: hard +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": + version: 1.1.0 + resolution: "es-shim-unscopables@npm:1.1.0" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10/c351f586c30bbabc62355be49564b2435468b52c3532b8a1663672e3d10dc300197e69c247869dd173e56d86423ab95fc0c10b0939cdae597094e0fdca078cba + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.3.0": + version: 1.3.4 + resolution: "es-to-primitive@npm:1.3.4" + dependencies: + es-abstract-get: "npm:^1.0.0" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + is-callable: "npm:^1.2.7" + is-date-object: "npm:^1.1.0" + is-symbol: "npm:^1.1.1" + checksum: 10/7a68d778c06de7de960682c57f4103259ca3cb6dc720b8908a027b04bf1216ae4c1688a8999443f871f03efaf8ec7c24b28f33892e2a553c2a4e3bc6bd0e276a + languageName: node + linkType: hard + "es-toolkit@npm:1.44.0": version: 1.44.0 resolution: "es-toolkit@npm:1.44.0" @@ -1876,6 +3007,260 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"eslint-config-prettier@npm:10.1.8": + version: 10.1.8 + resolution: "eslint-config-prettier@npm:10.1.8" + peerDependencies: + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 10/03f8e6ea1a6a9b8f9eeaf7c8c52a96499ec4b275b9ded33331a6cc738ed1d56de734097dbd0091f136f0e84bc197388bd8ec22a52a4658105883f8c8b7d8921a + languageName: node + linkType: hard + +"eslint-import-context@npm:^0.1.8": + version: 0.1.9 + resolution: "eslint-import-context@npm:0.1.9" + dependencies: + get-tsconfig: "npm:^4.10.1" + stable-hash-x: "npm:^0.2.0" + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + checksum: 10/f0778126bb3aae57c8c68946c71c4418927e9d39f72099b799d9c47a3b5712d6c9166b63ee8be58a020961dcc9216df09c856b825336af375ccbbdeedfc82a99 + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.10 + resolution: "eslint-import-resolver-node@npm:0.3.10" + dependencies: + debug: "npm:^3.2.7" + is-core-module: "npm:^2.16.1" + resolve: "npm:^2.0.0-next.6" + checksum: 10/f0ad564d345fc53076b46f726b6f9ba96a40d1b7cb33d515ea89d41d1dba37db4ff9b864550608756c2ba061c9e243bf10b920d975848616d0c6c4474f4ea415 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:4.4.5": + version: 4.4.5 + resolution: "eslint-import-resolver-typescript@npm:4.4.5" + dependencies: + debug: "npm:^4.4.1" + eslint-import-context: "npm:^0.1.8" + get-tsconfig: "npm:^4.10.1" + is-bun-module: "npm:^2.0.0" + stable-hash-x: "npm:^0.2.0" + tinyglobby: "npm:^0.2.14" + unrs-resolver: "npm:^1.7.11" + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + eslint-plugin-import-x: "*" + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + checksum: 10/f889b885abbe8b3517286de7f30289cf9318357b124ef2b92948c77d662901dd6b8fba0dffebedf64fb68a2bee0a416b5ccbf1f67f6502736964f972a72cef8e + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.12.1": + version: 2.14.0 + resolution: "eslint-module-utils@npm:2.14.0" + dependencies: + debug: "npm:^3.2.7" + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/78e508bc522717e756bcd1d84956ce43a5326cbb454c69b8fc1b4006c70b3d8bf93de61b389c32d76cf1e2fe1dcf035261445ed5b3f22b14338c73685de11c80 + languageName: node + linkType: hard + +"eslint-plugin-import@npm:2.32.0": + version: 2.32.0 + resolution: "eslint-plugin-import@npm:2.32.0" + dependencies: + "@rtsao/scc": "npm:^1.1.0" + array-includes: "npm:^3.1.9" + array.prototype.findlastindex: "npm:^1.2.6" + array.prototype.flat: "npm:^1.3.3" + array.prototype.flatmap: "npm:^1.3.3" + debug: "npm:^3.2.7" + doctrine: "npm:^2.1.0" + eslint-import-resolver-node: "npm:^0.3.9" + eslint-module-utils: "npm:^2.12.1" + hasown: "npm:^2.0.2" + is-core-module: "npm:^2.16.1" + is-glob: "npm:^4.0.3" + minimatch: "npm:^3.1.2" + object.fromentries: "npm:^2.0.8" + object.groupby: "npm:^1.0.3" + object.values: "npm:^1.2.1" + semver: "npm:^6.3.1" + string.prototype.trimend: "npm:^1.0.9" + tsconfig-paths: "npm:^3.15.0" + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + checksum: 10/1bacf4967e9ebf99e12176a795f0d6d3a87d1c9a030c2207f27b267e10d96a1220be2647504c7fc13ab543cdf13ffef4b8f5620e0447032dba4ff0d3922f7c9e + languageName: node + linkType: hard + +"eslint-plugin-playwright@npm:2.12.1": + version: 2.12.1 + resolution: "eslint-plugin-playwright@npm:2.12.1" + dependencies: + globals: "npm:^17.3.0" + peerDependencies: + eslint: ">=8.40.0" + checksum: 10/46e5b410cca0b7f8a55038b1a5f72b65fc83bc27de41e4349fb76213718a53dcc8defa57685874580d9e03ac37a315000e57ded75341fe0ce34e254391f8c2df + languageName: node + linkType: hard + +"eslint-plugin-prettier@npm:5.5.6": + version: 5.5.6 + resolution: "eslint-plugin-prettier@npm:5.5.6" + dependencies: + prettier-linter-helpers: "npm:^1.0.1" + synckit: "npm:^0.11.13" + peerDependencies: + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0" + prettier: ">=3.0.0" + peerDependenciesMeta: + "@types/eslint": + optional: true + eslint-config-prettier: + optional: true + checksum: 10/18a0189e084dd5f1e4e3944a8ff89f20d69c14f100965033a94edd8de16fb7abdcbf226fbc40f27b7ac6cfdb779065272dd8a9e6ca34ed86a59d895e630bd48b + languageName: node + linkType: hard + +"eslint-scope@npm:^9.1.2": + version: 9.1.2 + resolution: "eslint-scope@npm:9.1.2" + dependencies: + "@types/esrecurse": "npm:^4.3.1" + "@types/estree": "npm:^1.0.8" + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10/d102a22525020be99a6897c0d5570b16a387b251e661ba70cedb4f983536d5acd45b9ea2ee05b63ab04f6c35e4f2ed00a113d1c6fb5f61ff879d92e46d0c2f15 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^5.0.0, eslint-visitor-keys@npm:^5.0.1": + version: 5.0.1 + resolution: "eslint-visitor-keys@npm:5.0.1" + checksum: 10/f9cc1a57b75e0ef949545cac33d01e8367e302de4c1483266ed4d8646ee5c306376660196bbb38b004e767b7043d1e661cb4336b49eff634a1bbe75c1db709ec + languageName: node + linkType: hard + +"eslint@npm:10.12.0": + version: 10.12.0 + resolution: "eslint@npm:10.12.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.8.0" + "@eslint-community/regexpp": "npm:^4.12.2" + "@eslint/config-array": "npm:^0.23.5" + "@eslint/config-helpers": "npm:^0.7.0" + "@eslint/core": "npm:^1.2.1" + "@eslint/plugin-kit": "npm:^0.7.3" + "@humanfs/node": "npm:^0.16.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.4.2" + "@types/estree": "npm:^1.0.6" + ajv: "npm:^6.14.0" + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.3.2" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^9.1.2" + eslint-visitor-keys: "npm:^5.0.1" + espree: "npm:^11.2.0" + esquery: "npm:^1.7.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:11.1.5 || >11.1.6 <12" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + minimatch: "npm:^10.2.5" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 10/1cff87e4db79d4c9b6bd0af4c2aa483d88936a16f70e73af192a2aeee5ec597ad1de5d42ba1242336c27b25be6f0e503e4ea41ca036ab134eb5f4b4c24af15b9 + languageName: node + linkType: hard + +"espree@npm:^11.2.0": + version: 11.2.0 + resolution: "espree@npm:11.2.0" + dependencies: + acorn: "npm:^8.16.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^5.0.1" + checksum: 10/5cc4233b8f150010c70713669ef8231f07fe9b6391870cfa0a292a07f723ed5c2922064b978e627f7cabf7753280e64c5bde41d3840caaa40946989df7009a51 + languageName: node + linkType: hard + +"esquery@npm:^1.7.0": + version: 1.7.0 + resolution: "esquery@npm:1.7.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10/4afaf3089367e1f5885caa116ef386dffd8bfd64da21fd3d0e56e938d2667cfb2e5400ab4a825aa70e799bb3741e5b5d63c0b94d86e2d4cf3095c9e64b2f5a15 + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10/44ffcd89e714ea6b30143e7f119b104fc4d75e77ee913f34d59076b40ef2d21967f84e019f84e1fd0465b42cdbf725db449f232b5e47f29df29ed76194db8e16 + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10/b23acd24791db11d8f65be5ea58fd9a6ce2df5120ae2da65c16cfc5331ff59d5ac4ef50af66cd4bde238881503ec839928a0135b99a036a9cdfa22d17fd56cdb + languageName: node + linkType: hard + "ethers@npm:^5.8.0": version: 5.8.0 resolution: "ethers@npm:5.8.0" @@ -1948,13 +3333,34 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.1.3": +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" checksum: 10/e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d languageName: node linkType: hard +"fast-diff@npm:^1.1.2": + version: 1.3.0 + resolution: "fast-diff@npm:1.3.0" + checksum: 10/9e57415bc69cd6efcc720b3b8fe9fdaf42dcfc06f86f0f45378b1fa512598a8aac48aa3928c8751d58e2f01bb4ba4f07e4f3d9bc0d57586d45f1bd1e872c6cde + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:^2.0.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10/eb7e220ecf2bab5159d157350b81d01f75726a4382f5a9266f42b9150c4523b9795f7f5d9fbbbeaeac09a441b2369f05ee02db48ea938584205530fe5693cfe1 + languageName: node + linkType: hard + "fast-uri@npm:^3.0.1": version: 3.1.7 resolution: "fast-uri@npm:3.1.7" @@ -1962,6 +3368,18 @@ __metadata: languageName: node linkType: hard +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10/14ca1c9f0a0e8f4f2e9bf4e8551065a164a09545dae548c12a18d238b72e51e5a7b39bd8e5494b56463a0877672d0a6c1ef62c6fa0677db1b0c847773be939b1 + languageName: node + linkType: hard + "fflate@npm:^0.8.2": version: 0.8.3 resolution: "fflate@npm:0.8.3" @@ -1969,6 +3387,15 @@ __metadata: languageName: node linkType: hard +"file-entry-cache@npm:11.1.5 || >11.1.6 <12": + version: 11.1.5 + resolution: "file-entry-cache@npm:11.1.5" + dependencies: + flat-cache: "npm:^6.1.23" + checksum: 10/a4a6c45c9561fbceb6511b3483e299e636e5c67e225ea4445c8cbdbe6c571da8505b29b29fc4c62fe9cf28ffe33314f401fad3da09e4b62321c92f0d3a113135 + languageName: node + linkType: hard + "file-type@npm:20.4.1": version: 20.4.1 resolution: "file-type@npm:20.4.1" @@ -1981,12 +3408,40 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^7.1.1": - version: 7.1.1 - resolution: "fill-range@npm:7.1.1" - dependencies: - to-regex-range: "npm:^5.0.1" - checksum: 10/a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10/a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10/07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + languageName: node + linkType: hard + +"flat-cache@npm:^6.1.23": + version: 6.1.23 + resolution: "flat-cache@npm:6.1.23" + dependencies: + cacheable: "npm:^2.5.0" + flatted: "npm:^3.4.2" + hookified: "npm:^1.15.0" + checksum: 10/63ad3682f399e3e7b7255493b07469f80c418034a10e12e1c7043b41d666ff69b20be924984a0b91cd767a4f71540e4fb4421651d15adc736fca1c04b8505758 + languageName: node + linkType: hard + +"flatted@npm:^3.4.2": + version: 3.4.4 + resolution: "flatted@npm:3.4.4" + checksum: 10/5a6682ab87ed15e125419c61352c4bef26f310adceece03eae5f22c119d64ed47bfc0ee1948a77d0122559eaa86395ea06ef45b59bfe3db4fb13fb4cdff876de languageName: node linkType: hard @@ -2000,6 +3455,15 @@ __metadata: languageName: node linkType: hard +"for-each@npm:^0.3.3, for-each@npm:^0.3.5": + version: 0.3.5 + resolution: "for-each@npm:0.3.5" + dependencies: + is-callable: "npm:^1.2.7" + checksum: 10/330cc2439f85c94f4609de3ee1d32c5693ae15cdd7fe3d112c4fd9efd4ce7143f2c64ef6c2c9e0cfdb0058437f33ef05b5bdae5b98fcc903fb2143fbaf0fea0f + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" @@ -2077,6 +3541,30 @@ __metadata: languageName: node linkType: hard +"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": + version: 1.2.0 + resolution: "function.prototype.name@npm:1.2.0" + dependencies: + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + functions-have-names: "npm:^1.2.3" + has-property-descriptors: "npm:^1.0.2" + hasown: "npm:^2.0.4" + is-callable: "npm:^1.2.7" + is-document.all: "npm:^1.0.0" + checksum: 10/ad662230bc2b9e971625222b462142b34aa23c70ca58fb4fa72e226bb9106a5752be5c7d8986de7ce5cfb959e5317200d70d88d96359605a165ed1c8cb515223 + languageName: node + linkType: hard + +"functions-have-names@npm:^1.2.3": + version: 1.2.3 + resolution: "functions-have-names@npm:1.2.3" + checksum: 10/0ddfd3ed1066a55984aaecebf5419fbd9344a5c38dd120ffb0739fac4496758dcf371297440528b115e4367fc46e3abc86a2cc0ff44612181b175ae967a11a05 + languageName: node + linkType: hard + "generator-function@npm:^2.0.0": version: 2.0.1 resolution: "generator-function@npm:2.0.1" @@ -2084,7 +3572,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.2.6": +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": version: 1.3.1 resolution: "get-intrinsic@npm:1.3.1" dependencies: @@ -2115,6 +3603,35 @@ __metadata: languageName: node linkType: hard +"get-symbol-description@npm:^1.1.0": + version: 1.1.0 + resolution: "get-symbol-description@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + checksum: 10/a353e3a9595a74720b40fb5bae3ba4a4f826e186e83814d93375182384265676f59e49998b9cdfac4a2225ce95a3d32a68f502a2c5619303987f1c183ab80494 + languageName: node + linkType: hard + +"get-tsconfig@npm:^4.10.1": + version: 4.14.3 + resolution: "get-tsconfig@npm:4.14.3" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10/ac18243ffd5c2e7c0cbecc11d053599c73a4c534a626988fe545b686695bf2fa789ba47bc2af87e30d85c657dbcadc26b4e3e328096894fde6a9229615c67253 + languageName: node + linkType: hard + +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: "npm:^4.0.3" + checksum: 10/c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 + languageName: node + linkType: hard + "glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": version: 10.5.0 resolution: "glob@npm:10.5.0" @@ -2145,7 +3662,24 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.2.0": +"globals@npm:17.13.0, globals@npm:^17.3.0": + version: 17.13.0 + resolution: "globals@npm:17.13.0" + checksum: 10/f723714cfb07bcf3163d44661d63b2a6076d93fd2f3724622b22084c62bcbbdb3ea3c601ec39635f1430d5cdf60bbf6fd7e458f12b5381ed422ed355c699537b + languageName: node + linkType: hard + +"globalthis@npm:^1.0.4": + version: 1.0.4 + resolution: "globalthis@npm:1.0.4" + dependencies: + define-properties: "npm:^1.2.1" + gopd: "npm:^1.0.1" + checksum: 10/1f1fd078fb2f7296306ef9dd51019491044ccf17a59ed49d375b576ca108ff37e47f3d29aead7add40763574a992f16a5367dd1e2173b8634ef18556ab719ac4 + languageName: node + linkType: hard + +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" checksum: 10/94e296d69f92dc1c0768fcfeecfb3855582ab59a7c75e969d5f96ce50c3d201fd86d5a2857c22565764d5bb8a816c7b1e58f133ec318cd56274da36c5e3fb1a1 @@ -2195,6 +3729,13 @@ __metadata: languageName: node linkType: hard +"has-bigints@npm:^1.0.2": + version: 1.1.0 + resolution: "has-bigints@npm:1.1.0" + checksum: 10/90fb1b24d40d2472bcd1c8bd9dd479037ec240215869bdbff97b2be83acef57d28f7e96bdd003a21bed218d058b49097f4acc8821c05b1629cc5d48dd7bfcccd + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -2202,6 +3743,24 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10/2d8c9ab8cebb572e3362f7d06139a4592105983d4317e68f7adba320fe6ddfc8874581e0971e899e633fd5f72e262830edce36d5a0bc863dad17ad20572484b2 + languageName: node + linkType: hard + +"has-proto@npm:^1.2.0": + version: 1.2.0 + resolution: "has-proto@npm:1.2.0" + dependencies: + dunder-proto: "npm:^1.0.0" + checksum: 10/7eaed07728eaa28b77fadccabce53f30de467ff186a766872669a833ac2e87d8922b76a22cc58339d7e0277aefe98d6d00762113b27a97cdf65adcf958970935 + languageName: node + linkType: hard + "has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" @@ -2228,6 +3787,15 @@ __metadata: languageName: node linkType: hard +"hashery@npm:^1.4.0, hashery@npm:^1.5.1": + version: 1.5.1 + resolution: "hashery@npm:1.5.1" + dependencies: + hookified: "npm:^1.15.0" + checksum: 10/34eebad3e4d4041ae5c2457f129169b7be8d067fce4717ec6b903017e82b420263808a4d89f15cc77fa21822ae36d16841dc06d945392b6833b49082d3653e82 + languageName: node + linkType: hard + "hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -2257,6 +3825,20 @@ __metadata: languageName: node linkType: hard +"hookified@npm:^1.15.0, hookified@npm:^1.15.1": + version: 1.15.1 + resolution: "hookified@npm:1.15.1" + checksum: 10/ecaee63506d9a213e8b78dfdb92346227f951d3bcd8ef60d14105c5590f61d466f130a908274e1ec87ee3b3668bd87d9250cad64547cf15cfa69932bcdbbea8f + languageName: node + linkType: hard + +"hookified@npm:^2.1.1": + version: 2.2.0 + resolution: "hookified@npm:2.2.0" + checksum: 10/36be80a9645161c9747c90a0a26f75f074470984cf221fb73cf0e2f367667e0d4680797f7b4f27b83d1f4cd4a3b5913f685c91132b5d6eeb05522674081657a8 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -2264,125 +3846,401 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0": - version: 7.0.2 - resolution: "http-proxy-agent@npm:7.0.2" +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.1": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 10/f0dce7bdcac5e8eaa0be3c7368bb8836ed010fb5b6349ffb412b172a203efe8f807d9a6681319105ea1b6901e1972c7b5ea899672a7b9aad58309f766dcbe0df + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:4" + checksum: 10/784b628cbd55b25542a9d85033bdfd03d4eda630fb8b3c9477959367f3be95dc476ed2ecbb9836c359c7c698027fc7b45723a302324433590f45d6c1706e8c13 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"idb-keyval@npm:^6.2.1": + version: 6.2.5 + resolution: "idb-keyval@npm:6.2.5" + checksum: 10/ac645882b3258ff07347d085baab91b871bac7be4f46ff8e20a7c036c2df35d3f695a30050009f27237b99045203568f2a842a35295a48f9b815959ee51a347e + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 10/d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 + languageName: node + linkType: hard + +"ignore@npm:^7.0.5": + version: 7.0.12 + resolution: "ignore@npm:7.0.12" + checksum: 10/9415f9f9ac68e361692a50922c2dc42eb4b996b8c242a781f00006e8348b9622dadc90246fb5ddc55bc579a33940e722f4ca08d02dff8349bc59646f486dd487 + languageName: node + linkType: hard + +"immediate@npm:~3.0.5": + version: 3.0.6 + resolution: "immediate@npm:3.0.6" + checksum: 10/f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10/2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.0, inherits@npm:~2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"internal-slot@npm:^1.1.0": + version: 1.1.0 + resolution: "internal-slot@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + hasown: "npm:^2.0.2" + side-channel: "npm:^1.1.0" + checksum: 10/1d5219273a3dab61b165eddf358815eefc463207db33c20fcfca54717da02e3f492003757721f972fd0bf21e4b426cab389c5427b99ceea4b8b670dc88ee6d4a + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"iron-webcrypto@npm:^1.2.1": + version: 1.2.1 + resolution: "iron-webcrypto@npm:1.2.1" + checksum: 10/c1f52ccfe2780efa5438c134538ee4b26c96a87d22f351d896781219efbce25b4fe716d1cb7f248e02da96881760541135acbcc7c0622ffedf71cb0e227bebf9 + languageName: node + linkType: hard + +"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": + version: 3.0.5 + resolution: "is-array-buffer@npm:3.0.5" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + get-intrinsic: "npm:^1.2.6" + checksum: 10/ef1095c55b963cd0dcf6f88a113e44a0aeca91e30d767c475e7d746d28d1195b10c5076b94491a7a0cd85020ca6a4923070021d74651d093dc909e9932cf689b + languageName: node + linkType: hard + +"is-async-function@npm:^2.0.0": + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" + dependencies: + async-function: "npm:^1.0.0" + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/7c2ac7efdf671e03265e74a043bcb1c0a32e226bc2a42dfc5ec8644667df668bbe14b91c08e6c1414f392f8cf86cd1d489b3af97756e2c7a49dd1ba63fd40ca6 + languageName: node + linkType: hard + +"is-bigint@npm:^1.1.0": + version: 1.1.0 + resolution: "is-bigint@npm:1.1.0" + dependencies: + has-bigints: "npm:^1.0.2" + checksum: 10/10cf327310d712fe227cfaa32d8b11814c214392b6ac18c827f157e1e85363cf9c8e2a22df526689bd5d25e53b58cc110894787afb54e138e7c504174dba15fd + languageName: node + linkType: hard + +"is-boolean-object@npm:^1.2.1": + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" + dependencies: + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/051fa95fdb99d7fbf653165a7e6b2cba5d2eb62f7ffa81e793a790f3fb5366c91c1b7b6af6820aa2937dd86c73aa3ca9d9ca98f500988457b1c59692c52ba911 + languageName: node + linkType: hard + +"is-bun-module@npm:^2.0.0": + version: 2.0.0 + resolution: "is-bun-module@npm:2.0.0" + dependencies: + semver: "npm:^7.7.1" + checksum: 10/cded5a1a58368b847872d08617975d620ad94426d76a932f3e08d55b4574d199e0a62a4fb024fa2dc444200b71719eb0bffc5d3d1e1cc82e29b293bb8d66a990 + languageName: node + linkType: hard + +"is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10/48a9297fb92c99e9df48706241a189da362bff3003354aea4048bd5f7b2eb0d823cd16d0a383cece3d76166ba16d85d9659165ac6fcce1ac12e6c649d66dbdb9 + languageName: node + linkType: hard + +"is-core-module@npm:^2.16.1, is-core-module@npm:^2.16.2": + version: 2.17.0 + resolution: "is-core-module@npm:2.17.0" + dependencies: + hasown: "npm:^2.0.4" + checksum: 10/0020f71b7eb525ccd684012cd1cfba235e7596e0addbc993732f7d8faff7ccd3a399e16dac7eb317b63459ea23f97efd661d6bf32584f6bf1d0a607fd8e21a6b + languageName: node + linkType: hard + +"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": + version: 1.0.2 + resolution: "is-data-view@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.6" + is-typed-array: "npm:^1.1.13" + checksum: 10/357e9a48fa38f369fd6c4c3b632a3ab2b8adca14997db2e4b3fe94c4cd0a709af48e0fb61b02c64a90c0dd542fd489d49c2d03157b05ae6c07f5e4dec9e730a8 + languageName: node + linkType: hard + +"is-date-object@npm:^1.1.0": + version: 1.1.0 + resolution: "is-date-object@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.2" + checksum: 10/3a811b2c3176fb31abee1d23d3dc78b6c65fd9c07d591fcb67553cab9e7f272728c3dd077d2d738b53f9a2103255b0a6e8dfc9568a7805c56a78b2563e8d1dec + languageName: node + linkType: hard + +"is-document.all@npm:^1.0.0": + version: 1.0.0 + resolution: "is-document.all@npm:1.0.0" + dependencies: + call-bound: "npm:^1.0.4" + checksum: 10/c76fa391105f180e9d34bf219ab1db325b4f883d2d82c789dbf9a628e4213c97411f038f36b7d096d85f5ddc1fda6e22e9d8d7c65b89ad1ee5d4d1e5a2a4c077 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10/df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-finalizationregistry@npm:^1.1.0": + version: 1.1.1 + resolution: "is-finalizationregistry@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + checksum: 10/0bfb145e9a1ba852ddde423b0926d2169ae5fe9e37882cde9e8f69031281a986308df4d982283e152396e88b86562ed2256cbaa5e6390fb840a4c25ab54b8a80 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-generator-function@npm:^1.0.10": + version: 1.1.2 + resolution: "is-generator-function@npm:1.1.2" dependencies: - agent-base: "npm:^7.1.0" - debug: "npm:^4.3.4" - checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + call-bound: "npm:^1.0.4" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/cc50fa01034356bdfda26983c5457103240f201f4663c0de1257802714e40d36bcff7aee21091d37bbba4be962fa5c6475ce7ddbc0abfa86d6bef466e41e50a5 languageName: node linkType: hard -"https-proxy-agent@npm:^5.0.1": - version: 5.0.1 - resolution: "https-proxy-agent@npm:5.0.1" +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" dependencies: - agent-base: "npm:6" - debug: "npm:4" - checksum: 10/f0dce7bdcac5e8eaa0be3c7368bb8836ed010fb5b6349ffb412b172a203efe8f807d9a6681319105ea1b6901e1972c7b5ea899672a7b9aad58309f766dcbe0df + is-extglob: "npm:^2.1.1" + checksum: 10/3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": - version: 7.0.6 - resolution: "https-proxy-agent@npm:7.0.6" - dependencies: - agent-base: "npm:^7.1.2" - debug: "npm:4" - checksum: 10/784b628cbd55b25542a9d85033bdfd03d4eda630fb8b3c9477959367f3be95dc476ed2ecbb9836c359c7c698027fc7b45723a302324433590f45d6c1706e8c13 +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: 10/8de7b41715b08bcb0e5edb0fb9384b80d2d5bcd10e142188f33247d19ff078abaf8e9b6f858e2302d8d05376a26a55cd23a3c9f8ab93292b02fcd2cc9e4e92bb languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": - version: 0.6.3 - resolution: "iconv-lite@npm:0.6.3" +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 + languageName: node + linkType: hard + +"is-number-object@npm:^1.1.1": + version: 1.1.1 + resolution: "is-number-object@npm:1.1.1" dependencies: - safer-buffer: "npm:>= 2.1.2 < 3.0.0" - checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/a5922fb8779ab1ea3b8a9c144522b3d0bea5d9f8f23f7a72470e61e1e4df47714e28e0154ac011998b709cce260c3c9447ad3cd24a96c2f2a0abfdb2cbdc76c8 languageName: node linkType: hard -"idb-keyval@npm:^6.2.1": - version: 6.2.5 - resolution: "idb-keyval@npm:6.2.5" - checksum: 10/ac645882b3258ff07347d085baab91b871bac7be4f46ff8e20a7c036c2df35d3f695a30050009f27237b99045203568f2a842a35295a48f9b815959ee51a347e +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10/6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 languageName: node linkType: hard -"ieee754@npm:^1.2.1": +"is-regex@npm:^1.2.1": version: 1.2.1 - resolution: "ieee754@npm:1.2.1" - checksum: 10/d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10/c42b7efc5868a5c9a4d8e6d3e9816e8815c611b09535c00fead18a1138455c5cb5e1887f0023a467ad3f9c419d62ba4dc3d9ba8bafe55053914d6d6454a945d2 languageName: node linkType: hard -"immediate@npm:~3.0.5": - version: 3.0.6 - resolution: "immediate@npm:3.0.6" - checksum: 10/f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62 +"is-retry-allowed@npm:^2.2.0": + version: 2.2.0 + resolution: "is-retry-allowed@npm:2.2.0" + checksum: 10/6d8685530871f0b040346cc72322d90122473e921149affa16de363d6c2a6e46bc76abdfaac3259b93994ec8e7f70fbe67bbb080190e440533ff728e6a64494d languageName: node linkType: hard -"imurmurhash@npm:^0.1.4": - version: 0.1.4 - resolution: "imurmurhash@npm:0.1.4" - checksum: 10/2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 10/5685df33f0a4a6098a98c72d94d67cad81b2bc72f1fb2091f3d9283c4a1c582123cd709145b02a9745f0ce6b41e3e43f1c944496d1d74d4ea43358be61308669 languageName: node linkType: hard -"inflight@npm:^1.0.4": - version: 1.0.6 - resolution: "inflight@npm:1.0.6" +"is-shared-array-buffer@npm:^1.0.4": + version: 1.0.4 + resolution: "is-shared-array-buffer@npm:1.0.4" dependencies: - once: "npm:^1.3.0" - wrappy: "npm:1" - checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + call-bound: "npm:^1.0.3" + checksum: 10/0380d7c60cc692856871526ffcd38a8133818a2ee42d47bb8008248a0cd2121d8c8b5f66b6da3cac24bc5784553cacb6faaf678f66bc88c6615b42af2825230e languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.0, inherits@npm:~2.0.3": - version: 2.0.4 - resolution: "inherits@npm:2.0.4" - checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 +"is-string@npm:^1.1.1": + version: 1.1.1 + resolution: "is-string@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/5277cb9e225a7cc8a368a72623b44a99f2cfa139659c6b203553540681ad4276bfc078420767aad0e73eef5f0bd07d4abf39a35d37ec216917879d11cebc1f8b languageName: node linkType: hard -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" +"is-symbol@npm:^1.1.1": + version: 1.1.1 + resolution: "is-symbol@npm:1.1.1" dependencies: - jsbn: "npm:1.1.0" - sprintf-js: "npm:^1.1.3" - checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + call-bound: "npm:^1.0.2" + has-symbols: "npm:^1.1.0" + safe-regex-test: "npm:^1.1.0" + checksum: 10/db495c0d8cd0a7a66b4f4ef7fccee3ab5bd954cb63396e8ac4d32efe0e9b12fdfceb851d6c501216a71f4f21e5ff20fc2ee845a3d52d455e021c466ac5eb2db2 languageName: node linkType: hard -"iron-webcrypto@npm:^1.2.1": - version: 1.2.1 - resolution: "iron-webcrypto@npm:1.2.1" - checksum: 10/c1f52ccfe2780efa5438c134538ee4b26c96a87d22f351d896781219efbce25b4fe716d1cb7f248e02da96881760541135acbcc7c0622ffedf71cb0e227bebf9 +"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" + dependencies: + which-typed-array: "npm:^1.1.16" + checksum: 10/e8cf60b9ea85667097a6ad68c209c9722cfe8c8edf04d6218366469e51944c5cc25bae45ffb845c23f811d262e4314d3b0168748eb16711aa34d12724cdf0735 languageName: node linkType: hard -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: 10/a7b7e23206c542dcf2fa0abc483142731788771527e90e7e24f658c0833a0d91948a4f7b30d78f7a65255a48512e41a0288b778ba7fc396137515c12e201fd11 languageName: node linkType: hard -"is-number@npm:^7.0.0": - version: 7.0.0 - resolution: "is-number@npm:7.0.0" - checksum: 10/6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": + version: 1.1.1 + resolution: "is-weakref@npm:1.1.1" + dependencies: + call-bound: "npm:^1.0.3" + checksum: 10/543506fd8259038b371bb083aac25b16cb4fd8b12fc58053aa3d45ac28dfd001cd5c6dffbba7aeea4213c74732d46b6cb2cfb5b412eed11f2db524f3f97d09a0 languageName: node linkType: hard -"is-retry-allowed@npm:^2.2.0": - version: 2.2.0 - resolution: "is-retry-allowed@npm:2.2.0" - checksum: 10/6d8685530871f0b040346cc72322d90122473e921149affa16de363d6c2a6e46bc76abdfaac3259b93994ec8e7f70fbe67bbb080190e440533ff728e6a64494d +"is-weakset@npm:^2.0.3": + version: 2.0.4 + resolution: "is-weakset@npm:2.0.4" + dependencies: + call-bound: "npm:^1.0.3" + get-intrinsic: "npm:^1.2.6" + checksum: 10/1d5e1d0179beeed3661125a6faa2e59bfb48afda06fc70db807f178aa0ebebc3758fb6358d76b3d528090d5ef85148c345dcfbf90839592fe293e3e5e82f2134 + languageName: node + linkType: hard + +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: 10/1d8bc7911e13bb9f105b1b3e0b396c787a9e63046af0b8fe0ab1414488ab06b2b099b87a2d8a9e31d21c9a6fad773c7fc8b257c4880f2d957274479d28ca3414 languageName: node linkType: hard @@ -2528,6 +4386,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10/7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b + languageName: node + linkType: hard + "json-schema-traverse@npm:^1.0.0": version: 1.0.0 resolution: "json-schema-traverse@npm:1.0.0" @@ -2535,6 +4400,24 @@ __metadata: languageName: node linkType: hard +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10/12786c2e2f22c27439e6db0532ba321f1d0617c27ad8cb1c352a0e9249a50182fd1ba8b52a18899291604b0c32eafa8afd09e51203f19109a0537f68db2b652d + languageName: node + linkType: hard + +"json5@npm:^1.0.2": + version: 1.0.2 + resolution: "json5@npm:1.0.2" + dependencies: + minimist: "npm:^1.2.0" + bin: + json5: lib/cli.js + checksum: 10/a78d812dbbd5642c4f637dd130954acfd231b074965871c3e28a5bbd571f099d623ecf9161f1960c4ddf68e0cc98dee8bebfdb94a71ad4551f85a1afc94b63f6 + languageName: node + linkType: hard + "jszip@npm:^3.10.1": version: 3.10.1 resolution: "jszip@npm:3.10.1" @@ -2547,6 +4430,15 @@ __metadata: languageName: node linkType: hard +"keyv@npm:^5.6.0": + version: 5.6.0 + resolution: "keyv@npm:5.6.0" + dependencies: + "@keyv/serialize": "npm:^1.1.1" + checksum: 10/f1de999fdf635d703d091981a0a3844fb20081e01d45c6743ada7d01f3a6570dc47d1882e10d0a98d31075b342db8e62b4ebe4f5bf473dcd0903064d718709c1 + languageName: node + linkType: hard + "keyvaluestorage-interface@npm:^1.0.0": version: 1.0.0 resolution: "keyvaluestorage-interface@npm:1.0.0" @@ -2554,6 +4446,16 @@ __metadata: languageName: node linkType: hard +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10/2e4720ff79f21ae08d42374b0a5c2f664c5be8b6c8f565bb4e1315c96ed3a8acaa9de788ffed82d7f2378cf36958573de07ef92336cb5255ed74d08b8318c9ee + languageName: node + linkType: hard + "lie@npm:~3.3.0": version: 3.3.0 resolution: "lie@npm:3.3.0" @@ -2570,6 +4472,15 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 10/72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + languageName: node + linkType: hard + "lodash.get@npm:^4.4.2": version: 4.4.2 resolution: "lodash.get@npm:4.4.2" @@ -2671,7 +4582,16 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.1.1": +"minimatch@npm:^10.2.2, minimatch@npm:^10.2.4, minimatch@npm:^10.2.5": + version: 10.2.6 + resolution: "minimatch@npm:10.2.6" + dependencies: + brace-expansion: "npm:^5.0.8" + checksum: 10/a5e43f7c57d6061a77da320b42aa35ffff826030cf67c83c0eee47a26ede4d66486935881492b968c609bf27a7d48cc4b9f54b2806643cd8fb792fcf9240cc1b + languageName: node + linkType: hard + +"minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.5 resolution: "minimatch@npm:3.1.5" dependencies: @@ -2689,7 +4609,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.6": +"minimist@npm:^1.2.0, minimist@npm:^1.2.6": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10/908491b6cc15a6c440ba5b22780a0ba89b9810e1aea684e253e43c4e3b8d56ec1dcdd7ea96dde119c29df59c936cde16062159eae4225c691e19c70b432b6e6f @@ -2793,7 +4713,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:^2.1.3": +"ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10/aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d @@ -2807,6 +4727,22 @@ __metadata: languageName: node linkType: hard +"napi-postinstall@npm:^0.3.4": + version: 0.3.4 + resolution: "napi-postinstall@npm:0.3.4" + bin: + napi-postinstall: lib/cli.js + checksum: 10/5541381508f9e1051ff3518701c7130ebac779abb3a1ffe9391fcc3cab4cc0569b0ba0952357db3f6b12909c3bb508359a7a60261ffd795feebbdab967175832 + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10/23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d + languageName: node + linkType: hard + "negotiator@npm:^1.0.0": version: 1.0.0 resolution: "negotiator@npm:1.0.0" @@ -2814,6 +4750,18 @@ __metadata: languageName: node linkType: hard +"node-exports-info@npm:^1.6.0": + version: 1.6.2 + resolution: "node-exports-info@npm:1.6.2" + dependencies: + array.prototype.flatmap: "npm:^1.3.3" + es-errors: "npm:^1.3.0" + object.entries: "npm:^1.1.9" + semver: "npm:^6.3.1" + checksum: 10/6c9593094b3dd9b8a338f31490c0bad6da886a964b1bc6d95416dfe83810d4ab3493e53290b951d131a3148bf529f33bd908302aa4fd57c45c7b3d55e2cff848 + languageName: node + linkType: hard + "node-fetch-native@npm:^1.6.7": version: 1.6.7 resolution: "node-fetch-native@npm:1.6.7" @@ -2880,6 +4828,81 @@ __metadata: languageName: node linkType: hard +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10/3d81d02674115973df0b7117628ea4110d56042e5326413e4b4313f0bcdf7dd78d4a3acef2c831463fa3796a66762c49daef306f4a0ea1af44877d7086d73bde + languageName: node + linkType: hard + +"object.assign@npm:^4.1.7": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + object-keys: "npm:^1.1.1" + checksum: 10/3fe28cdd779f2a728a9a66bd688679ba231a2b16646cd1e46b528fe7c947494387dda4bc189eff3417f3717ef4f0a8f2439347cf9a9aa3cef722fbfd9f615587 + languageName: node + linkType: hard + +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.1.1" + checksum: 10/24163ab1e1e013796693fc5f5d349e8b3ac0b6a34a7edb6c17d3dd45c6a8854145780c57d302a82512c1582f63720f4b4779d6c1cfba12cbb1420b978802d8a3 + languageName: node + linkType: hard + +"object.fromentries@npm:^2.0.8": + version: 2.0.8 + resolution: "object.fromentries@npm:2.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + es-object-atoms: "npm:^1.0.0" + checksum: 10/5b2e80f7af1778b885e3d06aeb335dcc86965e39464671adb7167ab06ac3b0f5dd2e637a90d8ebd7426d69c6f135a4753ba3dd7d0fe2a7030cf718dcb910fd92 + languageName: node + linkType: hard + +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.2" + checksum: 10/44cb86dd2c660434be65f7585c54b62f0425b0c96b5c948d2756be253ef06737da7e68d7106e35506ce4a44d16aa85a413d11c5034eb7ce5579ec28752eb42d0 + languageName: node + linkType: hard + +"object.values@npm:^1.2.1": + version: 1.2.1 + resolution: "object.values@npm:1.2.1" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/f5ec9eccdefeaaa834b089c525663436812a65ff13de7964a1c3a9110f32054f2d58aa476a645bb14f75a79f3fe1154fb3e7bfdae7ac1e80affe171b2ef74bce + languageName: node + linkType: hard + "ofetch@npm:^1.5.1": version: 1.5.1 resolution: "ofetch@npm:1.5.1" @@ -2907,6 +4930,32 @@ __metadata: languageName: node linkType: hard +"optionator@npm:^0.9.3": + version: 0.9.4 + resolution: "optionator@npm:0.9.4" + dependencies: + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + word-wrap: "npm:^1.2.5" + checksum: 10/a8398559c60aef88d7f353a4f98dcdff6090a4e70f874c827302bf1213d9106a1c4d5fcb68dacb1feb3c30a04c4102f41047aa55d4c576b863d6fc876e001af6 + languageName: node + linkType: hard + +"own-keys@npm:^1.0.1": + version: 1.0.2 + resolution: "own-keys@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.4" + get-intrinsic: "npm:^1.3.0" + object-keys: "npm:^1.1.1" + safe-push-apply: "npm:^1.0.0" + checksum: 10/95add82ab823dfa5178c82d725b939eb1436b6a56ed2729dba31c7e2e03792d8e9ef504293959e9fda6f417d7133cb0ccdb96990c12f6d1e35b02dcbca408ac3 + languageName: node + linkType: hard + "ox@npm:0.6.9": version: 0.6.9 resolution: "ox@npm:0.6.9" @@ -2969,6 +5018,24 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10/7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 10/1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + languageName: node + linkType: hard + "p-map@npm:^7.0.2": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -2990,6 +5057,13 @@ __metadata: languageName: node linkType: hard +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10/505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 + languageName: node + linkType: hard + "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -3004,6 +5078,13 @@ __metadata: languageName: node linkType: hard +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10/49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + languageName: node + linkType: hard + "path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" @@ -3028,6 +5109,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.4": + version: 4.0.7 + resolution: "picomatch@npm:4.0.7" + checksum: 10/66e1df34bc39c72fa3756be4069f7887ea3e35e94bba1c3f6167763007698cb04b8a0a365161d186fda6e9571a2d3efb606b2966eb6a7dea6252911224dc2f48 + languageName: node + linkType: hard + "pino-abstract-transport@npm:^2.0.0": version: 2.0.0 resolution: "pino-abstract-transport@npm:2.0.0" @@ -3102,6 +5190,38 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0, possible-typed-array-names@npm:^1.1.0": + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: 10/2f44137b8d3dd35f4a7ba7469eec1cd9cfbb46ec164b93a5bc1f4c3d68599c9910ee3b91da1d28b4560e9cc8414c3cd56fedc07259c67e52cc774476270d3302 + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10/0b9d2c76801ca652a7f64892dd37b7e3fab149a37d2424920099bf894acccc62abb4424af2155ab36dea8744843060a2d8ddc983518d0b1e22265a22324b72ed + languageName: node + linkType: hard + +"prettier-linter-helpers@npm:^1.0.1": + version: 1.0.1 + resolution: "prettier-linter-helpers@npm:1.0.1" + dependencies: + fast-diff: "npm:^1.1.2" + checksum: 10/2dc35f5036a35f4c4f5e645887edda1436acb63687a7f12b2383e0a6f3c1f76b8a0a4709fe4d82e19157210feb5984b159bb714d43290022911ab53d606474ec + languageName: node + linkType: hard + +"prettier@npm:3.9.6": + version: 3.9.6 + resolution: "prettier@npm:3.9.6" + bin: + prettier: bin/prettier.cjs + checksum: 10/1dd1a1e0e40ec3b91cda9d294c4a95022aef61880ca3f441aad99b1252279f58a766c4cece81132c01550dcff1fd445efbd8812ea4a2374313e7fc6c8136f11f + languageName: node + linkType: hard + "pretty-format@npm:^28.1.3": version: 28.1.3 resolution: "pretty-format@npm:28.1.3" @@ -3152,6 +5272,13 @@ __metadata: languageName: node linkType: hard +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + languageName: node + linkType: hard + "qase-api-client@npm:~1.1.9": version: 1.1.10 resolution: "qase-api-client@npm:1.1.10" @@ -3193,6 +5320,15 @@ __metadata: languageName: node linkType: hard +"qified@npm:^0.10.1": + version: 0.10.1 + resolution: "qified@npm:0.10.1" + dependencies: + hookified: "npm:^2.1.1" + checksum: 10/65eda075defad24a3c53a0bcb0056fdaffb8355ca5dbe33bffaf3143e767dd1f0ddb403a4d9402e3bd0bc54b8efdec934055fb13eb5b6e7070835a80bf517f79 + languageName: node + linkType: hard + "quick-format-unescaped@npm:^4.0.3": version: 4.0.4 resolution: "quick-format-unescaped@npm:4.0.4" @@ -3247,14 +5383,26 @@ __metadata: version: 0.0.0-use.local resolution: "reef-knot_playwright_test@workspace:." dependencies: + "@eslint/js": "npm:10.0.1" "@lidofinance/browser-service": "npm:1.11.2" "@lidofinance/lido-ethereum-sdk": "npm:4.5.1" "@lidofinance/secret-guard-reporter": "npm:1.1.0" "@lidofinance/wallets-testing-extensions": "npm:1.3.1" "@lidofinance/wallets-testing-wallets": "npm:1.49.2" "@playwright/test": "npm:^1.57.0" + "@typescript/native": "npm:typescript@7.0.2" dotenv: "npm:^16.6.1" + eslint: "npm:10.12.0" + eslint-config-prettier: "npm:10.1.8" + eslint-import-resolver-typescript: "npm:4.4.5" + eslint-plugin-import: "npm:2.32.0" + eslint-plugin-playwright: "npm:2.12.1" + eslint-plugin-prettier: "npm:5.5.6" + globals: "npm:17.13.0" playwright-qase-reporter: "npm:2.5.0" + prettier: "npm:3.9.6" + typescript: "npm:@typescript/typescript6@6.0.2" + typescript-eslint: "npm:8.71.1" viem: "npm:^2.26.0" zod: "npm:^3.24.1" languageName: unknown @@ -3267,6 +5415,36 @@ __metadata: languageName: node linkType: hard +"reflect.getprototypeof@npm:^1.0.10": + version: 1.0.10 + resolution: "reflect.getprototypeof@npm:1.0.10" + dependencies: + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.23.9" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.7" + get-proto: "npm:^1.0.1" + which-builtin-type: "npm:^1.2.1" + checksum: 10/80a4e2be716f4fe46a89a08ccad0863b47e8ce0f49616cab2d65dab0fbd53c6fdba0f52935fd41d37a2e4e22355c272004f920d63070de849f66eea7aeb4a081 + languageName: node + linkType: hard + +"regexp.prototype.flags@npm:^1.5.4": + version: 1.5.4 + resolution: "regexp.prototype.flags@npm:1.5.4" + dependencies: + call-bind: "npm:^1.0.8" + define-properties: "npm:^1.2.1" + es-errors: "npm:^1.3.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + set-function-name: "npm:^2.0.2" + checksum: 10/8ab897ca445968e0b96f6237641510f3243e59c180ee2ee8d83889c52ff735dd1bf3657fcd36db053e35e1d823dd53f2565d0b8021ea282c9fe62401c6c3bd6d + languageName: node + linkType: hard + "require-from-string@npm:^2.0.2": version: 2.0.2 resolution: "require-from-string@npm:2.0.2" @@ -3274,6 +5452,45 @@ __metadata: languageName: node linkType: hard +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e + languageName: node + linkType: hard + +"resolve@npm:^2.0.0-next.6": + version: 2.0.0-next.7 + resolution: "resolve@npm:2.0.0-next.7" + dependencies: + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.2" + node-exports-info: "npm:^1.6.0" + object-keys: "npm:^1.1.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/0a6fbd452518c128355a72e3773e65d047128bbc5045d954eca7f911683abfb1b0177494ff8734ca74f2a7a4e3a6bfad9cd6d19a2bde0fe9851025a2734d4a0f + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^2.0.0-next.6#optional!builtin": + version: 2.0.0-next.7 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.7#optional!builtin::version=2.0.0-next.7&hash=9bd1a5" + dependencies: + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.2" + node-exports-info: "npm:^1.6.0" + object-keys: "npm:^1.1.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/b0bb50f5b12e0fb87baf9692d67a4bbcbfb58cb584d9c68973b12f7b351d9c61e64828a9e08073378b61b26fc3199b0a42d88056fcbe76963320e977642cf1b2 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -3312,6 +5529,19 @@ __metadata: languageName: node linkType: hard +"safe-array-concat@npm:^1.1.3": + version: 1.1.4 + resolution: "safe-array-concat@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + get-intrinsic: "npm:^1.3.0" + has-symbols: "npm:^1.1.0" + isarray: "npm:^2.0.5" + checksum: 10/89e6a4d2759225515e5ea6b9f21a62dfad74c3aef45c769c9bf000b1c681f15568183e62935711ec9d10c35712c4f21f0d6acb094bd35138608b4a57fa64667d + languageName: node + linkType: hard + "safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -3319,6 +5549,27 @@ __metadata: languageName: node linkType: hard +"safe-push-apply@npm:^1.0.0": + version: 1.0.0 + resolution: "safe-push-apply@npm:1.0.0" + dependencies: + es-errors: "npm:^1.3.0" + isarray: "npm:^2.0.5" + checksum: 10/2bd4e53b6694f7134b9cf93631480e7fafc8637165f0ee91d5a4af5e7f33d37de9562d1af5021178dd4217d0230cde8d6530fa28cfa1ebff9a431bf8fff124b4 + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.2.1" + checksum: 10/ebdb61f305bf4756a5b023ad86067df5a11b26898573afe9e52a548a63c3bd594825d9b0e2dde2eb3c94e57e0e04ac9929d4107c394f7b8e56a4613bed46c69a + languageName: node + linkType: hard + "safe-stable-stringify@npm:^2.3.1": version: 2.5.0 resolution: "safe-stable-stringify@npm:2.5.0" @@ -3340,6 +5591,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10/1ef3a85bd02a760c6ef76a45b8c1ce18226de40831e02a00bad78485390b98b6ccaa31046245fc63bba4a47a6a592b6c7eedc65cc47126e60489f9cc1ce3ed7e + languageName: node + linkType: hard + "semver@npm:^7.3.5": version: 7.7.1 resolution: "semver@npm:7.7.1" @@ -3349,6 +5609,52 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.7.1, semver@npm:^7.7.3": + version: 7.8.5 + resolution: "semver@npm:7.8.5" + bin: + semver: bin/semver.js + checksum: 10/9b01d2ff11e6e4a4539b7ca3c5f280c8704cb397a28504469f2ed4f00ad2194748d756647362a9712fff30984d15772ab7f083108c2fb508e2096ae9e708f22c + languageName: node + linkType: hard + +"set-function-length@npm:^1.2.2": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/505d62b8e088468917ca4e3f8f39d0e29f9a563b97dbebf92f4bd2c3172ccfb3c5b8e4566d5fcd00784a00433900e7cb8fbc404e2dbd8c3818ba05bb9d4a8a6d + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.2": + version: 2.0.2 + resolution: "set-function-name@npm:2.0.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + functions-have-names: "npm:^1.2.3" + has-property-descriptors: "npm:^1.0.2" + checksum: 10/c7614154a53ebf8c0428a6c40a3b0b47dac30587c1a19703d1b75f003803f73cdfa6a93474a9ba678fa565ef5fbddc2fae79bca03b7d22ab5fd5163dbe571a74 + languageName: node + linkType: hard + +"set-proto@npm:^1.0.0": + version: 1.0.0 + resolution: "set-proto@npm:1.0.0" + dependencies: + dunder-proto: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.0.0" + checksum: 10/b87f8187bca595ddc3c0721ece4635015fd9d7cb294e6dd2e394ce5186a71bbfa4dc8a35010958c65e43ad83cde09642660e61a952883c24fd6b45ead15f045c + languageName: node + linkType: hard + "setimmediate@npm:^1.0.5, setimmediate@npm:~1.0.4": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -3372,6 +5678,54 @@ __metadata: languageName: node linkType: hard +"side-channel-list@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-list@npm:1.0.1" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.4" + checksum: 10/3499671cd52adaee739eac1e14d07530b8e3530192741aeb05e7fe4ad1b51d1368ceea2cd3c21b0f62b05410a5c70a7c4d997ba4b143303ef73d0c65dfd1c252 + languageName: node + linkType: hard + +"side-channel-map@npm:^1.0.1": + version: 1.0.1 + resolution: "side-channel-map@npm:1.0.1" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + checksum: 10/5771861f77feefe44f6195ed077a9e4f389acc188f895f570d56445e251b861754b547ea9ef73ecee4e01fdada6568bfe9020d2ec2dfc5571e9fa1bbc4a10615 + languageName: node + linkType: hard + +"side-channel-weakmap@npm:^1.0.2": + version: 1.0.2 + resolution: "side-channel-weakmap@npm:1.0.2" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.5" + object-inspect: "npm:^1.13.3" + side-channel-map: "npm:^1.0.1" + checksum: 10/a815c89bc78c5723c714ea1a77c938377ea710af20d4fb886d362b0d1f8ac73a17816a5f6640f354017d7e292a43da9c5e876c22145bac00b76cfb3468001736 + languageName: node + linkType: hard + +"side-channel@npm:^1.1.0": + version: 1.1.1 + resolution: "side-channel@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + object-inspect: "npm:^1.13.4" + side-channel-list: "npm:^1.0.1" + side-channel-map: "npm:^1.0.1" + side-channel-weakmap: "npm:^1.0.2" + checksum: 10/5fa6393ff6ad25d8b4a38e9ba095481e498c8ebe5ab78481c1455146255a3d18ca37a6f936595cc671a6149134cdc295bbd2fa017620bdc73cbc7380634fa2fc + languageName: node + linkType: hard + "signal-exit@npm:^4.0.1": version: 4.1.0 resolution: "signal-exit@npm:4.1.0" @@ -3453,6 +5807,13 @@ __metadata: languageName: node linkType: hard +"stable-hash-x@npm:^0.2.0": + version: 0.2.0 + resolution: "stable-hash-x@npm:0.2.0" + checksum: 10/136f05d0e4d441876012b423541476ff5b695c93b56d1959560be858b9e324ea6de6c16ecbd735a040ee8396427dd867bed0bf90b2cdb1fc422566747b91a0e5 + languageName: node + linkType: hard + "stack-utils@npm:^2.0.3": version: 2.0.6 resolution: "stack-utils@npm:2.0.6" @@ -3462,6 +5823,16 @@ __metadata: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.1.0": + version: 1.1.0 + resolution: "stop-iteration-iterator@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + internal-slot: "npm:^1.1.0" + checksum: 10/ff36c4db171ee76c936ccfe9541946b77017f12703d4c446652017356816862d3aa029a64e7d4c4ceb484e00ed4a81789333896390d808458638f3a216aa1f41 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -3484,6 +5855,45 @@ __metadata: languageName: node linkType: hard +"string.prototype.trim@npm:^1.2.10": + version: 1.2.11 + resolution: "string.prototype.trim@npm:1.2.11" + dependencies: + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + define-data-property: "npm:^1.1.4" + define-properties: "npm:^1.2.1" + es-abstract: "npm:^1.24.2" + es-object-atoms: "npm:^1.1.2" + has-property-descriptors: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/77c2301fe9f2f2e2085c2a9ab048f9f86b1b95609944e1f16d067186b7ac9121db2dd5bf8d165835891876d750ed325314e3181b8b6829d533f5214d472b3fc4 + languageName: node + linkType: hard + +"string.prototype.trimend@npm:^1.0.9": + version: 1.0.10 + resolution: "string.prototype.trimend@npm:1.0.10" + dependencies: + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.1.2" + checksum: 10/f8a85346be853bbe34490c03f4c3f7adb0b4d5dedb206e4a48a006839fece0843fa97fe9c3222be5fd91ba33cdc7d495970af7a4707d15a62591555bfe5a5e20 + languageName: node + linkType: hard + +"string.prototype.trimstart@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimstart@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/160167dfbd68e6f7cb9f51a16074eebfce1571656fc31d40c3738ca9e30e35496f2c046fe57b6ad49f65f238a152be8c86fd9a2dd58682b5eba39dad995b3674 + languageName: node + linkType: hard + "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -3511,6 +5921,13 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10/8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b + languageName: node + linkType: hard + "strtok3@npm:^10.2.0": version: 10.3.1 resolution: "strtok3@npm:10.3.1" @@ -3529,6 +5946,22 @@ __metadata: languageName: node linkType: hard +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10/a9dc19ae2220c952bd2231d08ddeecb1b0328b61e72071ff4000c8384e145cc07c1c0bdb3b5a1cb06e186a7b2790f1dee793418b332f6ddf320de25d9125be7e + languageName: node + linkType: hard + +"synckit@npm:^0.11.13": + version: 0.11.13 + resolution: "synckit@npm:0.11.13" + dependencies: + "@pkgr/core": "npm:^0.3.6" + checksum: 10/188544a829dbd38abd144281960835c1f8027aaa495b7c40d39ebf0c1c63a4a41c0edc42818b7ada9b5c0c15fba2f625b472220d128798fe98f9181fed84e6a2 + languageName: node + linkType: hard + "tar@npm:^7.4.3": version: 7.5.22 resolution: "tar@npm:7.5.22" @@ -3551,6 +5984,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15": + version: 0.2.17 + resolution: "tinyglobby@npm:0.2.17" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10/f85e8a217d675c3f78d5f0ad25ea4557e7e023ed13ddc2b014da10bd0312eea53a34cd52356af07ccdff777f1243012547656282a4ca70936f68bf5065fbaa71 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -3584,6 +6027,27 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^2.5.0": + version: 2.5.0 + resolution: "ts-api-utils@npm:2.5.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: 10/d5f1936f5618c6ab6942a97b78802217540ced00e7501862ae1f578d9a3aa189fc06050e64cb8951d21f7088e5fd35f53d2bf0d0370a883861c7b05e993ebc44 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": "npm:^0.0.29" + json5: "npm:^1.0.2" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10/2041beaedc6c271fc3bedd12e0da0cc553e65d030d4ff26044b771fac5752d0460944c0b5e680f670c2868c95c664a256cec960ae528888db6ded83524e33a14 + languageName: node + linkType: hard + "tslib@npm:1.14.1": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -3598,6 +6062,104 @@ __metadata: languageName: node linkType: hard +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10/14687776479d048e3c1dbfe58a2409e00367810d6960c0f619b33793271ff2a27f81b52461f14a162f1f89a9b1d8da1b237fc7c99b0e1fdcec28ec63a86b1fec + languageName: node + linkType: hard + +"typed-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-buffer@npm:1.0.3" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-typed-array: "npm:^1.1.14" + checksum: 10/3fb91f0735fb413b2bbaaca9fabe7b8fc14a3fa5a5a7546bab8a57e755be0e3788d893195ad9c2b842620592de0e68d4c077d4c2c41f04ec25b8b5bb82fa9a80 + languageName: node + linkType: hard + +"typed-array-byte-length@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-byte-length@npm:1.0.3" + dependencies: + call-bind: "npm:^1.0.8" + for-each: "npm:^0.3.3" + gopd: "npm:^1.2.0" + has-proto: "npm:^1.2.0" + is-typed-array: "npm:^1.1.14" + checksum: 10/269dad101dda73e3110117a9b84db86f0b5c07dad3a9418116fd38d580cab7fc628a4fc167e29b6d7c39da2f53374b78e7cb578b3c5ec7a556689d985d193519 + languageName: node + linkType: hard + +"typed-array-byte-offset@npm:^1.0.4": + version: 1.0.5 + resolution: "typed-array-byte-offset@npm:1.0.5" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.9" + for-each: "npm:^0.3.5" + gopd: "npm:^1.2.0" + is-typed-array: "npm:^1.1.15" + reflect.getprototypeof: "npm:^1.0.10" + checksum: 10/c7054706f6957a406c9546db88787ecd389f3e468182b1e05dd07175ca263fbf672c6f773074d38d1832a0cab20cdb2138a45f18960c828f4c9d46cac14a5696 + languageName: node + linkType: hard + +"typed-array-length@npm:^1.0.7": + version: 1.0.8 + resolution: "typed-array-length@npm:1.0.8" + dependencies: + call-bind: "npm:^1.0.9" + for-each: "npm:^0.3.5" + gopd: "npm:^1.2.0" + is-typed-array: "npm:^1.1.15" + possible-typed-array-names: "npm:^1.1.0" + reflect.getprototypeof: "npm:^1.0.10" + checksum: 10/c044c644eee13fe8814d4c2401146103efd49bfd1e40412104f04c4d67f76b373da7e93026fbd99aaef1fdaa9c81d0886f34772d045472be9704157f4e1d0164 + languageName: node + linkType: hard + +"typescript-eslint@npm:8.71.1": + version: 8.71.1 + resolution: "typescript-eslint@npm:8.71.1" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.71.1" + "@typescript-eslint/parser": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/fd965ad7b08b66f92514bb2173bb82d7388782394f61d4f8442380eb41edcd67cb0468e233335489041bc4d7becb505f06e31e457d3ab1b2f0c3126e34d28d9f + languageName: node + linkType: hard + +"typescript@npm:@typescript/typescript6@6.0.2": + version: 6.0.2 + resolution: "@typescript/typescript6@npm:6.0.2" + dependencies: + "@typescript/old": "npm:typescript@^6" + bin: + tsc6: bin/tsc6 + checksum: 10/e214aa9b2783ac924498ebbb42a4419e1d8681acc10d26daa145e938d6da0ecde46ad36690fc4e9083a4b47cf73cdc83f2c2054f32e07f10920768956c2b00a1 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A@typescript/typescript6@6.0.2#optional!builtin": + version: 6.0.2 + resolution: "typescript@patch:@typescript/typescript6@npm%3A6.0.2#optional!builtin::version=6.0.2&hash=5786d5" + dependencies: + "@typescript/old": "npm:typescript@^6" + bin: + tsc6: bin/tsc6 + checksum: 10/b190ec6b713b0fa95c059ff8019b740c17591ea83a3b60e6fe592d51d56d73c360b86abce48f616d25c39697cc5f4bb9efe8e2a231096f493758457cb175e11c + languageName: node + linkType: hard + "ufo@npm:^1.6.1, ufo@npm:^1.6.3": version: 1.6.4 resolution: "ufo@npm:1.6.4" @@ -3630,6 +6192,18 @@ __metadata: languageName: node linkType: hard +"unbox-primitive@npm:^1.1.0": + version: 1.1.0 + resolution: "unbox-primitive@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.3" + has-bigints: "npm:^1.0.2" + has-symbols: "npm:^1.1.0" + which-boxed-primitive: "npm:^1.1.1" + checksum: 10/fadb347020f66b2c8aeacf8b9a79826fa34cc5e5457af4eb0bbc4e79bd87fed0fa795949825df534320f7c13f199259516ad30abc55a6e7b91d8d996ca069e50 + languageName: node + linkType: hard + "uncrypto@npm:^0.1.3": version: 0.1.3 resolution: "uncrypto@npm:0.1.3" @@ -3662,6 +6236,82 @@ __metadata: languageName: node linkType: hard +"unrs-resolver@npm:^1.7.11": + version: 1.12.2 + resolution: "unrs-resolver@npm:1.12.2" + dependencies: + "@unrs/resolver-binding-android-arm-eabi": "npm:1.12.2" + "@unrs/resolver-binding-android-arm64": "npm:1.12.2" + "@unrs/resolver-binding-darwin-arm64": "npm:1.12.2" + "@unrs/resolver-binding-darwin-x64": "npm:1.12.2" + "@unrs/resolver-binding-freebsd-x64": "npm:1.12.2" + "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.12.2" + "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.12.2" + "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-arm64-musl": "npm:1.12.2" + "@unrs/resolver-binding-linux-loong64-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-loong64-musl": "npm:1.12.2" + "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.12.2" + "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-x64-gnu": "npm:1.12.2" + "@unrs/resolver-binding-linux-x64-musl": "npm:1.12.2" + "@unrs/resolver-binding-openharmony-arm64": "npm:1.12.2" + "@unrs/resolver-binding-wasm32-wasi": "npm:1.12.2" + "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.12.2" + "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.12.2" + "@unrs/resolver-binding-win32-x64-msvc": "npm:1.12.2" + napi-postinstall: "npm:^0.3.4" + dependenciesMeta: + "@unrs/resolver-binding-android-arm-eabi": + optional: true + "@unrs/resolver-binding-android-arm64": + optional: true + "@unrs/resolver-binding-darwin-arm64": + optional: true + "@unrs/resolver-binding-darwin-x64": + optional: true + "@unrs/resolver-binding-freebsd-x64": + optional: true + "@unrs/resolver-binding-linux-arm-gnueabihf": + optional: true + "@unrs/resolver-binding-linux-arm-musleabihf": + optional: true + "@unrs/resolver-binding-linux-arm64-gnu": + optional: true + "@unrs/resolver-binding-linux-arm64-musl": + optional: true + "@unrs/resolver-binding-linux-loong64-gnu": + optional: true + "@unrs/resolver-binding-linux-loong64-musl": + optional: true + "@unrs/resolver-binding-linux-ppc64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-musl": + optional: true + "@unrs/resolver-binding-linux-s390x-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-musl": + optional: true + "@unrs/resolver-binding-openharmony-arm64": + optional: true + "@unrs/resolver-binding-wasm32-wasi": + optional: true + "@unrs/resolver-binding-win32-arm64-msvc": + optional: true + "@unrs/resolver-binding-win32-ia32-msvc": + optional: true + "@unrs/resolver-binding-win32-x64-msvc": + optional: true + checksum: 10/ef2fc38e7a7c5e0cad9a5fb3a70abead3c8073955b444908f35a55f54ced1c08433324220810b04d9ef5adeff62982ade136793dcde8297505ca3556ee0bbb82 + languageName: node + linkType: hard + "unstorage@npm:^1.9.0": version: 1.17.5 resolution: "unstorage@npm:1.17.5" @@ -3755,6 +6405,15 @@ __metadata: languageName: node linkType: hard +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10/b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb + languageName: node + linkType: hard + "util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -3839,6 +6498,67 @@ __metadata: languageName: node linkType: hard +"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": + version: 1.1.1 + resolution: "which-boxed-primitive@npm:1.1.1" + dependencies: + is-bigint: "npm:^1.1.0" + is-boolean-object: "npm:^1.2.1" + is-number-object: "npm:^1.1.1" + is-string: "npm:^1.1.1" + is-symbol: "npm:^1.1.1" + checksum: 10/a877c0667bc089518c83ad4d845cf8296b03efe3565c1de1940c646e00a2a1ae9ed8a185bcfa27cbf352de7906f0616d83b9d2f19ca500ee02a551fb5cf40740 + languageName: node + linkType: hard + +"which-builtin-type@npm:^1.2.1": + version: 1.2.1 + resolution: "which-builtin-type@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + function.prototype.name: "npm:^1.1.6" + has-tostringtag: "npm:^1.0.2" + is-async-function: "npm:^2.0.0" + is-date-object: "npm:^1.1.0" + is-finalizationregistry: "npm:^1.1.0" + is-generator-function: "npm:^1.0.10" + is-regex: "npm:^1.2.1" + is-weakref: "npm:^1.0.2" + isarray: "npm:^2.0.5" + which-boxed-primitive: "npm:^1.1.0" + which-collection: "npm:^1.0.2" + which-typed-array: "npm:^1.1.16" + checksum: 10/22c81c5cb7a896c5171742cd30c90d992ff13fb1ea7693e6cf80af077791613fb3f89aa9b4b7f890bd47b6ce09c6322c409932359580a2a2a54057f7b52d1cbe + languageName: node + linkType: hard + +"which-collection@npm:^1.0.2": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: "npm:^2.0.3" + is-set: "npm:^2.0.3" + is-weakmap: "npm:^2.0.2" + is-weakset: "npm:^2.0.3" + checksum: 10/674bf659b9bcfe4055f08634b48a8588e879161b9fefed57e9ec4ff5601e4d50a05ccd76cf10f698ef5873784e5df3223336d56c7ce88e13bcf52ebe582fc8d7 + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": + version: 1.1.24 + resolution: "which-typed-array@npm:1.1.24" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" + for-each: "npm:^0.3.5" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + checksum: 10/5b9abdc4ff046414312eac5c5b2fedab57b08979209882049fd2f4064166f8f97edd6831ff701cb6171313da19dbbd091ed46f30712e733e9b166f5f5388159e + languageName: node + linkType: hard + "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" @@ -3861,6 +6581,13 @@ __metadata: languageName: node linkType: hard +"word-wrap@npm:^1.2.5": + version: 1.2.5 + resolution: "word-wrap@npm:1.2.5" + checksum: 10/1ec6f6089f205f83037be10d0c4b34c9183b0b63fca0834a5b3cee55dd321429d73d40bb44c8fc8471b5203d6e8f8275717f49a8ff4b2b0ab41d7e1b563e0854 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -3964,6 +6691,13 @@ __metadata: languageName: node linkType: hard +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + languageName: node + linkType: hard + "zod@npm:^3.24.1": version: 3.24.1 resolution: "zod@npm:3.24.1" diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 00000000..d303e30e --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.ui-tests.json", + "include": [ + "packages/**/*.test.ts", + "packages/**/*.test.tsx", + "packages/**/test-ui/**/*.ts", + "packages/**/test-ui/**/*.tsx", + "packages/**/*.config.ts", + "packages/ui-lido-legacy/src/connect-wallet-modal/custom.d.ts", + "turbo/generators/**/*.ts" + ], + "exclude": ["node_modules", "**/dist", "turbo/generators/wallet/templates"] +} diff --git a/tsconfig.ui-tests.json b/tsconfig.ui-tests.json new file mode 100644 index 00000000..f25b83d7 --- /dev/null +++ b/tsconfig.ui-tests.json @@ -0,0 +1,26 @@ +{ + "extends": "./packages/tsconfig/react-library.json", + "compilerOptions": { + "rootDir": ".", + "paths": { + "@lidofinance/lido-ui": ["./node_modules/@lidofinance/lido-ui/dist/types/index.d.ts"], + "reef-knot": ["./packages/reef-knot/src/index.ts"], + "vitest": ["./node_modules/vitest/dist/index.d.ts"], + "vitest/config": ["./node_modules/vitest/dist/config.d.ts"] + } + }, + "include": [ + "packages/reef-knot/src/headless/**/*.test.tsx", + "packages/reef-knot/test-ui/**/*.tsx", + "packages/ui-lido-legacy/src/__tests__/**/*.tsx", + "packages/ui-lido/src/__tests__/**/*.tsx", + "packages/reef-knot/vitest.config.ts", + "packages/ui-lido-legacy/vitest.config.ts", + "packages/ui-lido/vitest.config.ts", + "packages/reef-knot/tsdown.config.ts", + "packages/ui-lido-legacy/tsdown.config.ts", + "packages/ui-lido/tsdown.config.ts", + "packages/ui-lido-legacy/src/connect-wallet-modal/custom.d.ts" + ], + "exclude": ["node_modules", "**/dist"] +} diff --git a/turbo.json b/turbo.json index 38ab0bed..8e328bfc 100644 --- a/turbo.json +++ b/turbo.json @@ -12,17 +12,35 @@ ] }, "dev": { - "dependsOn": ["^build"], + "dependsOn": [ + "^build" + ], "cache": false }, "lint": { - "outputs": [] + "outputs": [], + "inputs": [ + "$TURBO_DEFAULT$", + "$TURBO_ROOT$/eslint.config.mjs", + "$TURBO_ROOT$/tsconfig.eslint.json", + "$TURBO_ROOT$/.prettierrc", + "$TURBO_ROOT$/tsconfig.ui-tests.json", + "$TURBO_ROOT$/packages/tsconfig/**" + ], + "dependsOn": [ + "^build" + ] }, "test": { - "outputs": [] + "outputs": [], + "dependsOn": [ + "^build" + ] }, "typecheck": { - "dependsOn": ["^build"], + "dependsOn": [ + "^build" + ], "outputs": [] } } diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts index e0db4f18..e3a047e6 100644 --- a/turbo/generators/config.ts +++ b/turbo/generators/config.ts @@ -1,4 +1,4 @@ -import { PlopTypes } from "@turbo/gen"; +import { PlopTypes } from '@turbo/gen'; import { walletGenerator } from './wallet/config'; export default function generator(plop: PlopTypes.NodePlopAPI): void { diff --git a/turbo/generators/wallet/config.ts b/turbo/generators/wallet/config.ts index 48c605d9..a820c27d 100644 --- a/turbo/generators/wallet/config.ts +++ b/turbo/generators/wallet/config.ts @@ -1,34 +1,33 @@ -import { PlopTypes } from "@turbo/gen"; +import { PlopTypes } from '@turbo/gen'; export function walletGenerator(plop: PlopTypes.NodePlopAPI): void { - plop.setGenerator("wallet", { - description: - "Generate a new Wallet Adapter", + plop.setGenerator('wallet', { + description: 'Generate a new Wallet Adapter', prompts: [ { - type: "input", - name: "walletId", - message: "Enter ID for the wallet (no spaces or hyphens, camelcase)", + type: 'input', + name: 'walletId', + message: 'Enter ID for the wallet (no spaces or hyphens, camelcase)', validate: (input: string) => { - if (input.includes(" ")) { - return "wallet id cannot include spaces"; + if (input.includes(' ')) { + return 'wallet id cannot include spaces'; } - if (input.includes("-")) { - return "wallet id cannot include hyphens"; + if (input.includes('-')) { + return 'wallet id cannot include hyphens'; } if (!input) { - return "wallet id is required"; + return 'wallet id is required'; } return true; }, }, { - type: "input", - name: "walletName", - message: "Enter name for the wallet", + type: 'input', + name: 'walletName', + message: 'Enter name for the wallet', validate: (input: string) => { if (!input) { - return "wallet name is required"; + return 'wallet name is required'; } return true; }, @@ -36,11 +35,11 @@ export function walletGenerator(plop: PlopTypes.NodePlopAPI): void { ], actions: [ { - type: "addMany", - destination: "{{ turbo.paths.root }}/packages/wallets/{{ walletId }}", - templateFiles: "wallet/templates/**/*", + type: 'addMany', + destination: '{{ turbo.paths.root }}/packages/wallets/{{ walletId }}', + templateFiles: 'wallet/templates/**/*', globOptions: { dot: true }, - base: 'wallet/templates' + base: 'wallet/templates', }, ], }); diff --git a/turbo/generators/wallet/templates/.eslintrc.json.hbs b/turbo/generators/wallet/templates/.eslintrc.json.hbs deleted file mode 100644 index 06342be5..00000000 --- a/turbo/generators/wallet/templates/.eslintrc.json.hbs +++ /dev/null @@ -1,9 +0,0 @@ -{ - "root": true, - "extends": [ - "custom" - ], - "rules": { - "import/no-extraneous-dependencies": "warn" - } -} diff --git a/turbo/generators/wallet/templates/package.json.hbs b/turbo/generators/wallet/templates/package.json.hbs index 9795bf18..ddab69d4 100644 --- a/turbo/generators/wallet/templates/package.json.hbs +++ b/turbo/generators/wallet/templates/package.json.hbs @@ -28,19 +28,17 @@ "access": "public" }, "scripts": { - "build": "yarn run -T tsdown && yarn run -T tsc --noEmit false --noEmitOnError false --emitDeclarationOnly --outDir dist || true", + "build": "yarn run -T tsdown", "dev": "yarn run -T tsdown --watch", - "lint": "eslint --ext ts,tsx,js,mjs ." + "lint": "yarn run -T eslint .", + "typecheck": "yarn run -T tsc --noEmit" }, "devDependencies": { - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*", - "build-config": "*", - "eslint-config-custom": "*" + "build-config": "*" }, "peerDependencies": { "wagmi": ">=3.6", - "@reef-knot/types": "*", "@reef-knot/wallets-helpers": "*" } } diff --git a/turbo/generators/wallet/templates/src/index.ts.hbs b/turbo/generators/wallet/templates/src/index.ts.hbs index 74a9ddb5..73d053b0 100644 --- a/turbo/generators/wallet/templates/src/index.ts.hbs +++ b/turbo/generators/wallet/templates/src/index.ts.hbs @@ -1,9 +1,9 @@ -import type { WalletAdapterType } from '@reef-knot/types'; -import { injected } from 'wagmi/connectors'; +import type { WalletAdapterType } from '@reef-knot/wallets-helpers'; import { getTargetEIP6963, isProviderExistsEIP6963, } from '@reef-knot/wallets-helpers'; +import { injected } from 'wagmi/connectors'; import { WalletIcon } from './icons/index.js'; // This generator is intended to be used for a wallet app working via EIP-6963 diff --git a/yarn.lock b/yarn.lock index 5ff4634a..3cdc1b0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,34 +62,7 @@ __metadata: languageName: node linkType: hard -"@babel/cli@npm:7.29.7": - version: 7.29.7 - resolution: "@babel/cli@npm:7.29.7" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.28" - "@nicolo-ribaudo/chokidar-2": "npm:2.1.8-no-fsevents.3" - chokidar: "npm:^3.6.0" - commander: "npm:^6.2.0" - convert-source-map: "npm:^2.0.0" - fs-readdir-recursive: "npm:^1.1.0" - glob: "npm:^7.2.0" - make-dir: "npm:^2.1.0" - slash: "npm:^2.0.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - dependenciesMeta: - "@nicolo-ribaudo/chokidar-2": - optional: true - chokidar: - optional: true - bin: - babel: ./bin/babel.js - babel-external-helpers: ./bin/babel-external-helpers.js - checksum: 10/403b9b9bb50881eceff0367949d6642ed7fb829a6e8c17a8a36dc7c5bdcecac4a4decb5dab1029624967a212f56709d513cecf2db0f8bf9e06f9370d3758a7b6 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": version: 7.29.7 resolution: "@babel/code-frame@npm:7.29.7" dependencies: @@ -114,29 +87,6 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:7.29.7, @babel/core@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/core@npm:7.29.7" - dependencies: - "@babel/code-frame": "npm:^7.29.7" - "@babel/generator": "npm:^7.29.7" - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helpers": "npm:^7.29.7" - "@babel/parser": "npm:^7.29.7" - "@babel/template": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - "@jridgewell/remapping": "npm:^2.3.5" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10/38e71cf81db790b0bb2a3a0c8140c2b1c87576b61dc6be676de4fab8c3be871af590a739e8c489fe8e8f9a8e5899fa11e35e59e9e09d40b259c6a675f2f98928 - languageName: node - linkType: hard - "@babel/core@npm:^7.19.6, @babel/core@npm:^7.21.3": version: 7.29.6 resolution: "@babel/core@npm:7.29.6" @@ -160,6 +110,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.24.4, @babel/core@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/core@npm:7.29.7" + dependencies: + "@babel/code-frame": "npm:^7.29.7" + "@babel/generator": "npm:^7.29.7" + "@babel/helper-compilation-targets": "npm:^7.29.7" + "@babel/helper-module-transforms": "npm:^7.29.7" + "@babel/helpers": "npm:^7.29.7" + "@babel/parser": "npm:^7.29.7" + "@babel/template": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/38e71cf81db790b0bb2a3a0c8140c2b1c87576b61dc6be676de4fab8c3be871af590a739e8c489fe8e8f9a8e5899fa11e35e59e9e09d40b259c6a675f2f98928 + languageName: node + linkType: hard + "@babel/generator@npm:^7.29.0, @babel/generator@npm:^7.29.6": version: 7.29.7 resolution: "@babel/generator@npm:7.29.7" @@ -186,16 +159,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.15.4, @babel/helper-annotate-as-pure@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-annotate-as-pure@npm:7.29.7" - dependencies: - "@babel/types": "npm:^7.29.7" - checksum: 10/acd9e128de634a5144b5d622357d018fa616de45f64c74e42007c048dd15d0a0be213f4d5a2bf02307bdaddf053791b87900a99d183de828c08dc3b556329009 - languageName: node - linkType: hard - -"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": +"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" dependencies: @@ -230,7 +194,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.28.6": +"@babel/helper-create-class-features-plugin@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-create-class-features-plugin@npm:7.28.6" dependencies: @@ -247,23 +211,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-create-class-features-plugin@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-member-expression-to-functions": "npm:^7.29.7" - "@babel/helper-optimise-call-expression": "npm:^7.29.7" - "@babel/helper-replace-supers": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/74f871e5389beca9fb52670f2bd83abdd6dc7b7a10f34679ffab5eabf91077dccaabf55438b9f3c897258fb81fbb80bfbf469b836a404abb7e64b4d7c141a8da - languageName: node - linkType: hard - "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1, @babel/helper-create-regexp-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" @@ -277,19 +224,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - regexpu-core: "npm:^6.3.1" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/bf79ffc671d824d00b43a018555cb9fb3f2bc8be8d8ed8c901131e4cd072cc83e610a2cbb580f5f84b60d70bf4c7a7a8c5a629b7b325e1a27dca86d96d2668e0 - languageName: node - linkType: hard - "@babel/helper-define-polyfill-provider@npm:^0.6.8": version: 0.6.8 resolution: "@babel/helper-define-polyfill-provider@npm:0.6.8" @@ -329,16 +263,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-member-expression-to-functions@npm:7.29.7" - dependencies: - "@babel/traverse": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - checksum: 10/bb8dc59a65b4404260e0b7ff70f491de5a1607876f61736d26605ab3cba5b368827b0551acd3458212f5cfa99cbcd48bb66a96497b0fe00af09a6a2cbea4276b - languageName: node - linkType: hard - "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.22.5, @babel/helper-module-imports@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-module-imports@npm:7.28.6" @@ -349,7 +273,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.15.4, @babel/helper-module-imports@npm:^7.29.7": +"@babel/helper-module-imports@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-module-imports@npm:7.29.7" dependencies: @@ -394,29 +318,13 @@ __metadata: languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-optimise-call-expression@npm:7.29.7" - dependencies: - "@babel/types": "npm:^7.29.7" - checksum: 10/6b477e01b403fd48349336cb1d94722bff4fa54af2841b5fa950c557b796f4ecc14724052252ed1362ccfc23d1c09c54dc03e182fea59d3dc5bd69f8c626ba25 - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6": +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-plugin-utils@npm:7.28.6" checksum: 10/21c853bbc13dbdddf03309c9a0477270124ad48989e1ad6524b83e83a77524b333f92edd2caae645c5a7ecf264ec6d04a9ebe15aeb54c7f33c037b71ec521e4a languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-plugin-utils@npm:7.29.7" - checksum: 10/6d16929fe5c792bbc8e4d67e18d7c1be69d2f18992deaa3d94dc26541fec662e83cbeeaf7553c6867d068eb7aed4e0d5e3e137c1dd4d5bcfa286f8d772f1f457 - languageName: node - linkType: hard - "@babel/helper-remap-async-to-generator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" @@ -430,19 +338,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-remap-async-to-generator@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-wrap-function": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/98338ad6e34ebb4be2dc23f8d9199d28d6d8ac6a2ce8b90fe9efdf3595b39748321528d9f2540ec0586a6e45f7c84f5f623fbf980c5efa7fa9ba7ce837ea4b20 - languageName: node - linkType: hard - "@babel/helper-replace-supers@npm:^7.27.1, @babel/helper-replace-supers@npm:^7.28.6": version: 7.28.6 resolution: "@babel/helper-replace-supers@npm:7.28.6" @@ -456,19 +351,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-replace-supers@npm:7.29.7" - dependencies: - "@babel/helper-member-expression-to-functions": "npm:^7.29.7" - "@babel/helper-optimise-call-expression": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/4aa7b48a6078db99bba24b67f63f97cd08ad9b3c476dcca196c6421dc2080f3566d683fba64c772e2f9597603d42ad4ac2ce9ccf0559643823c540f08cf0efa7 - languageName: node - linkType: hard - "@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -479,16 +361,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.29.7" - dependencies: - "@babel/traverse": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - checksum: 10/a5800bfcdca6cef7f6fe33ac02a0f05ff33da9746f97806553f249733f7ba8400290a17f3831d7faa5d91656f254ab749931f53c8a29f301d958d7dd00499637 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-string-parser@npm:7.29.7" @@ -496,7 +368,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.5, @babel/helper-validator-identifier@npm:^7.28.5, @babel/helper-validator-identifier@npm:^7.29.7": +"@babel/helper-validator-identifier@npm:^7.28.5, @babel/helper-validator-identifier@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-validator-identifier@npm:7.29.7" checksum: 10/2efa42701eb05babf26dff3332109c9e5e1a3400a71fb9e68ee27af28235036a2a72c2494c04bdab3f909075f42a58b2e8271074372bc7f8e79ec02bd364d7a7 @@ -528,24 +400,24 @@ __metadata: languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.29.7": +"@babel/helpers@npm:^7.29.2, @babel/helpers@npm:^7.29.7": version: 7.29.7 - resolution: "@babel/helper-wrap-function@npm:7.29.7" + resolution: "@babel/helpers@npm:7.29.7" dependencies: "@babel/template": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" "@babel/types": "npm:^7.29.7" - checksum: 10/fc37b53a93c0814e5443c344fcd42b343c75856d865547ca0d50ddad73e96c27f6a677330d115232644e143066758188e4eb47ce5207124c095312b9e49599ed + checksum: 10/b4d1ef12c19e896585c009ba29677839097ff04f8b11a2430d335c3fb6bd667b4f9e96a3b185a083fdde6b1137eabbbf2600c32425cb69cefc81d81d5cfe425d languageName: node linkType: hard -"@babel/helpers@npm:^7.29.2, @babel/helpers@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helpers@npm:7.29.7" +"@babel/parser@npm:^7.24.4": + version: 7.29.9 + resolution: "@babel/parser@npm:7.29.9" dependencies: - "@babel/template": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - checksum: 10/b4d1ef12c19e896585c009ba29677839097ff04f8b11a2430d335c3fb6bd667b4f9e96a3b185a083fdde6b1137eabbbf2600c32425cb69cefc81d81d5cfe425d + "@babel/types": "npm:^7.29.8" + bin: + parser: ./bin/babel-parser.js + checksum: 10/b8d6acda3fc7405c497b839b0b6d46cbd309d81bdb310c349e5760ecd689c3641925e1184574106161ce2c78cf5c09d22544a0b3e4d5f002e3b78c263c6f11e6 languageName: node linkType: hard @@ -583,18 +455,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/c0e85e9b4bf8706f23b58c1794ad398e41b69a639416578fd4c0ef5a5472365a8d1d7a533f94137daf3660e4f710a8b7e10bc8a53a91a41773ec92bf1725af98 - languageName: node - linkType: hard - "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" @@ -606,17 +466,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/ad06de66ccfb19f0f04e6124d144f3fef72fa5191861b1d04bc32cab87ce43958810d9632eac5881ef991a78b33e68588e3d90e76a63d917bd5a7ff4c96618f8 - languageName: node - linkType: hard - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" @@ -628,29 +477,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/2189a2a648948107c59ad3bf028e5b71a85b28c840facfead769a33c5f63ae4ec0f147e6a2e664a91a506d4405f5a8972d2ca628f3b64d03edd7620d770761fb - languageName: node - linkType: hard - -"@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/a9bd13c2600bdfcb5b35590e210bcb30f009fda9bd1556567757ea4fcb8ca247750331d6d10774d68127cae4e529bc79abd86a28fe5e2a1cc2cc00e75964ac52 - languageName: node - linkType: hard - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" @@ -664,19 +490,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.13.0 - checksum: 10/76a494ec4f52a127b0208c4574a6da36f6ff5f30484306921762db549fa7d9d9183c837759eb68c0c9e5a56013aa247e6e02e02263384d2a103240353ae0ceb6 - languageName: node - linkType: hard - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.6" @@ -689,42 +502,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/73125174671241b3eb1fa7c7f53ed0894d3853f2afb280684492a707cf3e4a9c498537acb511c014d364018117e181bb265dbbb975ea0b1a61a6de60bae8f07e - languageName: node - linkType: hard - -"@babel/plugin-proposal-class-properties@npm:7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.18.6" - "@babel/helper-plugin-utils": "npm:^7.18.6" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/49a78a2773ec0db56e915d9797e44fd079ab8a9b2e1716e0df07c92532f2c65d76aeda9543883916b8e0ff13606afeffa67c5b93d05b607bc87653ad18a91422 - languageName: node - linkType: hard - -"@babel/plugin-proposal-private-methods@npm:7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-proposal-private-methods@npm:7.18.6" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.18.6" - "@babel/helper-plugin-utils": "npm:^7.18.6" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/22d8502ee96bca99ad2c8393e8493e2b8d4507576dd054490fd8201a36824373440106f5b098b6d821b026c7e72b0424ff4aeca69ed5f42e48f029d3a156d5ad - languageName: node - linkType: hard - "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": version: 7.21.0-placeholder-for-preset-env.2 resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" @@ -734,20 +511,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-proposal-private-property-in-object@npm:7.21.11": - version: 7.21.11 - resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.11" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.18.6" - "@babel/helper-create-class-features-plugin": "npm:^7.21.0" - "@babel/helper-plugin-utils": "npm:^7.20.2" - "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f803b5e1de0cb7c53f0d7f70bfbf57f2b3a20d95c19f8f2710719c4938149b490ee14d2d0c2f8316080823f0943c6cb8668fa8c139420e7bc7f80a66bfd50fff - languageName: node - linkType: hard - "@babel/plugin-syntax-import-assertions@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-syntax-import-assertions@npm:7.28.6" @@ -759,17 +522,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a7f24858e7e833c2ee25779a355b5eff46e4bc93c98b06bda7ea0fd12faf99c4954e0f71074485512045920432790e0269aa562dd4d2085c3f8660ed1cfde8a1 - languageName: node - linkType: hard - "@babel/plugin-syntax-import-attributes@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" @@ -781,17 +533,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/9f47345d09aae16b7ab52ecaf541cde3e3ae1e57e3eb2d4088e062b29dfbd67db55d42d529840557583d66121e2a98788df7a455401cc6d635c8b7700a02efc9 - languageName: node - linkType: hard - "@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.27.1": version: 7.28.6 resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" @@ -803,28 +544,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-syntax-jsx@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/84150d27c553a1d3d921354437f6725ca1d63b49514c25591bfcaaafa6ea4d6c10715b66fe7245e4ad7ab7c6cf4b6e1de7373defd3df00877ab12638170d7772 - languageName: node - linkType: hard - -"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.14.5" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/b317174783e6e96029b743ccff2a67d63d38756876e7e5d0ba53a322e38d9ca452c13354a57de1ad476b4c066dbae699e0ca157441da611117a47af88985ecda - languageName: node - linkType: hard - "@babel/plugin-syntax-typescript@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-syntax-typescript@npm:7.28.6" @@ -836,17 +555,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-syntax-typescript@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ef454d2a7a6209dd4255361c072c94ab1293e7ad4b06e7e744d08bb308065d4d6544964eae9b2357c3b33d8d939f9e32d4aa95905bc464407cd8f7101dee4443 - languageName: node - linkType: hard - "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -870,17 +578,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/0037fd7563c7c91cddb8ce104e270bc260190d29c7a297df65e4306471010b4343366de13fab4602cf8ee6c672d3b313b34a01b62f27a333cad16908c83368d8 - languageName: node - linkType: hard - "@babel/plugin-transform-async-generator-functions@npm:^7.29.0": version: 7.29.0 resolution: "@babel/plugin-transform-async-generator-functions@npm:7.29.0" @@ -894,19 +591,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-remap-async-to-generator": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/0abb8d8bb21e7293b3eda5a743051678478ab7c0392310a4a9e0417125a2bb8536a0a5f41a8062211d995479339afa7ffab6b0141f0839af8fbba367dd6a99c5 - languageName: node - linkType: hard - "@babel/plugin-transform-async-to-generator@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-async-to-generator@npm:7.28.6" @@ -920,19 +604,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.29.7" - dependencies: - "@babel/helper-module-imports": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-remap-async-to-generator": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/e24db9c4c69121daab25883f9a96e6849fa664c78c6bbcfb77fe0a0c6ab29b81ba39e8497985367463d3a88deac3b5bbe15dd1c5d0e5dd492cfccf8efdd27452 - languageName: node - linkType: hard - "@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" @@ -944,17 +615,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/24f9712ade98061cd22088709b86b8e3e19ea416dbe5a69ad504fc3f8f2179af5bdeb32fcb9c24fc861bef515e41ae5ef72cd909e0e42bb0cf15838c4e737149 - languageName: node - linkType: hard - "@babel/plugin-transform-block-scoping@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-block-scoping@npm:7.28.6" @@ -966,17 +626,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-block-scoping@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/9c3cbbdda288b2eff7355ab94fc7b4b18f408d8e7145c2d6bd34e70eef03f200c699f527318ac11d9cd6e99124b5e8d6aeeba4421346ee5cdc224d06175d984f - languageName: node - linkType: hard - "@babel/plugin-transform-class-properties@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-class-properties@npm:7.28.6" @@ -989,18 +638,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-class-properties@npm:7.29.7" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/0cc5e7a882e29eead360f02ef79f6b2ec3b3813213b1513d8fdaa931d1d1361fccc92fbacc9b399e42495953d9d6fc722f283b5f3aa272fe016a0b5fe1e6a130 - languageName: node - linkType: hard - "@babel/plugin-transform-class-static-block@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-class-static-block@npm:7.28.6" @@ -1013,18 +650,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-class-static-block@npm:7.29.7" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.12.0 - checksum: 10/9e7112dafb0e7791de3858cb721a76147e8cfc9b6ba370dd0267bdc193abdbe8a8f78db8d70e0f860d03497d861f0ac7e8cd3e8caf2639c59b57fc74eb3b95d0 - languageName: node - linkType: hard - "@babel/plugin-transform-classes@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-classes@npm:7.28.6" @@ -1041,22 +666,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-classes@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-globals": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-replace-supers": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ac6387c6bfb9d9b9f9d0702050fa8833e76c123d607bdba1af8d991f691e01a0652130954baa53051f0e16b8a0545e3f3c5a5bc4404a19abac0af2eee748f898 - languageName: node - linkType: hard - "@babel/plugin-transform-computed-properties@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-computed-properties@npm:7.28.6" @@ -1069,18 +678,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-computed-properties@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/template": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/c982355904fc113334ba108282c8a617e3159c6960de717bbe7c5fa86ff777baea04c117edc692fb4de22b01460bfedc62af3c6a9d0ecd81511f5eb8357d8bab - languageName: node - linkType: hard - "@babel/plugin-transform-destructuring@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-destructuring@npm:7.28.5" @@ -1093,18 +690,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-destructuring@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/e53caad0c2d523367724aefcc6b8c8df24fcb1a3f53e9899cb4bb5dc39ccf61e30df0a761d74485a895d9bcaaad49644879cbd3a9fc20c90501a5e831caaac5b - languageName: node - linkType: hard - "@babel/plugin-transform-dotall-regex@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-dotall-regex@npm:7.28.6" @@ -1117,18 +702,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/537df0fb915a420df715a2f4da16ab6c08ce2370521edef9a8a59af23a533314109f6abd836c5e127c8cea4a46bc4a05692670cf7ad64868c286075fa2d7848c - languageName: node - linkType: hard - "@babel/plugin-transform-duplicate-keys@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" @@ -1140,17 +713,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/f0e7ad459dd9c78514c07a576fa509478aa9c7e90c1d7cf3b1d142579f8dadd609878c10b044dd2a3a2b08adbdb51b108fcb261d9a78443e13494a7985f9c2a7 - languageName: node - linkType: hard - "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.29.0": version: 7.29.0 resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.29.0" @@ -1163,18 +725,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/fa7fcdbede10dbc06fe4f861e90286f7f599d3f3c43e69445e63c3f48422fd34db0b0dd9bbebccd1dbd04a50fca4ab22fd82d28e7bc8fe9b6d5790c9e694d380 - languageName: node - linkType: hard - "@babel/plugin-transform-dynamic-import@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" @@ -1186,17 +736,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/58c035e6b9103c225f3d181671d9b3dec140351c3ecf12bc3a66b8653be41161f20135ada00a703244c2bfc9dd57b62fc54f77f2f6fe43df6c598358f377e6fa - languageName: node - linkType: hard - "@babel/plugin-transform-explicit-resource-management@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.6" @@ -1209,18 +748,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-explicit-resource-management@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/plugin-transform-destructuring": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a4ea28a18161a7e8c8f33731cb3dfc6981cb089b9a6b57abfa7ff7579a0ca76a4c19c29ebaf775b037ff31503c74c6cf3687ce86cdaa246d1c60afb5abd820df - languageName: node - linkType: hard - "@babel/plugin-transform-exponentiation-operator@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.6" @@ -1232,17 +759,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/bf0366d77d318d4b6eae6880217e3fdfcb6e5f7913f658583de9537fd4fca1f05f9ac4083d8f946a84eaefec068cbba948be90f4a39484c85bc69082def3162d - languageName: node - linkType: hard - "@babel/plugin-transform-export-namespace-from@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" @@ -1254,17 +770,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/d157d62b144d1626b801e557dcede914db33e78f3f4230f487e5709c21efd40648f7f3a47a44a7fce694ad9cd117d2ac3ed796da0102275fd02b4fdb317d906b - languageName: node - linkType: hard - "@babel/plugin-transform-for-of@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-for-of@npm:7.27.1" @@ -1277,18 +782,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-for-of@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/af79d2859f7330c4b47fefc49a7849fb651ef062532beafdba5500fc13a46b9dfe1a853a27b73257a092d7e65a7b9956a8df9971c9908825d2f3b86b00c35c38 - languageName: node - linkType: hard - "@babel/plugin-transform-function-name@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-function-name@npm:7.27.1" @@ -1302,19 +795,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-function-name@npm:7.29.7" - dependencies: - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/87a6329442ef8085fbc160e659f64562f0f5b63be65403b8bbb8e18c67dd7d03b82fb2e1371fdde734e2f05b13a72f88ed8d8cb03807150063954b9604d082cf - languageName: node - linkType: hard - "@babel/plugin-transform-json-strings@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-json-strings@npm:7.28.6" @@ -1326,17 +806,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-json-strings@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/3af97e144e0d986522f01803ffa0f90741530d1610952ac6a92511c356ecbf5616092ab1d21401d25bc7cb8ac90d73c2c7ff35e41766df2708c29d7e588cfa7f - languageName: node - linkType: hard - "@babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" @@ -1348,17 +817,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-literals@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/aadb2b3fe85186c274a07d5486aeef9496ce374e534fbc7b54f77985c75513422d9acec4c532f67b027e939644d93a69c00505b8909e259184c3ee5c5c62c46b - languageName: node - linkType: hard - "@babel/plugin-transform-logical-assignment-operators@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.6" @@ -1370,17 +828,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/374d83dfbb2de5e339d2966487c0f0d766cd67422addbd0172104ff2788b60317858172a7ab2cb6ee7d5bffad72ce07120fec009a2ef3b35551013fce4908686 - languageName: node - linkType: hard - "@babel/plugin-transform-member-expression-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" @@ -1392,17 +839,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/698cbc9500e8caea1d36b48248112d60e023cea9d0772ac1ecf1639b38b662d9352043747dbe617fe1f6f17709bc17601534f7bf2f22c791fb86f7e2ab43e39f - languageName: node - linkType: hard - "@babel/plugin-transform-modules-amd@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" @@ -1415,18 +851,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-modules-amd@npm:7.29.7" - dependencies: - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a25cfc84db14a943cee1717030114e052152487af8784c015762a4fc11ee7b45127036c074044636b10c7251eb310c172904028a6f36abcae816e0cc685553b8 - languageName: node - linkType: hard - "@babel/plugin-transform-modules-commonjs@npm:^7.27.1, @babel/plugin-transform-modules-commonjs@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-modules-commonjs@npm:7.28.6" @@ -1439,18 +863,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.29.7" - dependencies: - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/7d816febde2d65bde5607ef355d751ba6c5a2d68ffe47c37b809e3ed2f829603751d4b5a5506f4299936d95fc73909243f9074f98dd32201277ec4131fc3ff33 - languageName: node - linkType: hard - "@babel/plugin-transform-modules-systemjs@npm:^7.29.0": version: 7.29.4 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.4" @@ -1465,20 +877,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.29.7": - version: 7.29.8 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.8" - dependencies: - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-validator-identifier": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.8" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/926dcc428282f4a29e4b650e8f25131891f675cd9c9430587828f9453f9847077ae7d87d71abacfbb1ec5a9c7f97835f57bd84b834134541184c185b21e0e96e - languageName: node - linkType: hard - "@babel/plugin-transform-modules-umd@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" @@ -1491,18 +889,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-modules-umd@npm:7.29.7" - dependencies: - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/74024ae1ecb702a766af6b3131a44be8b50d3614860ba857f8bb1e29c38acbecb14f66e2847082ccc5e188547aaa9678d9bbd67c20cef6f2e597f977a81f34dd - languageName: node - linkType: hard - "@babel/plugin-transform-named-capturing-groups-regex@npm:^7.29.0": version: 7.29.0 resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.29.0" @@ -1515,18 +901,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/3a481be133e9ca5d25570b5ed62daae323a51663bacf30fed0d1980e912047ebd34d6326533182db625fc0bbd086d1a23ed68ebb6108e7a68a8650c228afc084 - languageName: node - linkType: hard - "@babel/plugin-transform-new-target@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-new-target@npm:7.27.1" @@ -1538,17 +912,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-new-target@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/6ef505da7107e46afe170a7c3dc69a2afb2a58276c172189cbba86ed669e64bf2884a16deb007257af399fcc3c2381c688b8bbed612c986ded82ac9fa43ab5b1 - languageName: node - linkType: hard - "@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.28.6" @@ -1560,17 +923,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/4bff79355c240342e18e02cee282ce5c30bafa4335a250f4a47e822fde6def70afa19708e04fec3cc942252da16ea3a28a21279180cc92734c2a2d9826600bb3 - languageName: node - linkType: hard - "@babel/plugin-transform-numeric-separator@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-numeric-separator@npm:7.28.6" @@ -1582,17 +934,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/6177df9e1a8a190bf4a360f8cbcfa614b70ededba61201bd0a38929770b6d00a8a54a19f8fda82cf60688d9bab938427a9fe5dae0a9e8cd8ed79c88a3b2dbcd7 - languageName: node - linkType: hard - "@babel/plugin-transform-object-rest-spread@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.6" @@ -1608,21 +949,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.29.7" - dependencies: - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/plugin-transform-destructuring": "npm:^7.29.7" - "@babel/plugin-transform-parameters": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/36b906179d21a2a3287fac5283b25584bd7b79eb2707c62fa8e75ab79b21b4e11b2670e6b2eafb99fb448495153587dc5cdeec1d8433ba175060e5c8101292b0 - languageName: node - linkType: hard - "@babel/plugin-transform-object-super@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-object-super@npm:7.27.1" @@ -1635,18 +961,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-object-super@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-replace-supers": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/65ed8719563572c4917f19b32c476c9a9062fccf89bfd44a418bb734cd866034d66049499cace58e2bb4589da779983f534078bd989333f36268b9da08d4b33c - languageName: node - linkType: hard - "@babel/plugin-transform-optional-catch-binding@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.28.6" @@ -1658,17 +972,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/4b6e41e1dc5dbd02cfe0b96214130cca5fd3bd879551fc82188bb3d9a2782af9bab50f2140af9ff946a8ee23b9478ee42810641fb99aa3e033884d7c6103d138 - languageName: node - linkType: hard - "@babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.6" @@ -1681,18 +984,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/2fd8f0135d8b051e4873ba097443bd753abd12a32f910fd19ae4c2f94a183129cf0936aed7aa14b417a68752aa1eec7a9fe43befdab736dbb24bbf192b7e5edc - languageName: node - linkType: hard - "@babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" @@ -1704,17 +995,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-parameters@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/05faa7bbe1ae81eda6ab9bfca35476d7e55049b1ad182471a6e5a45a888ef1208977a0cbe0ee23b6920d4754d2386cd94026d705e32acff7a036b9db4110b566 - languageName: node - linkType: hard - "@babel/plugin-transform-private-methods@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-private-methods@npm:7.28.6" @@ -1727,18 +1007,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-private-methods@npm:7.29.7" - dependencies: - "@babel/helper-create-class-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/5055af2b86a95acbf6bd1a14256edf439ba4f214707f6aa9f6a29d1168c882e5709853c4ff225f55575f88d3a58effbed952d25c5cd70f93785106541f992cdd - languageName: node - linkType: hard - "@babel/plugin-transform-private-property-in-object@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-private-property-in-object@npm:7.28.6" @@ -1752,19 +1020,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-create-class-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/72464fe21457daa2002b8fb8ab222dfc4a5fa4df33b99a371ca5594a28c933491d4373349cbff95caff33d8b5506d0350b1b7b0f4fde04ebd1defcdd5d7d9751 - languageName: node - linkType: hard - "@babel/plugin-transform-property-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" @@ -1776,17 +1031,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-property-literals@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/7e7a557df8feb50cd6913158c6d12df0e8a9da58e3f73e7cbfc08af399055b03e77a22b12c73d5bf6bb49239617d6189ccb6021ab03f0225bc54f9c74a880b62 - languageName: node - linkType: hard - "@babel/plugin-transform-react-constant-elements@npm:^7.18.12, @babel/plugin-transform-react-constant-elements@npm:^7.21.3": version: 7.27.1 resolution: "@babel/plugin-transform-react-constant-elements@npm:7.27.1" @@ -1809,17 +1053,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-react-display-name@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/65b6676cfc9a163915e7ed4ca2e3e6080ccaa419cb04e44517101d86f08afc4e3310676c713d18b88b12b98a3e7e44f0694286609207968bb3f60ef3debf9b70 - languageName: node - linkType: hard - "@babel/plugin-transform-react-jsx-development@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" @@ -1831,17 +1064,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.29.7" - dependencies: - "@babel/plugin-transform-react-jsx": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/c535bb5ee09e07839a422f7a8e55849cd30525af57021888eceb84d33391290f6250207319bb4fbb4d4cbdcdb894b2a2b963f0769a3e95536370159b4b505855 - languageName: node - linkType: hard - "@babel/plugin-transform-react-jsx@npm:^7.22.15, @babel/plugin-transform-react-jsx@npm:^7.22.5": version: 7.23.4 resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" @@ -1857,21 +1079,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-react-jsx@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-module-imports": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/plugin-syntax-jsx": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ad735e6666e296404fd3c55378ad9ac712816a9ba3292bf491fd44e2d7bf32217a02c70fd8977c5ae07a246cfdbd75ea3bf5906e69af5dc1d0f404bca09aa7bf - languageName: node - linkType: hard - "@babel/plugin-transform-react-pure-annotations@npm:^7.23.3": version: 7.23.3 resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.23.3" @@ -1884,18 +1091,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/7b6bc9e9db06f2c40685b4f0a043af17a98a8bee833831aa28f70c89876dc649fdd682ae572445143b53fe091258964107bae9d3583480eb1c4f1d9c22780b38 - languageName: node - linkType: hard - "@babel/plugin-transform-regenerator@npm:^7.29.0": version: 7.29.0 resolution: "@babel/plugin-transform-regenerator@npm:7.29.0" @@ -1907,17 +1102,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.29.7": - version: 7.29.8 - resolution: "@babel/plugin-transform-regenerator@npm:7.29.8" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/4dd85d21b9483ef84aea3292aa618ec468fb75178a45f651e2c9d540201580ed9d0c491a160b45d2c220e0a2d91d7f8284a70a9ae721ac5fc4c0aa68b23235fa - languageName: node - linkType: hard - "@babel/plugin-transform-regexp-modifiers@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.28.6" @@ -1930,18 +1114,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regexp-modifiers@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/bfbc6b898ace99b8412eb6e902b90856188c692e69672d42d48c5e22a5bf9b0d15d35424fda8501bfb06ba0504acc5f1b9e13eacaba232aa58af74472d6068dc - languageName: node - linkType: hard - "@babel/plugin-transform-reserved-words@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" @@ -1953,17 +1125,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-reserved-words@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/ffd7f86ddce36c6ded2dd9218f81be8cbae35b1ed01100ac0a98623bd0a76c059188b70953ab5accae8f8430451e8ed4779d533ac5e35c523f5004a981208b7c - languageName: node - linkType: hard - "@babel/plugin-transform-shorthand-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" @@ -1975,17 +1136,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/c57ef27853f334a6147da9aa00f8a8f4c3a1c217eb2efa73cba2e118edda10754fa23cec2c0c7f7408279ad28fef92c1f663dfec137a7503813331569c3e02f9 - languageName: node - linkType: hard - "@babel/plugin-transform-spread@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-spread@npm:7.28.6" @@ -1998,18 +1148,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.29.7": - version: 7.29.8 - resolution: "@babel/plugin-transform-spread@npm:7.29.8" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/bcb0d92a87a534ff2ea46bfc9bd3190ca6f18cf7791ca291f7cfa856a9d74d8f4d930e53bd4a44c1d40e513039d133b08082233e9373b51b9e07406bc1d7720f - languageName: node - linkType: hard - "@babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" @@ -2021,17 +1159,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/16b570c0270a59c2a29b2118c00e463882e9dda49b51a17dde3ae6b2886995d49f4bf2161a4c743ad1bca39d2aeb3ac963400e095682e105c7f751e6a2156c28 - languageName: node - linkType: hard - "@babel/plugin-transform-template-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" @@ -2043,17 +1170,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-template-literals@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/d1014dab020f0f802089de17bba82d929eda6ac87fde5f58fb9763885b8d645ce63fc1df97055c06a12d95a8788334a93b559fcaf1da6d7777a191e5f9c5646e - languageName: node - linkType: hard - "@babel/plugin-transform-typeof-symbol@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" @@ -2065,17 +1181,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/a22bbe6c46cc4b5dda7aeb907d0263f3c3f93763c0ea6f5cac3c511673ec0be3fc6d9f3d9e65450b14e231cb4ae1cdead29ca9e6b4a94d30485baeab50513f85 - languageName: node - linkType: hard - "@babel/plugin-transform-typescript@npm:^7.28.5": version: 7.28.6 resolution: "@babel/plugin-transform-typescript@npm:7.28.6" @@ -2091,21 +1196,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-typescript@npm:7.29.7" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.29.7" - "@babel/helper-create-class-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" - "@babel/plugin-syntax-typescript": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/88d39bcdfee418795ad65097fff88f491e87793b958fe334273a20f74693b64369456a6d666eb0f1e98c9ecb633c99bcccf90562593e64eb92cc9dd040f25c1c - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" @@ -2117,17 +1207,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/69ae159d4c7b5518c8009e96e406c5110c8238412d5f120b382c6f4fa2ff1226c3951d3fdc835461b81b29af78fe9131da51100b8fd47ef7eefe27d7d6d18b29 - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-property-regex@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.28.6" @@ -2140,18 +1219,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/03ee0b5d27eee08ba71bc09e919eb648094123985b7adc7dc875e4172100596a47ab68337abf6814cbd3140c6552cf1044135eb0ec1ec78345e1270e5e6aabba - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" @@ -2164,18 +1231,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/1ade0672ae5bbbf2ec1ea0a8de1b5d804ae414283215620097ab21cf7f05dae8916f5b0548a18c6f080ec17135018f5edd2d38f8fa9ca052af570cab5c712786 - languageName: node - linkType: hard - "@babel/plugin-transform-unicode-sets-regex@npm:^7.28.6": version: 7.28.6 resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.28.6" @@ -2188,99 +1243,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.29.7" - dependencies: - "@babel/helper-create-regexp-features-plugin": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10/680c22e2a63bffbf6798b0c2f599b06beb7ea4d29ee37a56c9192014143d396c479b12783d9c343e107fa491aeeb65b1ca774fd76825ffb306eef7fb5e7b4b2c - languageName: node - linkType: hard - -"@babel/preset-env@npm:7.29.7": - version: 7.29.7 - resolution: "@babel/preset-env@npm:7.29.7" - dependencies: - "@babel/compat-data": "npm:^7.29.7" - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-validator-option": "npm:^7.29.7" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.29.7" - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.29.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.29.7" - "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "npm:^7.29.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.29.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.29.7" - "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions": "npm:^7.29.7" - "@babel/plugin-syntax-import-attributes": "npm:^7.29.7" - "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" - "@babel/plugin-transform-arrow-functions": "npm:^7.29.7" - "@babel/plugin-transform-async-generator-functions": "npm:^7.29.7" - "@babel/plugin-transform-async-to-generator": "npm:^7.29.7" - "@babel/plugin-transform-block-scoped-functions": "npm:^7.29.7" - "@babel/plugin-transform-block-scoping": "npm:^7.29.7" - "@babel/plugin-transform-class-properties": "npm:^7.29.7" - "@babel/plugin-transform-class-static-block": "npm:^7.29.7" - "@babel/plugin-transform-classes": "npm:^7.29.7" - "@babel/plugin-transform-computed-properties": "npm:^7.29.7" - "@babel/plugin-transform-destructuring": "npm:^7.29.7" - "@babel/plugin-transform-dotall-regex": "npm:^7.29.7" - "@babel/plugin-transform-duplicate-keys": "npm:^7.29.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.29.7" - "@babel/plugin-transform-dynamic-import": "npm:^7.29.7" - "@babel/plugin-transform-explicit-resource-management": "npm:^7.29.7" - "@babel/plugin-transform-exponentiation-operator": "npm:^7.29.7" - "@babel/plugin-transform-export-namespace-from": "npm:^7.29.7" - "@babel/plugin-transform-for-of": "npm:^7.29.7" - "@babel/plugin-transform-function-name": "npm:^7.29.7" - "@babel/plugin-transform-json-strings": "npm:^7.29.7" - "@babel/plugin-transform-literals": "npm:^7.29.7" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.29.7" - "@babel/plugin-transform-member-expression-literals": "npm:^7.29.7" - "@babel/plugin-transform-modules-amd": "npm:^7.29.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.29.7" - "@babel/plugin-transform-modules-systemjs": "npm:^7.29.7" - "@babel/plugin-transform-modules-umd": "npm:^7.29.7" - "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.29.7" - "@babel/plugin-transform-new-target": "npm:^7.29.7" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.29.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.29.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.29.7" - "@babel/plugin-transform-object-super": "npm:^7.29.7" - "@babel/plugin-transform-optional-catch-binding": "npm:^7.29.7" - "@babel/plugin-transform-optional-chaining": "npm:^7.29.7" - "@babel/plugin-transform-parameters": "npm:^7.29.7" - "@babel/plugin-transform-private-methods": "npm:^7.29.7" - "@babel/plugin-transform-private-property-in-object": "npm:^7.29.7" - "@babel/plugin-transform-property-literals": "npm:^7.29.7" - "@babel/plugin-transform-regenerator": "npm:^7.29.7" - "@babel/plugin-transform-regexp-modifiers": "npm:^7.29.7" - "@babel/plugin-transform-reserved-words": "npm:^7.29.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.29.7" - "@babel/plugin-transform-spread": "npm:^7.29.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.29.7" - "@babel/plugin-transform-template-literals": "npm:^7.29.7" - "@babel/plugin-transform-typeof-symbol": "npm:^7.29.7" - "@babel/plugin-transform-unicode-escapes": "npm:^7.29.7" - "@babel/plugin-transform-unicode-property-regex": "npm:^7.29.7" - "@babel/plugin-transform-unicode-regex": "npm:^7.29.7" - "@babel/plugin-transform-unicode-sets-regex": "npm:^7.29.7" - "@babel/preset-modules": "npm:0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2: "npm:^0.4.15" - babel-plugin-polyfill-corejs3: "npm:^0.14.0" - babel-plugin-polyfill-regenerator: "npm:^0.6.6" - core-js-compat: "npm:^3.48.0" - semver: "npm:^6.3.1" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/08df2b7dc47108cdd66f807bc6390caa20e54cc4780a320cf5a8049c37af49f3c03889e10bc7911a51bfd854360e120b9443fa039b51356a805784215b81b451 - languageName: node - linkType: hard - "@babel/preset-env@npm:^7.19.4, @babel/preset-env@npm:^7.20.2": version: 7.29.2 resolution: "@babel/preset-env@npm:7.29.2" @@ -2374,22 +1336,6 @@ __metadata: languageName: node linkType: hard -"@babel/preset-react@npm:7.29.7": - version: 7.29.7 - resolution: "@babel/preset-react@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-validator-option": "npm:^7.29.7" - "@babel/plugin-transform-react-display-name": "npm:^7.29.7" - "@babel/plugin-transform-react-jsx": "npm:^7.29.7" - "@babel/plugin-transform-react-jsx-development": "npm:^7.29.7" - "@babel/plugin-transform-react-pure-annotations": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/6bc8a85d9342c20ee2d93095c7283dd2b094ccf14421b4ac974ff00253a58996b696f4256d01c2810ac98350ded744555e4620fc22d743df69298a8b626613e1 - languageName: node - linkType: hard - "@babel/preset-react@npm:^7.18.6": version: 7.23.3 resolution: "@babel/preset-react@npm:7.23.3" @@ -2406,21 +1352,6 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:7.29.7": - version: 7.29.7 - resolution: "@babel/preset-typescript@npm:7.29.7" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.29.7" - "@babel/helper-validator-option": "npm:^7.29.7" - "@babel/plugin-syntax-jsx": "npm:^7.29.7" - "@babel/plugin-transform-modules-commonjs": "npm:^7.29.7" - "@babel/plugin-transform-typescript": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10/487c5b5ee80afd656a8e6254c0638559fa4cd8d11b8d9ef9328cd5c403b8dfd1003690246910681de0f12e879d38fdf91aa2592f51ab9761e5197a3b36508919 - languageName: node - linkType: hard - "@babel/preset-typescript@npm:^7.18.6, @babel/preset-typescript@npm:^7.21.0": version: 7.28.5 resolution: "@babel/preset-typescript@npm:7.28.5" @@ -2436,7 +1367,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": +"@babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.25.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": version: 7.28.6 resolution: "@babel/runtime@npm:7.28.6" checksum: 10/fbcd439cb74d4a681958eb064c509829e3f46d8a4bfaaf441baa81bb6733d1e680bccc676c813883d7741bcaada1d0d04b15aa320ef280b5734e2192b50decf9 @@ -2469,7 +1400,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.29.7, @babel/traverse@npm:^7.29.8": +"@babel/traverse@npm:^7.29.7": version: 7.29.8 resolution: "@babel/traverse@npm:7.29.8" dependencies: @@ -2521,6 +1452,28 @@ __metadata: languageName: node linkType: hard +"@cacheable/memory@npm:^2.2.0": + version: 2.2.0 + resolution: "@cacheable/memory@npm:2.2.0" + dependencies: + "@cacheable/utils": "npm:^2.5.0" + "@keyv/bigmap": "npm:^1.3.1" + hookified: "npm:^1.15.1" + keyv: "npm:^5.6.0" + checksum: 10/97db83d7a74979accca9de56cf278e42c22b4273e752d7e23c44fbec4a47450716c4920903424fd19184a7bee6325064b6c453afc6f96bf92b39eecfe0b40648 + languageName: node + linkType: hard + +"@cacheable/utils@npm:^2.5.0": + version: 2.5.0 + resolution: "@cacheable/utils@npm:2.5.0" + dependencies: + hashery: "npm:^1.5.1" + keyv: "npm:^5.6.0" + checksum: 10/a77a7e682926b984cb28b6993f4595638ce8799de3223dbdcdb796a077a02de763687bdc5669779019aba44d27693260ef92d860a19330d7eaa4dfcca3433c3b + languageName: node + linkType: hard + "@chainsafe/is-ip@npm:^2.0.1": version: 2.1.0 resolution: "@chainsafe/is-ip@npm:2.1.0" @@ -2884,45 +1837,114 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.0 - resolution: "@eslint-community/eslint-utils@npm:4.4.0" +"@eslint-community/eslint-utils@npm:^4.10.1, @eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": + version: 4.10.1 + resolution: "@eslint-community/eslint-utils@npm:4.10.1" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10/61059b9f0192df5a86c441c03e0eedbda8c3810bb788775839afe4c5ec6bbdaa6433ac18001046b319390552435da3f6b8f5e18cca255993b3df37fe97a42b90 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.4.0": + version: 4.4.0 + resolution: "@eslint-community/eslint-utils@npm:4.4.0" + dependencies: + eslint-visitor-keys: "npm:^3.3.0" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10/8d70bcdcd8cd279049183aca747d6c2ed7092a5cf0cf5916faac1ef37ffa74f0c245c2a3a3d3b9979d9dfdd4ca59257b4c5621db699d637b847a2c5e02f491c2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.12.2, @eslint-community/regexpp@npm:^4.8.0": + version: 4.12.2 + resolution: "@eslint-community/regexpp@npm:4.12.2" + checksum: 10/049b280fddf71dd325514e0a520024969431dc3a8b02fa77476e6820e9122f28ab4c9168c11821f91a27982d2453bcd7a66193356ea84e84fb7c8d793be1ba0c + languageName: node + linkType: hard + +"@eslint/compat@npm:2.1.1": + version: 2.1.1 + resolution: "@eslint/compat@npm:2.1.1" + dependencies: + "@eslint/core": "npm:^1.2.1" + peerDependencies: + eslint: ^8.40 || 9 || 10 + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/7749ad710b787bd4a37949f5a0051120b08e313d17bb1b4203e60f7c6500f1194aa55a6e85b329441d0b5102d077a4f8c9898d84feef7e468cec7f106c299811 + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.23.5": + version: 0.23.5 + resolution: "@eslint/config-array@npm:0.23.5" + dependencies: + "@eslint/object-schema": "npm:^3.0.5" + debug: "npm:^4.3.1" + minimatch: "npm:^10.2.4" + checksum: 10/0e05be2b5c8b9f9fb8094948fd2d35591a32091b9d39205181f2ed9bec0e2c8b2969f019f40a0388755a025408b98929e2d0beccb4fbd6609c1c0d6c9e9a14f0 + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.7.0": + version: 0.7.0 + resolution: "@eslint/config-helpers@npm:0.7.0" + dependencies: + "@eslint/core": "npm:^1.2.1" + checksum: 10/57f9cdf303fd56f0da6712e7d6da350c18a332f7d1dc0f5a5f8a9c357f0d5ab9ff9e7515be4726ad4b0fc41c297570a118d7ede02246c5b7a37932c3df46271e + languageName: node + linkType: hard + +"@eslint/core@npm:^1.2.1": + version: 1.2.1 + resolution: "@eslint/core@npm:1.2.1" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10/e1f9f5534f495b74a4c13c372e8f2feaf0c67f5dd666111c849c97c221d4ba730c98333a2ca94dd28cd7c24e3b1016bd868ca03c42e070732c047053f854cb13 + languageName: node + linkType: hard + +"@eslint/css-tree@npm:^4.1.1": + version: 4.1.1 + resolution: "@eslint/css-tree@npm:4.1.1" dependencies: - eslint-visitor-keys: "npm:^3.3.0" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10/8d70bcdcd8cd279049183aca747d6c2ed7092a5cf0cf5916faac1ef37ffa74f0c245c2a3a3d3b9979d9dfdd4ca59257b4c5621db699d637b847a2c5e02f491c2 + mdn-data: "npm:2.35.0" + source-map-js: "npm:^1.2.1" + checksum: 10/9bd6a25b227add974c3f4c995c017022ccdf0b84f0585943898d21151b3ca7e24634f86c8ecb4e80c3b05bca6a30aff75e855f13688ae7bd90366103a68ecf6d languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": - version: 4.11.0 - resolution: "@eslint-community/regexpp@npm:4.11.0" - checksum: 10/f053f371c281ba173fe6ee16dbc4fe544c84870d58035ccca08dba7f6ce1830d895ce3237a0db89ba37616524775dca82f1c502066b58e2d5712d7f87f5ba17c +"@eslint/js@npm:10.0.1": + version: 10.0.1 + resolution: "@eslint/js@npm:10.0.1" + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + checksum: 10/27ff77b8f0aab350b2f7a69d974eabb816bb9f4cab986b1538782269d6bfdc29e351803fa7a62c22c0b786341324f1a28b86bc83956ddfa189aa6bead1a87758 languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10/7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 +"@eslint/object-schema@npm:^3.0.5": + version: 3.0.5 + resolution: "@eslint/object-schema@npm:3.0.5" + checksum: 10/42e9ec2551d7cafe1825f20494576c9a867dfd26e728b66620f55d954cd5c4c9c4987755d147893985b8d39b49dace31117e59e7bc9564eb411b397e579a50e7 languageName: node linkType: hard -"@eslint/js@npm:8.57.0": - version: 8.57.0 - resolution: "@eslint/js@npm:8.57.0" - checksum: 10/3c501ce8a997cf6cbbaf4ed358af5492875e3550c19b9621413b82caa9ae5382c584b0efa79835639e6e0ddaa568caf3499318e5bdab68643ef4199dce5eb0a0 +"@eslint/plugin-kit@npm:^0.7.3": + version: 0.7.3 + resolution: "@eslint/plugin-kit@npm:0.7.3" + dependencies: + "@eslint/core": "npm:^1.2.1" + levn: "npm:^0.4.1" + checksum: 10/bd603f0438d6829a5b0c8cbb90383e3b0fda3aac3a87faa22c80124ce4121f5dcfe8ef9b933c3308cbed70a27c4f51036403e3f0cb64ca2743e595dd865ccef6 languageName: node linkType: hard @@ -3197,14 +2219,30 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.14": - version: 0.11.14 - resolution: "@humanwhocodes/config-array@npm:0.11.14" +"@humanfs/core@npm:^0.19.2": + version: 0.19.2 + resolution: "@humanfs/core@npm:0.19.2" dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.2" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10/3ffb24ecdfab64014a230e127118d50a1a04d11080cbb748bc21629393d100850496456bbcb4e8c438957fe0934430d731042f1264d6a167b62d32fc2863580a + "@humanfs/types": "npm:^0.15.0" + checksum: 10/c6c0273721ec8df3d36a57c390a11a168d0a2f513d78bceb25165bded4fcb73609b1a317edc6c8f331cefd4b47285dde0b1e6679e08ef7f062232ec14fe05312 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.8 + resolution: "@humanfs/node@npm:0.16.8" + dependencies: + "@humanfs/core": "npm:^0.19.2" + "@humanfs/types": "npm:^0.15.0" + "@humanwhocodes/retry": "npm:^0.4.0" + checksum: 10/ed01b3c066d9cec7526d139b9e71ca00ee4a30b3b5f5f5c198eb069c3509a3e167e180ba7e1e5a83b9571e906c4908bd20402b47586887452311af7354995e95 + languageName: node + linkType: hard + +"@humanfs/types@npm:^0.15.0": + version: 0.15.0 + resolution: "@humanfs/types@npm:0.15.0" + checksum: 10/dea3cc7fd8f8d4d088ed8d0a9921cf12bd8e1cdf40a6133106b03a6e2aebcc9a6f1771b3643b7ec71baae90d08245db34069dfcc861da8d678662741e6c3c986 languageName: node linkType: hard @@ -3215,10 +2253,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.2": - version: 2.0.2 - resolution: "@humanwhocodes/object-schema@npm:2.0.2" - checksum: 10/ef915e3e2f34652f3d383b28a9a99cfea476fa991482370889ab14aac8ecd2b38d47cc21932526c6d949da0daf4a4a6bf629d30f41b0caca25e146819cbfa70e +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10/0b32cfd362bea7a30fbf80bb38dcaf77fee9c2cae477ee80b460871d03590110ac9c77d654f04ec5beaf71b6f6a89851bdf6c1e34ccdf2f686bd86fcd97d9e61 languageName: node linkType: hard @@ -3559,6 +2597,25 @@ __metadata: languageName: node linkType: hard +"@keyv/bigmap@npm:^1.3.1": + version: 1.3.1 + resolution: "@keyv/bigmap@npm:1.3.1" + dependencies: + hashery: "npm:^1.4.0" + hookified: "npm:^1.15.0" + peerDependencies: + keyv: ^5.6.0 + checksum: 10/9745786a94729117460b5399a964ec151e94a89db0e5ed573419c4c620f0595f05d7ad87d596bb7e212a4f3ad2335271694fddcfaa8400013f7b64e11669a884 + languageName: node + linkType: hard + +"@keyv/serialize@npm:^1.1.1": + version: 1.1.1 + resolution: "@keyv/serialize@npm:1.1.1" + checksum: 10/e3b2cb1377863342acedd5ff785af3e69269bee9b44707c617d1c8bc14eeb5ac763159d6455903ffe92f143c2238e1e783c4f113f9c8910eacccf172894472da + languageName: node + linkType: hard + "@ledgerhq/devices@npm:8.16.0": version: 8.16.0 resolution: "@ledgerhq/devices@npm:8.16.0" @@ -3769,29 +2826,17 @@ __metadata: languageName: node linkType: hard -"@lidofinance/eslint-config@npm:^0.63.0": - version: 0.63.0 - resolution: "@lidofinance/eslint-config@npm:0.63.0" +"@lidofinance/lido-app-ui@npm:1.4.0": + version: 1.4.0 + resolution: "@lidofinance/lido-app-ui@npm:1.4.0" dependencies: - typescript: "npm:^4.7" + "@lidofinance/lido-shared-ui": "npm:^1.1.3" + classnames: "npm:2.5.1" + react-jazzicon: "npm:1.0.4" peerDependencies: - "@next/eslint-plugin-next": ^13 - "@typescript-eslint/eslint-plugin": ^5 - "@typescript-eslint/parser": ^5.46.0 - eslint: ^8.29 - eslint-config-prettier: ^8.5.0 - eslint-import-resolver-node: ^0.3.6 - eslint-import-resolver-typescript: ^3 - eslint-plugin-eslint-comments: ^3 - eslint-plugin-import: ^2 - eslint-plugin-jest: ^27 - eslint-plugin-prettier: ^4 - eslint-plugin-promise: ^6 - eslint-plugin-react: ^7 - eslint-plugin-react-hooks: ^4 - eslint-plugin-sonarjs: ^0.14.0 - eslint-plugin-unicorn: ^45 - checksum: 10/97c3f91c730eea63ec42c7c866908ea04e92a8c762ca6731db8b913a183566d39d29c89f1bd2fa866d36433c84dee2f4c3994fb93fabe4bdcabad676dd562568 + react: ^18 + react-dom: ^18 + checksum: 10/32f08b66d95327723d74f870ab51538dc31410a4fc67bf1a8ef8d4409b47c348ce325770982de9600cc722e374585f166ae070b89fe84bf20367bc74f3c7df41 languageName: node linkType: hard @@ -3812,6 +2857,19 @@ __metadata: languageName: node linkType: hard +"@lidofinance/lido-shared-ui@npm:^1.1.3": + version: 1.1.3 + resolution: "@lidofinance/lido-shared-ui@npm:1.1.3" + dependencies: + classnames: "npm:2.5.1" + ua-parser-js: "npm:2.0.3" + peerDependencies: + react: ^18 + react-dom: ^18 + checksum: 10/c565cb4eeb5d3bcc8b867173201eb24a7c10170ccce1fec8da08e92bc878fce48f6fc214e6dea8648a80e23a57909488efd969cab60f512a6af73bd95babf619 + languageName: node + linkType: hard + "@lidofinance/lido-ui@npm:^3.18.0": version: 3.18.2 resolution: "@lidofinance/lido-ui@npm:3.18.2" @@ -4130,15 +3188,6 @@ __metadata: languageName: node linkType: hard -"@next/eslint-plugin-next@npm:^13.5.11": - version: 13.5.11 - resolution: "@next/eslint-plugin-next@npm:13.5.11" - dependencies: - glob: "npm:7.1.7" - checksum: 10/113d694eef1551a01a725011233053684da61a8b4753f4ce06a5ad31db50aadd51f56e0b5b0d08ebc7c0f07dd7ad1eb93177af32f86141e477d562005eb459d5 - languageName: node - linkType: hard - "@next/swc-android-arm-eabi@npm:12.3.4": version: 12.3.4 resolution: "@next/swc-android-arm-eabi@npm:12.3.4" @@ -4230,13 +3279,6 @@ __metadata: languageName: node linkType: hard -"@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3": - version: 2.1.8-no-fsevents.3 - resolution: "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3" - checksum: 10/c6e83af3b5051a3f6562649ff8fe37de9934a4cc02138678ed1badbd13ed3334f7ae5f63f2bbc3432210f6b245f082ac97e9b2afe0c13730c9838b295658c185 - languageName: node - linkType: hard - "@noble/ciphers@npm:1.3.0, @noble/ciphers@npm:^1.3.0": version: 1.3.0 resolution: "@noble/ciphers@npm:1.3.0" @@ -4327,7 +3369,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -4337,13 +3379,6 @@ __metadata: languageName: node linkType: hard -"@nolyfill/is-core-module@npm:1.0.39": - version: 1.0.39 - resolution: "@nolyfill/is-core-module@npm:1.0.39" - checksum: 10/0d6e098b871eca71d875651288e1f0fa770a63478b0b50479c99dc760c64175a56b5b04f58d5581bbcc6b552b8191ab415eada093d8df9597ab3423c8cac1815 - languageName: node - linkType: hard - "@npmcli/agent@npm:^3.0.0": version: 3.0.0 resolution: "@npmcli/agent@npm:3.0.0" @@ -4696,13 +3731,6 @@ __metadata: languageName: node linkType: hard -"@oxc-project/types@npm:=0.147.0": - version: 0.147.0 - resolution: "@oxc-project/types@npm:0.147.0" - checksum: 10/d454c44bb9e65b8a660c2b2099391883986bbb6796fd4eea22fbd3016af109547986ec5fa0685db9ee7a6c5e33568134a2e5eea6452eb0f94c4fcc44e544fb32 - languageName: node - linkType: hard - "@oxc-project/types@npm:=0.149.0": version: 0.149.0 resolution: "@oxc-project/types@npm:0.149.0" @@ -4710,6 +3738,13 @@ __metadata: languageName: node linkType: hard +"@oxc-project/types@npm:=0.153.0": + version: 0.153.0 + resolution: "@oxc-project/types@npm:0.153.0" + checksum: 10/b123d6c8ed40b683be9af3a976148d522c621421bbae2d5716d210cda7a858108daa4bad77450b780f63529f2c43bd00e4c179f5952ffb6abbaacebdc71e282f + languageName: node + linkType: hard + "@paulmillr/qr@npm:^0.2.1": version: 0.2.1 resolution: "@paulmillr/qr@npm:0.2.1" @@ -4848,72 +3883,6 @@ __metadata: languageName: node linkType: hard -"@reef-knot/connect-wallet-modal@npm:*, @reef-knot/connect-wallet-modal@workspace:packages/connect-wallet-modal": - version: 0.0.0-use.local - resolution: "@reef-knot/connect-wallet-modal@workspace:packages/connect-wallet-modal" - dependencies: - "@ledgerhq/hw-app-eth": "npm:7.8.12" - "@ledgerhq/hw-transport": "npm:6.35.7" - "@ledgerhq/hw-transport-webhid": "npm:6.36.0" - "@lidofinance/lido-ui": "npm:^3.18.0" - "@reef-knot/core-react": "npm:*" - "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/types": "npm:*" - "@reef-knot/ui-react": "npm:*" - "@reef-knot/wallets-helpers": "npm:*" - "@reef-knot/wallets-list": "npm:*" - "@reef-knot/web3-react": "npm:*" - "@types/react": "npm:18.2.45" - "@types/react-dom": "npm:18.2.17" - build-config: "npm:*" - eslint-config-custom: "npm:*" - react: "npm:18.2.0" - react-dom: "npm:^18.2.0" - viem: "npm:>=2.50" - wagmi: "npm:>=3.6" - peerDependencies: - "@lidofinance/lido-ui": ^3.18.0 - "@reef-knot/core-react": "*" - "@reef-knot/ledger-connector": "*" - "@reef-knot/types": "*" - "@reef-knot/ui-react": "*" - "@reef-knot/wallets-helpers": "*" - "@reef-knot/web3-react": "*" - "@tanstack/react-query": ^5.29.0 - react: ">=18" - viem: ">=2.50" - wagmi: ">=3.6" - languageName: unknown - linkType: soft - -"@reef-knot/core-react@npm:*, @reef-knot/core-react@workspace:packages/core-react": - version: 0.0.0-use.local - resolution: "@reef-knot/core-react@workspace:packages/core-react" - dependencies: - "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/types": "npm:*" - "@reef-knot/ui-react": "npm:*" - "@reef-knot/wallets-helpers": "npm:*" - "@reef-knot/wallets-list": "npm:*" - build-config: "npm:*" - eslint-config-custom: "npm:*" - mipd: "npm:0.0.7" - react: "npm:18.2.0" - viem: "npm:>=2.50" - wagmi: "npm:>=3.6" - peerDependencies: - "@reef-knot/ledger-connector": "*" - "@reef-knot/types": "*" - "@reef-knot/ui-react": "*" - "@reef-knot/wallets-helpers": "*" - "@reef-knot/wallets-list": "*" - "@tanstack/react-query": ^5.29.0 - react: ">=18" - viem: ">=2.50" - wagmi: ">=3.6" - languageName: unknown - linkType: soft - "@reef-knot/ledger-connector@npm:*, @reef-knot/ledger-connector@workspace:packages/connectors/ledger-connector": version: 0.0.0-use.local resolution: "@reef-knot/ledger-connector@workspace:packages/connectors/ledger-connector" @@ -4925,7 +3894,6 @@ __metadata: "@ledgerhq/iframe-provider": "npm:^0.4.3" "@types/w3c-web-hid": "npm:^1.0.7" build-config: "npm:*" - eslint-config-custom: "npm:*" happy-dom: "npm:^20.0.0" viem: "npm:>=2.50" vitest: "npm:^4.1.11" @@ -4937,45 +3905,56 @@ __metadata: languageName: unknown linkType: soft -"@reef-knot/types@npm:*, @reef-knot/types@workspace:packages/types": +"@reef-knot/ui-lido-legacy@npm:*, @reef-knot/ui-lido-legacy@workspace:packages/ui-lido-legacy": version: 0.0.0-use.local - resolution: "@reef-knot/types@workspace:packages/types" + resolution: "@reef-knot/ui-lido-legacy@workspace:packages/ui-lido-legacy" dependencies: - "@reef-knot/ui-react": "npm:*" + "@lidofinance/lido-ui": "npm:^3.18.0" + "@tanstack/react-query": "npm:^5.51.1" + "@types/react": "npm:18.2.45" + "@types/react-dom": "npm:18.2.17" + "@types/react-transition-group": "npm:4.4.12" build-config: "npm:*" + happy-dom: "npm:^20.0.0" react: "npm:18.2.0" + react-dom: "npm:18.2.0" + react-transition-group: "npm:4" + reef-knot: "npm:*" + styled-components: "npm:^5.3.6" + tsconfig: "npm:*" + use-callback-ref: "npm:1.2.5" viem: "npm:>=2.50" + vitest: "npm:^4.1.11" wagmi: "npm:>=3.6" peerDependencies: - "@reef-knot/ui-react": "*" - "@tanstack/react-query": ^5.29.0 + "@lidofinance/lido-ui": ^3.18.0 react: ">=18" - viem: ">=2.50" - wagmi: ">=3.6" + react-dom: ">=18" + reef-knot: ^9 + styled-components: ^5.3.5 languageName: unknown linkType: soft -"@reef-knot/ui-react@npm:*, @reef-knot/ui-react@workspace:packages/ui-react": +"@reef-knot/ui-lido@npm:*, @reef-knot/ui-lido@workspace:packages/ui-lido": version: 0.0.0-use.local - resolution: "@reef-knot/ui-react@workspace:packages/ui-react" + resolution: "@reef-knot/ui-lido@workspace:packages/ui-lido" dependencies: - "@tanstack/react-query": "npm:^5.29.0" - "@types/react-transition-group": "npm:4.4.12" + "@lidofinance/lido-app-ui": "npm:1.4.0" + "@tanstack/react-query": "npm:^5.51.1" + "@types/react": "npm:18.2.45" + "@types/react-dom": "npm:18.2.17" build-config: "npm:*" - eslint-config-custom: "npm:*" + happy-dom: "npm:^20.0.0" react: "npm:18.2.0" react-dom: "npm:18.2.0" - react-transition-group: "npm:4" - styled-components: "npm:^5.3.6" - use-callback-ref: "npm:1.2.5" - viem: "npm:>=2.50" - wagmi: "npm:>=3.6" + reef-knot: "npm:*" + tsconfig: "npm:*" + vitest: "npm:^4.1.11" peerDependencies: - react: ">=18" - react-dom: ">=18" - styled-components: 5 - viem: ">=2.50" - wagmi: ">=3.6" + "@lidofinance/lido-app-ui": ~1.4.0 + react: ^18 + react-dom: ^18 + reef-knot: ^9 languageName: unknown linkType: soft @@ -4983,12 +3962,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-ambire@workspace:packages/wallets/ambire" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -4999,12 +3975,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-anchorage-digital@workspace:packages/wallets/anchorageDigital" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" wagmi: ">=3.6" languageName: unknown @@ -5014,12 +3987,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-bitkeep@workspace:packages/wallets/bitkeep" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -5030,12 +4000,11 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-browser-extension@workspace:packages/wallets/browserExtension" dependencies: - "@reef-knot/types": "npm:*" + "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" viem: "npm:>=2.50" peerDependencies: - "@reef-knot/types": "*" + "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 viem: ">=2.50" wagmi: ">=3.6" @@ -5046,12 +4015,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-coinbase-smart-wallet@workspace:packages/wallets/coinbase-smart-wallet" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -5062,12 +4028,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-dapp-browser-injected@workspace:packages/wallets/dappBrowserInjected" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 viem: ">=2.50" @@ -5079,12 +4042,11 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-imtoken@workspace:packages/wallets/imtoken" dependencies: - "@reef-knot/types": "npm:*" + "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" viem: "npm:>=2.50" peerDependencies: - "@reef-knot/types": "*" + "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 viem: ">=2.50" wagmi: ">=3.6" @@ -5096,12 +4058,11 @@ __metadata: resolution: "@reef-knot/wallet-adapter-ledger-hid@workspace:packages/wallets/ledger-hid" dependencies: "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/types": "npm:*" + "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: "@reef-knot/ledger-connector": "*" - "@reef-knot/types": "*" + "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" languageName: unknown @@ -5112,12 +4073,11 @@ __metadata: resolution: "@reef-knot/wallet-adapter-ledger-live@workspace:packages/wallets/ledger-live" dependencies: "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/types": "npm:*" + "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: "@reef-knot/ledger-connector": "*" - "@reef-knot/types": "*" + "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" languageName: unknown @@ -5127,12 +4087,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-metamask@workspace:packages/wallets/metamask" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -5143,12 +4100,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-okx@workspace:packages/wallets/okx" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -5159,15 +4113,14 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-safe@workspace:packages/wallets/safe" dependencies: - "@reef-knot/types": "npm:*" + "@reef-knot/wallets-helpers": "npm:*" "@safe-global/safe-apps-provider": "npm:^0.18.6" "@safe-global/safe-apps-sdk": "npm:^9.1.0" build-config: "npm:*" - eslint-config-custom: "npm:*" happy-dom: "npm:^20.0.0" vitest: "npm:^4.1.11" peerDependencies: - "@reef-knot/types": "*" + "@reef-knot/wallets-helpers": "*" "@safe-global/safe-apps-provider": ^0.18.6 "@safe-global/safe-apps-sdk": ^9.1.0 "@tanstack/react-query": ^5.29.0 @@ -5180,12 +4133,9 @@ __metadata: version: 0.0.0-use.local resolution: "@reef-knot/wallet-adapter-walletconnect@workspace:packages/wallets/walletconnect" dependencies: - "@reef-knot/types": "npm:*" "@reef-knot/wallets-helpers": "npm:*" build-config: "npm:*" - eslint-config-custom: "npm:*" peerDependencies: - "@reef-knot/types": "*" "@reef-knot/wallets-helpers": "*" "@tanstack/react-query": ^5.29.0 wagmi: ">=3.6" @@ -5198,8 +4148,10 @@ __metadata: dependencies: "@types/ua-parser-js": "npm:0.7.39" build-config: "npm:*" - eslint-config-custom: "npm:*" + mipd: "npm:0.0.7" + react: "npm:18.2.0" ua-parser-js: "npm:1.0.37" + vitest: "npm:^4.1.11" wagmi: "npm:>=3.6" peerDependencies: "@tanstack/react-query": ^5.29.0 @@ -5208,81 +4160,6 @@ __metadata: languageName: unknown linkType: soft -"@reef-knot/wallets-icons@workspace:packages/wallets-icons": - version: 0.0.0-use.local - resolution: "@reef-knot/wallets-icons@workspace:packages/wallets-icons" - dependencies: - build-config: "npm:*" - eslint-config-custom: "npm:*" - react: "npm:18.2.0" - peerDependencies: - react: ">=18" - languageName: unknown - linkType: soft - -"@reef-knot/wallets-list@npm:*, @reef-knot/wallets-list@workspace:packages/wallets-list": - version: 0.0.0-use.local - resolution: "@reef-knot/wallets-list@workspace:packages/wallets-list" - dependencies: - "@reef-knot/types": "npm:*" - "@reef-knot/wallet-adapter-ambire": "npm:*" - "@reef-knot/wallet-adapter-anchorage-digital": "npm:*" - "@reef-knot/wallet-adapter-bitkeep": "npm:*" - "@reef-knot/wallet-adapter-browser-extension": "npm:*" - "@reef-knot/wallet-adapter-coinbase-smart-wallet": "npm:*" - "@reef-knot/wallet-adapter-dapp-browser-injected": "npm:*" - "@reef-knot/wallet-adapter-imtoken": "npm:*" - "@reef-knot/wallet-adapter-ledger-hid": "npm:*" - "@reef-knot/wallet-adapter-ledger-live": "npm:*" - "@reef-knot/wallet-adapter-metamask": "npm:*" - "@reef-knot/wallet-adapter-okx": "npm:*" - "@reef-knot/wallet-adapter-safe": "npm:*" - "@reef-knot/wallet-adapter-walletconnect": "npm:*" - build-config: "npm:*" - eslint-config-custom: "npm:*" - peerDependencies: - "@reef-knot/types": "*" - "@tanstack/react-query": ^5.29.0 - react: ">=18" - viem: ">=2.50" - wagmi: ">=3.6" - languageName: unknown - linkType: soft - -"@reef-knot/web3-react@npm:*, @reef-knot/web3-react@workspace:packages/web3-react": - version: 0.0.0-use.local - resolution: "@reef-knot/web3-react@workspace:packages/web3-react" - dependencies: - "@babel/cli": "npm:7.29.7" - "@babel/core": "npm:7.29.7" - "@babel/plugin-proposal-class-properties": "npm:7.18.6" - "@babel/plugin-proposal-private-methods": "npm:7.18.6" - "@babel/plugin-proposal-private-property-in-object": "npm:7.21.11" - "@babel/preset-env": "npm:7.29.7" - "@babel/preset-react": "npm:7.29.7" - "@babel/preset-typescript": "npm:7.29.7" - "@reef-knot/core-react": "npm:*" - "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/wallets-helpers": "npm:*" - "@testing-library/react": "npm:^12.1.5" - "@testing-library/react-hooks": "npm:^7.0.2" - "@types/react": "npm:18.2.45" - babel-loader: "npm:8.4.1" - babel-plugin-styled-components: "npm:1.13.3" - build-config: "npm:*" - eslint-config-custom: "npm:*" - react: "npm:18.2.0" - tiny-invariant: "npm:^1.1.0" - peerDependencies: - "@reef-knot/core-react": "*" - "@reef-knot/ledger-connector": "*" - "@reef-knot/wallets-helpers": "*" - "@tanstack/react-query": ^5.29.0 - react: ">=18" - wagmi: ">=3.6" - languageName: unknown - linkType: soft - "@reown/appkit-common@npm:1.8.17-wc-circular-dependencies-fix.0": version: 1.8.17-wc-circular-dependencies-fix.0 resolution: "@reown/appkit-common@npm:1.8.17-wc-circular-dependencies-fix.0" @@ -5425,9 +4302,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-android-arm-eabi@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-android-arm-eabi@npm:1.2.6" +"@rolldown/binding-android-arm-eabi@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-android-arm-eabi@npm:1.2.13" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -5439,9 +4316,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-android-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-android-arm64@npm:1.2.6" +"@rolldown/binding-android-arm64@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-android-arm64@npm:1.2.13" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -5453,9 +4330,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-darwin-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-darwin-arm64@npm:1.2.6" +"@rolldown/binding-darwin-arm64@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-darwin-arm64@npm:1.2.13" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -5467,9 +4344,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-darwin-x64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-darwin-x64@npm:1.2.6" +"@rolldown/binding-darwin-x64@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-darwin-x64@npm:1.2.13" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -5481,9 +4358,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-freebsd-x64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-freebsd-x64@npm:1.2.6" +"@rolldown/binding-freebsd-x64@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-freebsd-x64@npm:1.2.13" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -5495,9 +4372,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.6" +"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.13" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -5509,9 +4386,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-arm64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.6" +"@rolldown/binding-linux-arm64-gnu@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.13" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard @@ -5523,9 +4400,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-arm64-musl@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.6" +"@rolldown/binding-linux-arm64-musl@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.13" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard @@ -5537,9 +4414,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-ppc64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.6" +"@rolldown/binding-linux-ppc64-gnu@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.13" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard @@ -5551,9 +4428,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-s390x-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.6" +"@rolldown/binding-linux-s390x-gnu@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.13" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard @@ -5565,9 +4442,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-x64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.6" +"@rolldown/binding-linux-x64-gnu@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.13" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard @@ -5579,9 +4456,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-linux-x64-musl@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.6" +"@rolldown/binding-linux-x64-musl@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.13" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard @@ -5593,9 +4470,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-openharmony-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.6" +"@rolldown/binding-openharmony-arm64@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.13" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -5607,9 +4484,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-win32-arm64-msvc@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.6" +"@rolldown/binding-win32-arm64-msvc@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.13" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -5621,9 +4498,9 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-win32-x64-msvc@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.6" +"@rolldown/binding-win32-x64-msvc@npm:1.2.13": + version: 1.2.13 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.13" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -6723,6 +5600,13 @@ __metadata: languageName: node linkType: hard +"@sonarsource/analyzer-commons-configurations@npm:^2.31.0-5284": + version: 2.31.0-5284 + resolution: "@sonarsource/analyzer-commons-configurations@npm:2.31.0-5284" + checksum: 10/f129e15465a0a762330ab846b4a19346adf55309f161c7308c6dc4dddb6572529fed8ca26d5e9f315198562aa0c5109286d2789af62f3a3666124b6f6fc7187e + languageName: node + linkType: hard + "@standard-schema/spec@npm:^1.1.0": version: 1.1.0 resolution: "@standard-schema/spec@npm:1.1.0" @@ -7170,73 +6054,21 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:5.51.15": - version: 5.51.15 - resolution: "@tanstack/query-core@npm:5.51.15" - checksum: 10/66d319e29891a1bcb8c3800ad69e11941d8aff64687dd3e042e1f6ccc73917d47bdab4dc04d3d7536211a5ff9f4e7e9b0b47d4f438f44db0d0a7d4d91a1ccc02 - languageName: node - linkType: hard - -"@tanstack/react-query@npm:^5.29.0": - version: 5.51.15 - resolution: "@tanstack/react-query@npm:5.51.15" - dependencies: - "@tanstack/query-core": "npm:5.51.15" - peerDependencies: - react: ^18.0.0 - checksum: 10/637a79951d35f9bc28eb6667f4d7936436e80b2e51377cce3dafe83a21ba65575272036e980f6bf755b5b4b4cde2e35cddb9c0d14c5ed9a83a15b68372fced72 - languageName: node - linkType: hard - -"@testing-library/dom@npm:^8.0.0": - version: 8.20.1 - resolution: "@testing-library/dom@npm:8.20.1" - dependencies: - "@babel/code-frame": "npm:^7.10.4" - "@babel/runtime": "npm:^7.12.5" - "@types/aria-query": "npm:^5.0.1" - aria-query: "npm:5.1.3" - chalk: "npm:^4.1.0" - dom-accessibility-api: "npm:^0.5.9" - lz-string: "npm:^1.5.0" - pretty-format: "npm:^27.0.2" - checksum: 10/6c7a92fcc89931ef62a9a92dacec09b3e5ee5c3aba2171aa8de6c7504927b7c9364d73d2ed87b72447d6783108c1c92c207d16f788de64c69bc97059d7105e3c - languageName: node - linkType: hard - -"@testing-library/react-hooks@npm:^7.0.2": - version: 7.0.2 - resolution: "@testing-library/react-hooks@npm:7.0.2" - dependencies: - "@babel/runtime": "npm:^7.12.5" - "@types/react": "npm:>=16.9.0" - "@types/react-dom": "npm:>=16.9.0" - "@types/react-test-renderer": "npm:>=16.9.0" - react-error-boundary: "npm:^3.1.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - react-test-renderer: ">=16.9.0" - peerDependenciesMeta: - react-dom: - optional: true - react-test-renderer: - optional: true - checksum: 10/2f9f4f775d11f3a6526a4f5bcb359fd17c387c1604a0e055a4a312c74f4cb1694f4a9432434eb565571aee0d595c8ad7a1dc70aeec04b56864da081d9ed840e6 +"@tanstack/query-core@npm:5.104.1": + version: 5.104.1 + resolution: "@tanstack/query-core@npm:5.104.1" + checksum: 10/05a4410e32e91eb471a7ca1f420c839b49a11367e15a3cebe8ca94e6bfdfbd3bf75a8c22da664746032113419da95d4a37a3be18471fab009d94601d9295d890 languageName: node linkType: hard -"@testing-library/react@npm:^12.1.5": - version: 12.1.5 - resolution: "@testing-library/react@npm:12.1.5" +"@tanstack/react-query@npm:^5.51.1": + version: 5.104.1 + resolution: "@tanstack/react-query@npm:5.104.1" dependencies: - "@babel/runtime": "npm:^7.12.5" - "@testing-library/dom": "npm:^8.0.0" - "@types/react-dom": "npm:<18.0.0" + "@tanstack/query-core": "npm:5.104.1" peerDependencies: - react: <18.0.0 - react-dom: <18.0.0 - checksum: 10/24ea6ed298ae65c374b3068974359371f551fa1ffdeb5de9853432856ff63b71576d8bbfa8ee1e45d4fa214c2135e49561bafc9b11528cecc8a7943e2a942255 + react: ^18 || ^19 + checksum: 10/845b0e7549bce8b85adeb8d092bbdf749b8215296420a02023f2abcee3b350e5d54fcc5aaf396eff617a86581da8313652c3e4de2f6d30848424c1f201409c86 languageName: node linkType: hard @@ -7327,13 +6159,6 @@ __metadata: languageName: node linkType: hard -"@types/aria-query@npm:^5.0.1": - version: 5.0.4 - resolution: "@types/aria-query@npm:5.0.4" - checksum: 10/c0084c389dc030daeaf0115a92ce43a3f4d42fc8fef2d0e22112d87a42798d4a15aac413019d4a63f868327d52ad6740ab99609462b442fe6b9286b172d2e82e - languageName: node - linkType: hard - "@types/chai@npm:^5.2.2": version: 5.2.3 resolution: "@types/chai@npm:5.2.3" @@ -7369,7 +6194,14 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:^1.0.0": +"@types/esrecurse@npm:^4.3.1": + version: 4.3.1 + resolution: "@types/esrecurse@npm:4.3.1" + checksum: 10/ada5798554b76ac466e90fff26a769b65f905666f32988dcd1b6cf8288896e0fb53080843fd644bf731d16719a6e09b155d623ce36545b75abdd99bb6dcec114 + languageName: node + linkType: hard + +"@types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": version: 1.0.9 resolution: "@types/estree@npm:1.0.9" checksum: 10/16aabfa703b5bdac83f719b07ce92a11b2d3c9b8628eacc92889d8af46cab2d78fc45c7b5378de383d0500585cea5c2f79125eeddfe5fbc6bd6a27eb0c8ccee5 @@ -7395,7 +6227,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -7430,6 +6262,16 @@ __metadata: languageName: node linkType: hard +"@types/node-fetch@npm:^2.6.12": + version: 2.6.13 + resolution: "@types/node-fetch@npm:2.6.13" + dependencies: + "@types/node": "npm:*" + form-data: "npm:^4.0.4" + checksum: 10/944d52214791ebba482ca1393a4f0d62b0dbac5f7343ff42c128b75d5356d8bcefd4df77771b55c1acd19d118e16e9bd5d2792819c51bc13402d1c87c0975435 + languageName: node + linkType: hard + "@types/node@npm:*, @types/node@npm:>=13.7.0": version: 26.1.0 resolution: "@types/node@npm:26.1.0" @@ -7462,7 +6304,7 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0, @types/normalize-package-data@npm:^2.4.3, @types/normalize-package-data@npm:^2.4.4": +"@types/normalize-package-data@npm:^2.4.3, @types/normalize-package-data@npm:^2.4.4": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" checksum: 10/65dff72b543997b7be8b0265eca7ace0e34b75c3e5fee31de11179d08fa7124a7a5587265d53d0409532ecb7f7fba662c2012807963e1f9b059653ec2c83ee05 @@ -7499,33 +6341,6 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:<18.0.0": - version: 17.0.25 - resolution: "@types/react-dom@npm:17.0.25" - dependencies: - "@types/react": "npm:^17" - checksum: 10/5854802aee0f23436e086b179360e93ac6db3387339f7e9359a786245a36bff5e4c36ff380e9ddb3c7c02d720a3bc9cbb3a3433906ecb4b48482f6e5462d1d22 - languageName: node - linkType: hard - -"@types/react-dom@npm:>=16.9.0": - version: 18.2.18 - resolution: "@types/react-dom@npm:18.2.18" - dependencies: - "@types/react": "npm:*" - checksum: 10/4ef7725b4cebd4a32e049097ddfdfd855a178e63ead97ab6d3084872e7d6c1acd71aa923488123cd1015f0e0b11489d2b44f674a1df8fe82d7827eabbec6dbf1 - languageName: node - linkType: hard - -"@types/react-test-renderer@npm:>=16.9.0": - version: 18.0.7 - resolution: "@types/react-test-renderer@npm:18.0.7" - dependencies: - "@types/react": "npm:*" - checksum: 10/701d7d815fe7b921712ebdb2c4434e99b92403d37c51b33a01ce1b62fed7d1efbf9f749971d9031a5b137c6d5e194249c378106768aa69725a01f150fef0ec7f - languageName: node - linkType: hard - "@types/react-transition-group@npm:4.4.12": version: 4.4.12 resolution: "@types/react-transition-group@npm:4.4.12" @@ -7535,7 +6350,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:>=16.9.0": +"@types/react@npm:*": version: 18.2.48 resolution: "@types/react@npm:18.2.48" dependencies: @@ -7557,17 +6372,6 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^17": - version: 17.0.75 - resolution: "@types/react@npm:17.0.75" - dependencies: - "@types/prop-types": "npm:*" - "@types/scheduler": "npm:*" - csstype: "npm:^3.0.2" - checksum: 10/c0dc70e51f2e0a6df617bdaef2c95ddf47ea7a7a416b8dffb482299f215fa28444b9a6d9fe95930ede674514c5cfe429b7c9f582dd3caf74dc3325ea6d8565b8 - languageName: node - linkType: hard - "@types/scheduler@npm:*": version: 0.16.8 resolution: "@types/scheduler@npm:0.16.8" @@ -7575,7 +6379,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.12, @types/semver@npm:^7.7.0": +"@types/semver@npm:^7.7.0": version: 7.7.1 resolution: "@types/semver@npm:7.7.1" checksum: 10/8f09e7e6ca3ded67d78ba7a8f7535c8d9cf8ced83c52e7f3ac3c281fe8c689c3fe475d199d94390dc04fc681d51f2358b430bb7b2e21c62de24f2bee2c719068 @@ -7653,191 +6457,359 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" +"@typescript-eslint/eslint-plugin@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/eslint-plugin@npm:8.71.1" dependencies: - "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/type-utils": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" + "@eslint-community/regexpp": "npm:^4.12.2" + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/type-utils": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + ignore: "npm:^7.0.5" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^1.3.0" + ts-api-utils: "npm:^2.5.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/6ee4c61f145dc05f0a567b8ac01b5399ef9c75f58bc6e9a3ffca8927b15e2be2d4c3fd32a2c1a7041cc0848fdeadac30d9cb0d3bcd3835d301847a88ffd19c4d + "@typescript-eslint/parser": ^8.71.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/dc117ca7be83d17b41d3298165b336d46797da247a8388614f3f65afc7875fb4fe23ffe28eb0c37a4e83deacd4ec8e94624a2c8de151ba6b41b58f9207e5c164 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/parser@npm:7.18.0" +"@typescript-eslint/parser@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/parser@npm:8.71.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + debug: "npm:^4.4.3" peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/36b00e192a96180220ba100fcce3c777fc3e61a6edbdead4e6e75a744d9f0cbe3fabb5f1c94a31cce6b28a4e4d5de148098eec01296026c3c8e16f7f0067cb1e + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/8ce699481f3cec81292889f77f1cffbef68d5f011b0fe1f71150d973794b6d2da89971b80b94824d7fa8bc54ff007a5e632ad6cfb66c595ce8fc1b852cac0c10 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/scope-manager@npm:5.62.0" +"@typescript-eslint/project-service@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/project-service@npm:8.71.1" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - checksum: 10/e827770baa202223bc0387e2fd24f630690809e460435b7dc9af336c77322290a770d62bd5284260fa881c86074d6a9fd6c97b07382520b115f6786b8ed499da + "@typescript-eslint/tsconfig-utils": "npm:^8.71.1" + "@typescript-eslint/types": "npm:^8.71.1" + debug: "npm:^4.4.3" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/9de11189629df886d456d2e80d1541060e5598f512ba42231953445a94764aa863fbc32b652735ee0694543fd6b0012b0807cda6b92d751a46fcd5fbcb481e3b languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/scope-manager@npm:7.18.0" +"@typescript-eslint/scope-manager@npm:8.71.1, @typescript-eslint/scope-manager@npm:^8.58.0": + version: 8.71.1 + resolution: "@typescript-eslint/scope-manager@npm:8.71.1" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - checksum: 10/9eb2ae5d69d9f723e706c16b2b97744fc016996a5473bed596035ac4d12429b3d24e7340a8235d704efa57f8f52e1b3b37925ff7c2e3384859d28b23a99b8bcc + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + checksum: 10/59b0ee05006c4be44eb939ee8a1c0ed60d79fdabe7211f6adc30989541c306b07934144c51ec454ad8252cbe95ab8b38400ffe123977ae2ce512e76d460e5e98 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.71.1, @typescript-eslint/tsconfig-utils@npm:^8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.71.1" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/7a3a71b00f898d8ef53a3aed992597ae6bc56f8b6310cb8180b8f226979877afcb2628fbdc7a4b6f59db8ced5f6779b1fa684c0785e63a99b545f60de31ece51 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/type-utils@npm:7.18.0" +"@typescript-eslint/type-utils@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/type-utils@npm:8.71.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - debug: "npm:^4.3.4" - ts-api-utils: "npm:^1.3.0" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" + debug: "npm:^4.4.3" + ts-api-utils: "npm:^2.5.0" peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/bcc7958a4ecdddad8c92e17265175773e7dddf416a654c1a391e69cb16e43960b39d37b6ffa349941bf3635e050f0ca7cd8f56ec9dd774168f2bbe7afedc9676 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/56b5b433062b9005c1c627aec3cae4bfe6b3647bb08d826ec82fb4279c5f2c781028ce2e6274d38440eea53d348f393ad6b40a5e82825cf057de32fb813cb2f3 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/types@npm:5.62.0" - checksum: 10/24e8443177be84823242d6729d56af2c4b47bfc664dd411a1d730506abf2150d6c31bdefbbc6d97c8f91043e3a50e0c698239dcb145b79bb6b0c34469aaf6c45 +"@typescript-eslint/types@npm:8.71.1, @typescript-eslint/types@npm:^8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/types@npm:8.71.1" + checksum: 10/e719c89af197092fe69bee725582013e57b661d14f2edbdf0637811216e207139876d57631708d544ede41e52b1a01200e0511c8d9c46742d408cc70f3edc7a1 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/types@npm:7.18.0" - checksum: 10/0e30c73a3cc3c67dd06360a5a12fd12cee831e4092750eec3d6c031bdc4feafcb0ab1d882910a73e66b451a4f6e1dd015e9e2c4d45bf6bf716a474e5d123ddf0 +"@typescript-eslint/typescript-estree@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.71.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.71.1" + "@typescript-eslint/tsconfig-utils": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/visitor-keys": "npm:8.71.1" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10/73cd8debfea2ffe582f689a615cdc875f0e97f0430eef55db7158443b37bedbf1ed76559e7ddfd445ad9b4d5de9cee3afe54dda1512cca0d4e31d1dcc6a12c41 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" +"@typescript-eslint/utils@npm:8.71.1, @typescript-eslint/utils@npm:^8.58.0": + version: 8.71.1 + resolution: "@typescript-eslint/utils@npm:8.71.1" dependencies: - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/visitor-keys": "npm:5.62.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/06c975eb5f44b43bd19fadc2e1023c50cf87038fe4c0dd989d4331c67b3ff509b17fa60a3251896668ab4d7322bdc56162a9926971218d2e1a1874d2bef9a52e + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.71.1" + "@typescript-eslint/types": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/8427c5634502be65a149cdc1681986fc306332f2309fc6525d85e3b44d5b35fd2d35ee51989a71277d722455a06455154dc267796218723af384776d6b2f289e languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" +"@typescript-eslint/visitor-keys@npm:8.71.1": + version: 8.71.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.71.1" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - debug: "npm:^4.3.4" - globby: "npm:^11.1.0" - is-glob: "npm:^4.0.3" - minimatch: "npm:^9.0.4" - semver: "npm:^7.6.0" - ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: + "@typescript-eslint/types": "npm:8.71.1" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10/9abc7b1a266eb65b16ac16d99e334d06e0539241e5ae9b6721a11a6a1d2736a9f564dc5e5dc37e7d0bfce5e260da6495bab9d594a1317d01624d239286bd12c2 + languageName: node + linkType: hard + +"@typescript/native@npm:typescript@7.0.2": + version: 7.0.2 + resolution: "typescript@npm:7.0.2" + dependencies: + "@typescript/typescript-aix-ppc64": "npm:7.0.2" + "@typescript/typescript-darwin-arm64": "npm:7.0.2" + "@typescript/typescript-darwin-x64": "npm:7.0.2" + "@typescript/typescript-freebsd-arm64": "npm:7.0.2" + "@typescript/typescript-freebsd-x64": "npm:7.0.2" + "@typescript/typescript-linux-arm": "npm:7.0.2" + "@typescript/typescript-linux-arm64": "npm:7.0.2" + "@typescript/typescript-linux-loong64": "npm:7.0.2" + "@typescript/typescript-linux-mips64el": "npm:7.0.2" + "@typescript/typescript-linux-ppc64": "npm:7.0.2" + "@typescript/typescript-linux-riscv64": "npm:7.0.2" + "@typescript/typescript-linux-s390x": "npm:7.0.2" + "@typescript/typescript-linux-x64": "npm:7.0.2" + "@typescript/typescript-netbsd-arm64": "npm:7.0.2" + "@typescript/typescript-netbsd-x64": "npm:7.0.2" + "@typescript/typescript-openbsd-arm64": "npm:7.0.2" + "@typescript/typescript-openbsd-x64": "npm:7.0.2" + "@typescript/typescript-sunos-x64": "npm:7.0.2" + "@typescript/typescript-win32-arm64": "npm:7.0.2" + "@typescript/typescript-win32-x64": "npm:7.0.2" + dependenciesMeta: + "@typescript/typescript-aix-ppc64": + optional: true + "@typescript/typescript-darwin-arm64": + optional: true + "@typescript/typescript-darwin-x64": + optional: true + "@typescript/typescript-freebsd-arm64": + optional: true + "@typescript/typescript-freebsd-x64": + optional: true + "@typescript/typescript-linux-arm": + optional: true + "@typescript/typescript-linux-arm64": + optional: true + "@typescript/typescript-linux-loong64": + optional: true + "@typescript/typescript-linux-mips64el": + optional: true + "@typescript/typescript-linux-ppc64": + optional: true + "@typescript/typescript-linux-riscv64": + optional: true + "@typescript/typescript-linux-s390x": + optional: true + "@typescript/typescript-linux-x64": + optional: true + "@typescript/typescript-netbsd-arm64": + optional: true + "@typescript/typescript-netbsd-x64": optional: true - checksum: 10/b01e66235a91aa4439d02081d4a5f8b4a7cf9cb24f26b334812f657e3c603493e5f41e5c1e89cf4efae7d64509fa1f73affc16afc5e15cb7f83f724577c82036 + "@typescript/typescript-openbsd-arm64": + optional: true + "@typescript/typescript-openbsd-x64": + optional: true + "@typescript/typescript-sunos-x64": + optional: true + "@typescript/typescript-win32-arm64": + optional: true + "@typescript/typescript-win32-x64": + optional: true + bin: + tsc: bin/tsc + checksum: 10/b0179005349b43dc1febb35c4e79162cdf89b84eae60f6deac142429109041e07582e69a6aacf5a897e085869686d4512ea444a10acf5b5aa2b60910f82a19ca languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/utils@npm:7.18.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - peerDependencies: - eslint: ^8.56.0 - checksum: 10/f43fedb4f4d2e3836bdf137889449063a55c0ece74fdb283929cd376197b992313be8ef4df920c1c801b5c3076b92964c84c6c3b9b749d263b648d0011f5926e +"@typescript/old@npm:typescript@^6, typescript@npm:>=5 <6.1.0": + version: 6.0.3 + resolution: "typescript@npm:6.0.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/0ef2357a4cffd916b52b683a021cdab0f81eea4e9aa35f2d254581c9a5106da02224e3392e1b0ed42b7a48f80c966e5f52b8e1a27941fa0523c1705a9c2e0330 languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.10.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" - semver: "npm:^7.3.7" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10/15ef13e43998a082b15f85db979f8d3ceb1f9ce4467b8016c267b1738d5e7cdb12aa90faf4b4e6dd6486c236cf9d33c463200465cf25ff997dbc0f12358550a1 +"@typescript/typescript-aix-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-aix-ppc64@npm:7.0.2" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" - dependencies: - "@typescript-eslint/types": "npm:5.62.0" - eslint-visitor-keys: "npm:^3.3.0" - checksum: 10/dc613ab7569df9bbe0b2ca677635eb91839dfb2ca2c6fa47870a5da4f160db0b436f7ec0764362e756d4164e9445d49d5eb1ff0b87f4c058946ae9d8c92eb388 +"@typescript/typescript-darwin-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-arm64@npm:7.0.2" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" - dependencies: - "@typescript-eslint/types": "npm:7.18.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/b7cfe6fdeae86c507357ac6b2357813c64fb2fbf1aaf844393ba82f73a16e2599b41981b34200d9fc7765d70bc3a8181d76b503051e53f04bcb7c9afef637eab +"@typescript/typescript-darwin-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-darwin-x64@npm:7.0.2" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 10/c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 +"@typescript/typescript-freebsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-arm64@npm:7.0.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-freebsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-freebsd-x64@npm:7.0.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm64@npm:7.0.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-arm@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-arm@npm:7.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@typescript/typescript-linux-loong64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-loong64@npm:7.0.2" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-mips64el@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-mips64el@npm:7.0.2" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@typescript/typescript-linux-ppc64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-ppc64@npm:7.0.2" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-riscv64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-riscv64@npm:7.0.2" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@typescript/typescript-linux-s390x@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-s390x@npm:7.0.2" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@typescript/typescript-linux-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-linux-x64@npm:7.0.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-arm64@npm:7.0.2" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-netbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-netbsd-x64@npm:7.0.2" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-arm64@npm:7.0.2" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-openbsd-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-openbsd-x64@npm:7.0.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-sunos-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-sunos-x64@npm:7.0.2" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-arm64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-arm64@npm:7.0.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@typescript/typescript-win32-x64@npm:7.0.2": + version: 7.0.2 + resolution: "@typescript/typescript-win32-x64@npm:7.0.2" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -7999,6 +6971,28 @@ __metadata: languageName: node linkType: hard +"@vitest/eslint-plugin@npm:1.6.27": + version: 1.6.27 + resolution: "@vitest/eslint-plugin@npm:1.6.27" + dependencies: + "@typescript-eslint/scope-manager": "npm:^8.58.0" + "@typescript-eslint/utils": "npm:^8.58.0" + peerDependencies: + "@typescript-eslint/eslint-plugin": "*" + eslint: ">=8.57.0" + typescript: ">=5.0.0" + vitest: "*" + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + typescript: + optional: true + vitest: + optional: true + checksum: 10/4f5795107fa79bf2d95d7b2600e1508946235c6e0779dc0ff8a650f746d707b4320db8c6ded382986947b4cd28df6514b05f4202126df149e2980eb3e04fc35b + languageName: node + linkType: hard + "@vitest/expect@npm:4.1.11": version: 4.1.11 resolution: "@vitest/expect@npm:4.1.11" @@ -8548,187 +7542,103 @@ __metadata: linkType: hard "@walletconnect/window-metadata@npm:1.0.1": - version: 1.0.1 - resolution: "@walletconnect/window-metadata@npm:1.0.1" - dependencies: - "@walletconnect/window-getters": "npm:^1.0.1" - tslib: "npm:1.14.1" - checksum: 10/cf322e0860c4448cefcd81f34bc6d49d1a235a81e74a6146baefb74e47cf6c3c8050b65e534a3dc13f8d2aed3fc59732ccf48d5a01b5b23e08e1847fcffa950c - languageName: node - linkType: hard - -"@yuku-codegen/binding-android-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-android-arm64@npm:0.8.7" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@yuku-codegen/binding-darwin-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-darwin-arm64@npm:0.8.7" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@yuku-codegen/binding-darwin-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-darwin-x64@npm:0.8.7" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@yuku-codegen/binding-freebsd-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-freebsd-x64@npm:0.8.7" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-arm-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-arm-gnu@npm:0.8.7" - conditions: os=linux & cpu=arm & libc=glibc - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-arm-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-arm-musl@npm:0.8.7" - conditions: os=linux & cpu=arm & libc=musl - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-arm64-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-arm64-gnu@npm:0.8.7" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-arm64-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-arm64-musl@npm:0.8.7" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-x64-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-x64-gnu@npm:0.8.7" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@yuku-codegen/binding-linux-x64-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-linux-x64-musl@npm:0.8.7" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@yuku-codegen/binding-win32-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-win32-arm64@npm:0.8.7" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@yuku-codegen/binding-win32-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-codegen/binding-win32-x64@npm:0.8.7" - conditions: os=win32 & cpu=x64 + version: 1.0.1 + resolution: "@walletconnect/window-metadata@npm:1.0.1" + dependencies: + "@walletconnect/window-getters": "npm:^1.0.1" + tslib: "npm:1.14.1" + checksum: 10/cf322e0860c4448cefcd81f34bc6d49d1a235a81e74a6146baefb74e47cf6c3c8050b65e534a3dc13f8d2aed3fc59732ccf48d5a01b5b23e08e1847fcffa950c languageName: node linkType: hard -"@yuku-parser/binding-android-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-android-arm64@npm:0.8.7" +"@yuku-core/binding-android-arm64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-android-arm64@npm:0.19.0" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@yuku-parser/binding-darwin-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-darwin-arm64@npm:0.8.7" +"@yuku-core/binding-darwin-arm64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-darwin-arm64@npm:0.19.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@yuku-parser/binding-darwin-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-darwin-x64@npm:0.8.7" +"@yuku-core/binding-darwin-x64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-darwin-x64@npm:0.19.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@yuku-parser/binding-freebsd-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-freebsd-x64@npm:0.8.7" +"@yuku-core/binding-freebsd-x64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-freebsd-x64@npm:0.19.0" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@yuku-parser/binding-linux-arm-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-arm-gnu@npm:0.8.7" +"@yuku-core/binding-linux-arm-gnu@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-arm-gnu@npm:0.19.0" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@yuku-parser/binding-linux-arm-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-arm-musl@npm:0.8.7" +"@yuku-core/binding-linux-arm-musl@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-arm-musl@npm:0.19.0" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@yuku-parser/binding-linux-arm64-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-arm64-gnu@npm:0.8.7" +"@yuku-core/binding-linux-arm64-gnu@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-arm64-gnu@npm:0.19.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@yuku-parser/binding-linux-arm64-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-arm64-musl@npm:0.8.7" +"@yuku-core/binding-linux-arm64-musl@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-arm64-musl@npm:0.19.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@yuku-parser/binding-linux-x64-gnu@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-x64-gnu@npm:0.8.7" +"@yuku-core/binding-linux-x64-gnu@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-x64-gnu@npm:0.19.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@yuku-parser/binding-linux-x64-musl@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-linux-x64-musl@npm:0.8.7" +"@yuku-core/binding-linux-x64-musl@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-linux-x64-musl@npm:0.19.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@yuku-parser/binding-win32-arm64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-win32-arm64@npm:0.8.7" +"@yuku-core/binding-win32-arm64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-win32-arm64@npm:0.19.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@yuku-parser/binding-win32-x64@npm:0.8.7": - version: 0.8.7 - resolution: "@yuku-parser/binding-win32-x64@npm:0.8.7" +"@yuku-core/binding-win32-x64@npm:0.19.0": + version: 0.19.0 + resolution: "@yuku-core/binding-win32-x64@npm:0.19.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@yuku-toolchain/types@npm:^0.8.7": - version: 0.8.7 - resolution: "@yuku-toolchain/types@npm:0.8.7" - checksum: 10/04b1701bb1f60d30b113be7b2553dc2cde498e175c7eaf4dc44f88c659328d47da4a2841761076c6ef22c40e2ca8c8600c8f97fe6c6d11bfe369a0b2bf4fb2be +"@yuku-toolchain/types@npm:^0.19.0": + version: 0.19.0 + resolution: "@yuku-toolchain/types@npm:0.19.0" + checksum: 10/5baa9d9d019710ffb0d5620e1d08f016e4298ee762fbc64319bbe81fe2796f598e831216cd8669586e8492efa8d76092fb50332d49aa5e7ff59439e1dc70ec1c languageName: node linkType: hard @@ -8799,7 +7709,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.9.0": +"acorn@npm:^8.0.4": version: 8.11.3 resolution: "acorn@npm:8.11.3" bin: @@ -8808,6 +7718,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.16.0": + version: 8.19.0 + resolution: "acorn@npm:8.19.0" + bin: + acorn: bin/acorn + checksum: 10/99307d577b38d6a441cd478456633b5b669d32bc722633ff84f1f3c88d361735d7cf01d04ecbf1113c70f1f39e5ceceb95cd5bf93b15bacaddc8fca1ea5e7496 + languageName: node + linkType: hard + "agent-base@npm:6": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -8884,7 +7803,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.12.5": version: 6.14.0 resolution: "ajv@npm:6.14.0" dependencies: @@ -8896,6 +7815,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^6.14.0": + version: 6.15.0 + resolution: "ajv@npm:6.15.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10/0916dda09c152fb5857bc1cc7ce61718e9cec5b7faeff44a74f5e324eed8a556e1a84856724ea322a067b436ecad9f74ac8295fd395449788cca52f0c25bd5fb + languageName: node + linkType: hard + "ajv@npm:^8.0.0, ajv@npm:^8.9.0": version: 8.18.0 resolution: "ajv@npm:8.18.0" @@ -8949,13 +7880,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^5.0.0": - version: 5.2.0 - resolution: "ansi-styles@npm:5.2.0" - checksum: 10/d7f4e97ce0623aea6bc0d90dcd28881ee04cba06c570b97fd3391bd7a268eedfd9d5e2dd4fdcbdd82b8105df5faf6f24aaedc08eaf3da898e702db5948f63469 - languageName: node - linkType: hard - "ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": version: 6.2.3 resolution: "ansi-styles@npm:6.2.3" @@ -8963,13 +7887,6 @@ __metadata: languageName: node linkType: hard -"ansis@npm:^4.3.1": - version: 4.3.1 - resolution: "ansis@npm:4.3.1" - checksum: 10/c3ed79aaa76fc6c419de13b2f31845ba875b1f7d1b398f17ccbd25357c9398cfc58ec5d6707710d068a3bfaf6f3121926455dace8a4853ea0a1847aee07e8072 - languageName: node - linkType: hard - "any-promise@npm:^1.0.0": version: 1.3.0 resolution: "any-promise@npm:1.3.0" @@ -8977,7 +7894,7 @@ __metadata: languageName: node linkType: hard -"anymatch@npm:^3.1.3, anymatch@npm:~3.1.2": +"anymatch@npm:^3.1.3": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -9015,15 +7932,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" - dependencies: - deep-equal: "npm:^2.0.5" - checksum: 10/e5da608a7c4954bfece2d879342b6c218b6b207e2d9e5af270b5e38ef8418f02d122afdc948b68e32649b849a38377785252059090d66fa8081da95d1609c0d2 - languageName: node - linkType: hard - "aria-query@npm:^5.3.2": version: 5.3.2 resolution: "aria-query@npm:5.3.2" @@ -9045,17 +7953,7 @@ __metadata: languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.0, array-buffer-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "array-buffer-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.5" - is-array-buffer: "npm:^3.0.4" - checksum: 10/53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e - languageName: node - linkType: hard - -"array-buffer-byte-length@npm:^1.0.2": +"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "array-buffer-byte-length@npm:1.0.2" dependencies: @@ -9072,39 +7970,19 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6": - version: 3.1.7 - resolution: "array-includes@npm:3.1.7" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - get-intrinsic: "npm:^1.2.1" - is-string: "npm:^1.0.7" - checksum: 10/856a8be5d118967665936ad33ff3b07adfc50b06753e596e91fb80c3da9b8c022e92e3cc6781156d6ad95db7109b9f603682c7df2d6a529ed01f7f6b39a4a360 - languageName: node - linkType: hard - -"array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": - version: 3.1.9 - resolution: "array-includes@npm:3.1.9" +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": + version: 3.2.0 + resolution: "array-includes@npm:3.2.0" dependencies: - call-bind: "npm:^1.0.8" + call-bind: "npm:^1.0.9" call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.24.0" - es-object-atoms: "npm:^1.1.1" - get-intrinsic: "npm:^1.3.0" + es-abstract: "npm:^1.24.2" + es-object-atoms: "npm:^1.1.2" + es-shim-unscopables: "npm:^1.1.0" is-string: "npm:^1.1.1" math-intrinsics: "npm:^1.1.0" - checksum: 10/8bfe9a58df74f326b4a76b04ee05c13d871759e888b4ee8f013145297cf5eb3c02cfa216067ebdaac5d74eb9763ac5cad77cdf2773b8ab475833701e032173aa - languageName: node - linkType: hard - -"array-union@npm:^2.1.0": - version: 2.1.0 - resolution: "array-union@npm:2.1.0" - checksum: 10/5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + checksum: 10/c6b00774aa3f0100dbc5443722b69b0aa7ff5e31e28d2fc9ac69adc394c9fba4bc5cfea292bfbb20369a9657a8a67e0e9a128863cc0f9c426852e7cb11f6715e languageName: node linkType: hard @@ -9137,19 +8015,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.3.1": - version: 1.3.2 - resolution: "array.prototype.flat@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/d9d2f6f27584de92ec7995bc931103e6de722cd2498bdbfc4cba814fc3e52f056050a93be883018811f7c0a35875f5056584a0e940603a5e5934f0279896aebe - languageName: node - linkType: hard - -"array.prototype.flat@npm:^1.3.3": +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flat@npm:1.3.3" dependencies: @@ -9161,19 +8027,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flatmap@npm:^1.3.2": - version: 1.3.2 - resolution: "array.prototype.flatmap@npm:1.3.2" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - es-shim-unscopables: "npm:^1.0.0" - checksum: 10/33f20006686e0cbe844fde7fd290971e8366c6c5e3380681c2df15738b1df766dd02c7784034aeeb3b037f65c496ee54de665388288edb323a2008bb550f77ea - languageName: node - linkType: hard - -"array.prototype.flatmap@npm:^1.3.3": +"array.prototype.flatmap@npm:^1.3.2, array.prototype.flatmap@npm:^1.3.3": version: 1.3.3 resolution: "array.prototype.flatmap@npm:1.3.3" dependencies: @@ -9198,22 +8052,6 @@ __metadata: languageName: node linkType: hard -"arraybuffer.prototype.slice@npm:^1.0.3": - version: 1.0.3 - resolution: "arraybuffer.prototype.slice@npm:1.0.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.22.3" - es-errors: "npm:^1.2.1" - get-intrinsic: "npm:^1.2.3" - is-array-buffer: "npm:^3.0.4" - is-shared-array-buffer: "npm:^1.0.2" - checksum: 10/0221f16c1e3ec7b67da870ee0e1f12b825b5f9189835392b59a22990f715827561a4f4cd5330dc7507de272d8df821be6cd4b0cb569babf5ea4be70e365a2f3d - languageName: node - linkType: hard - "arraybuffer.prototype.slice@npm:^1.0.4": version: 1.0.4 resolution: "arraybuffer.prototype.slice@npm:1.0.4" @@ -9304,9 +8142,9 @@ __metadata: linkType: hard "axe-core@npm:^4.10.0": - version: 4.13.0 - resolution: "axe-core@npm:4.13.0" - checksum: 10/b9319bedc705fde00e4abd981d8724202cc20102e4ae6d8edfde33cb5265e0fb8f67f32adcb4ad33fbd4a2c8d7ad7ef5af1d933d9ad859bed90e3eae0ee8c52f + version: 4.14.0 + resolution: "axe-core@npm:4.14.0" + checksum: 10/b41f9c5fb670b3e1812ba203b17570efa026071e6c722cd8384bacbe5f2be1578fc5d7544acf06df7758eb755c7d23629df922e86cc0655d656784157c0d8df5 languageName: node linkType: hard @@ -9340,21 +8178,6 @@ __metadata: languageName: node linkType: hard -"babel-loader@npm:8.4.1": - version: 8.4.1 - resolution: "babel-loader@npm:8.4.1" - dependencies: - find-cache-dir: "npm:^3.3.1" - loader-utils: "npm:^2.0.4" - make-dir: "npm:^3.1.0" - schema-utils: "npm:^2.6.5" - peerDependencies: - "@babel/core": ^7.0.0 - webpack: ">=2" - checksum: 10/b54ae3796a351e5b5186cd7a8d53a902b679a33a187424c2858e385850142139a4343524c9fddd0eb4356250e51e67e47a9efeef79d01e132976c406212cba1d - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.15": version: 0.4.17 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.17" @@ -9391,20 +8214,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-styled-components@npm:1.13.3": - version: 1.13.3 - resolution: "babel-plugin-styled-components@npm:1.13.3" - dependencies: - "@babel/helper-annotate-as-pure": "npm:^7.15.4" - "@babel/helper-module-imports": "npm:^7.15.4" - babel-plugin-syntax-jsx: "npm:^6.18.0" - lodash: "npm:^4.17.11" - peerDependencies: - styled-components: ">= 2" - checksum: 10/27d3adc83a777dd497a4f192f9737404da8425880ed354ce08951ff1ff64b2a0a22f0c113b842f8d90426f34eb8f14dbd892c2aa67c5b6a791f4ee024782db2f - languageName: node - linkType: hard - "babel-plugin-styled-components@npm:>= 1.12.0": version: 2.1.4 resolution: "babel-plugin-styled-components@npm:2.1.4" @@ -9420,13 +8229,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-syntax-jsx@npm:^6.18.0": - version: 6.18.0 - resolution: "babel-plugin-syntax-jsx@npm:6.18.0" - checksum: 10/0c7ce5b81d6cfc01a7dd7a76a9a8f090ee02ba5c890310f51217ef1a7e6163fb7848994bbc14fd560117892e82240df9c7157ad0764da67ca5f2afafb73a7d27 - languageName: node - linkType: hard - "balanced-match@npm:^1.0.0": version: 1.0.2 resolution: "balanced-match@npm:1.0.2" @@ -9480,6 +8282,15 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.11.26": + version: 2.11.28 + resolution: "baseline-browser-mapping@npm:2.11.28" + bin: + baseline-browser-mapping: dist/cli.cjs + checksum: 10/8561ad5d30b36e17d1c2b7c6e492eb4a6792d3441335669f7e95806149d759b6af3fc9f151586a65044636e65cf848b15c83fdd34c86d22d0da970c905fc7ac8 + languageName: node + linkType: hard + "before-after-hook@npm:^4.0.0": version: 4.0.0 resolution: "before-after-hook@npm:4.0.0" @@ -9521,13 +8332,6 @@ __metadata: languageName: node linkType: hard -"binary-extensions@npm:^2.0.0": - version: 2.3.0 - resolution: "binary-extensions@npm:2.3.0" - checksum: 10/bcad01494e8a9283abf18c1b967af65ee79b0c6a9e6fcfafebfe91dbe6e0fc7272bafb73389e198b310516ae04f7ad17d79aacf6cb4c0d5d5202a7e2e52c7d98 - languageName: node - linkType: hard - "binary-extensions@npm:^3.0.0": version: 3.1.0 resolution: "binary-extensions@npm:3.1.0" @@ -9641,7 +8445,16 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.3, braces@npm:~3.0.2": +"brace-expansion@npm:^5.0.8": + version: 5.0.12 + resolution: "brace-expansion@npm:5.0.12" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10/65b550f1836e3b43f512f12afbc3be96616eee5c353e16d70181b7dffec8c08beabffb51d69a3bbdb27d675840725cbab025fda9d10716b5cda7dd864dc7bc4a + languageName: node + linkType: hard + +"braces@npm:^3.0.3": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -9672,6 +8485,21 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.28.7, browserslist@npm:^4.29.1": + version: 4.29.3 + resolution: "browserslist@npm:4.29.3" + dependencies: + baseline-browser-mapping: "npm:^2.11.26" + caniuse-lite: "npm:^1.0.30001813" + electron-to-chromium: "npm:^1.5.439" + node-releases: "npm:^2.0.57" + update-browserslist-db: "npm:^1.3.3" + bin: + browserslist: cli.js + checksum: 10/9649d4d73fff11f7c0b19948f08f9f287c184feb0965ac0b489cee7e1a9f430e747809db0d6014a30fdbcc42755e7a4dd047dfd7e28f62982072dcd0f8291eb0 + languageName: node + linkType: hard + "bs58@npm:6.0.0": version: 6.0.0 resolution: "bs58@npm:6.0.0" @@ -9734,10 +8562,24 @@ __metadata: languageName: node linkType: hard -"cac@npm:^7.0.0": - version: 7.0.0 - resolution: "cac@npm:7.0.0" - checksum: 10/1ada3b090403d0051619b1519c21db1cb0b32c7772d6c8782cc55c5349caac9efbb1076ba513c5975331ff0bdb104e2be9421fd3ff6c0ef5db9d58a04a4aa6f5 +"builtin-modules@npm:^5.0.0": + version: 5.4.0 + resolution: "builtin-modules@npm:5.4.0" + checksum: 10/325982b68c792cc22694209f5a798a8bcb80ea8c24bcabd683b9559977768cea6406fa773172eaa60f68792ed41d9bc1c7bd2dc2a1e7d1b54da9eadeb6a45995 + languageName: node + linkType: hard + +"bytes@npm:^3.1.2": + version: 3.1.2 + resolution: "bytes@npm:3.1.2" + checksum: 10/a10abf2ba70c784471d6b4f58778c0beeb2b5d405148e66affa91f23a9f13d07603d0a0354667310ae1d6dc141474ffd44e2a074be0f6e2254edb8fc21445388 + languageName: node + linkType: hard + +"cac@npm:^7.0.1": + version: 7.1.0 + resolution: "cac@npm:7.1.0" + checksum: 10/2be44f8fd9e60ad21c0f2e2aad914c9666e0a14045b89b90696f79140fcb3ffd296626f3807d360603efa2c488bc15c61774d2573593a543966b0733660cc2b3 languageName: node linkType: hard @@ -9779,7 +8621,20 @@ __metadata: languageName: node linkType: hard -"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": +"cacheable@npm:^2.5.0": + version: 2.5.0 + resolution: "cacheable@npm:2.5.0" + dependencies: + "@cacheable/memory": "npm:^2.2.0" + "@cacheable/utils": "npm:^2.5.0" + hookified: "npm:^1.15.0" + keyv: "npm:^5.6.0" + qified: "npm:^0.10.1" + checksum: 10/216a896e17dfa9c598a69e2fff31216126e94286f6c0ceb1bfab1d34e6c1a8791e8dc34dbd28660ec72a84f1d370c3733a9fc481e00a5512fd4e0cfc35775db6 + languageName: node + linkType: hard + +"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" dependencies: @@ -9789,19 +8644,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": - version: 1.0.8 - resolution: "call-bind@npm:1.0.8" - dependencies: - call-bind-apply-helpers: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - set-function-length: "npm:^1.2.2" - checksum: 10/659b03c79bbfccf0cde3a79e7d52570724d7290209823e1ca5088f94b52192dc1836b82a324d0144612f816abb2f1734447438e38d9dafe0b3f82c2a1b9e3bce - languageName: node - linkType: hard - -"call-bind@npm:^1.0.9": +"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8, call-bind@npm:^1.0.9": version: 1.0.9 resolution: "call-bind@npm:1.0.9" dependencies: @@ -9865,6 +8708,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001813": + version: 1.0.30001815 + resolution: "caniuse-lite@npm:1.0.30001815" + checksum: 10/975bc77d07201295d56ce25c0f796bede1b7c2447c46c4a4b1819cc67de3a505897a3e22926bb5195cf5cd4c31c32aed90fa2d8533a10e379c0a6a16916a8380 + languageName: node + linkType: hard + "centrifuge@npm:^5.3.5": version: 5.7.0 resolution: "centrifuge@npm:5.7.0" @@ -9910,6 +8760,13 @@ __metadata: languageName: node linkType: hard +"change-case@npm:^5.4.4": + version: 5.4.4 + resolution: "change-case@npm:5.4.4" + checksum: 10/446e5573f3c854290a91292afef92b957d2e43a928260c91989b482aa860caaa29711b6725fc40c200af68061cbab357b033446d16a17bc5c553636994074e92 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -9931,25 +8788,6 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.6.0": - version: 3.6.0 - resolution: "chokidar@npm:3.6.0" - dependencies: - anymatch: "npm:~3.1.2" - braces: "npm:~3.0.2" - fsevents: "npm:~2.3.2" - glob-parent: "npm:~5.1.2" - is-binary-path: "npm:~2.1.0" - is-glob: "npm:~4.0.1" - normalize-path: "npm:~3.0.0" - readdirp: "npm:~3.6.0" - dependenciesMeta: - fsevents: - optional: true - checksum: 10/c327fb07704443f8d15f7b4a7ce93b2f0bc0e6cea07ec28a7570aa22cd51fcf0379df589403976ea956c369f25aa82d84561947e227cd925902e1751371658df - languageName: node - linkType: hard - "chokidar@npm:^5.0.0": version: 5.0.0 resolution: "chokidar@npm:5.0.0" @@ -9966,13 +8804,6 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^3.8.0": - version: 3.9.0 - resolution: "ci-info@npm:3.9.0" - checksum: 10/75bc67902b4d1c7b435497adeb91598f6d52a3389398e44294f6601b20cfef32cf2176f7be0eb961d9e085bb333a8a5cae121cb22f81cf238ae7f58eb80e9397 - languageName: node - linkType: hard - "ci-info@npm:^4.0.0, ci-info@npm:^4.4.0": version: 4.4.0 resolution: "ci-info@npm:4.4.0" @@ -9987,12 +8818,10 @@ __metadata: languageName: node linkType: hard -"clean-regexp@npm:^1.0.0": - version: 1.0.0 - resolution: "clean-regexp@npm:1.0.0" - dependencies: - escape-string-regexp: "npm:^1.0.5" - checksum: 10/0b1ce281b07da2463c6882ea2e8409119b6cabbd9f687cdbdcee942c45b2b9049a2084f7b5f228c63ef9f21e722963ae0bfe56a735dbdbdd92512867625a7e40 +"classnames@npm:2.5.1": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: 10/58eb394e8817021b153bb6e7d782cfb667e4ab390cb2e9dac2fc7c6b979d1cc2b2a733093955fc5c94aa79ef5c8c89f11ab77780894509be6afbb91dddd79d15 languageName: node linkType: hard @@ -10216,13 +9045,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^6.2.0": - version: 6.2.1 - resolution: "commander@npm:6.2.1" - checksum: 10/25b88c2efd0380c84f7844b39cf18510da7bfc5013692d68cdc65f764a1c34e6c8a36ea6d72b6620e3710a930cf8fab2695bdec2bf7107a0f4fa30a3ef3b7d0e - languageName: node - linkType: hard - "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -10237,13 +9059,6 @@ __metadata: languageName: node linkType: hard -"commondir@npm:^1.0.1": - version: 1.0.1 - resolution: "commondir@npm:1.0.1" - checksum: 10/4620bc4936a4ef12ce7dfcd272bb23a99f2ad68889a4e4ad766c9f8ad21af982511934d6f7050d4a8bde90011b1c15d56e61a1b4576d9913efbf697a20172d6c - languageName: node - linkType: hard - "compare-func@npm:^2.0.0": version: 2.0.0 resolution: "compare-func@npm:2.0.0" @@ -10271,13 +9086,6 @@ __metadata: languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.10": - version: 1.0.11 - resolution: "confusing-browser-globals@npm:1.0.11" - checksum: 10/3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef - languageName: node - linkType: hard - "content-type@npm:^2.0.0": version: 2.0.0 resolution: "content-type@npm:2.0.0" @@ -10367,6 +9175,15 @@ __metadata: languageName: node linkType: hard +"core-js-compat@npm:^3.50.0": + version: 3.50.0 + resolution: "core-js-compat@npm:3.50.0" + dependencies: + browserslist: "npm:^4.28.7" + checksum: 10/491d522653c8e606b9548f030e247fb84c9374f897dd56703691206501d30c51e08f77c69f9a60ec36fc4a9d31495c6bcd5433ac03af5c62c69fe467ebb84b1e + languageName: node + linkType: hard + "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -10448,7 +9265,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -10613,17 +9430,6 @@ __metadata: languageName: node linkType: hard -"data-view-buffer@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-buffer@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/5919a39a18ee919573336158fd162fdf8ada1bc23a139f28543fd45fac48e0ea4a3ad3bfde91de124d4106e65c4a7525f6a84c20ba0797ec890a77a96d13a82a - languageName: node - linkType: hard - "data-view-buffer@npm:^1.0.2": version: 1.0.2 resolution: "data-view-buffer@npm:1.0.2" @@ -10635,17 +9441,6 @@ __metadata: languageName: node linkType: hard -"data-view-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "data-view-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/f33c65e58d8d0432ad79761f2e8a579818d724b5dc6dc4e700489b762d963ab30873c0f1c37d8f2ed12ef51c706d1195f64422856d25f067457aeec50cc40aac - languageName: node - linkType: hard - "data-view-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "data-view-byte-length@npm:1.0.2" @@ -10657,17 +9452,6 @@ __metadata: languageName: node linkType: hard -"data-view-byte-offset@npm:^1.0.0": - version: 1.0.0 - resolution: "data-view-byte-offset@npm:1.0.0" - dependencies: - call-bind: "npm:^1.0.6" - es-errors: "npm:^1.3.0" - is-data-view: "npm:^1.0.1" - checksum: 10/96f34f151bf02affb7b9f98762fb7aca1dd5f4553cb57b80bce750ca609c15d33ca659568ef1d422f7e35680736cbccb893a3d4b012760c758c1446bbdc4c6db - languageName: node - linkType: hard - "data-view-byte-offset@npm:^1.0.1": version: 1.0.1 resolution: "data-view-byte-offset@npm:1.0.1" @@ -10693,7 +9477,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.3": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -10721,32 +9505,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.3 - resolution: "deep-equal@npm:2.2.3" - dependencies: - array-buffer-byte-length: "npm:^1.0.0" - call-bind: "npm:^1.0.5" - es-get-iterator: "npm:^1.1.3" - get-intrinsic: "npm:^1.2.2" - is-arguments: "npm:^1.1.1" - is-array-buffer: "npm:^3.0.2" - is-date-object: "npm:^1.0.5" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.2" - isarray: "npm:^2.0.5" - object-is: "npm:^1.1.5" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.4" - regexp.prototype.flags: "npm:^1.5.1" - side-channel: "npm:^1.0.4" - which-boxed-primitive: "npm:^1.0.2" - which-collection: "npm:^1.0.1" - which-typed-array: "npm:^1.1.13" - checksum: 10/1ce49d0b71d0f14d8ef991a742665eccd488dfc9b3cada069d4d7a86291e591c92d2589c832811dea182b4015736b210acaaebce6184be356c1060d176f5a05f - languageName: node - linkType: hard - "deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -10779,7 +9537,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.1.3, define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -10817,14 +9575,17 @@ __metadata: dependencies: "@babel/core": "npm:^7.29.7" "@coinbase/wallet-sdk": "npm:^4.3.6" + "@lidofinance/lido-app-ui": "npm:1.4.0" "@lidofinance/lido-ethereum-sdk": "npm:4.7.0" "@lidofinance/lido-ui": "npm:^3.18.0" "@metamask/connect-evm": "npm:^2.1.0" "@next/bundle-analyzer": "npm:^14.2.35" + "@reef-knot/ui-lido": "npm:*" + "@reef-knot/ui-lido-legacy": "npm:*" "@safe-global/safe-apps-provider": "npm:^0.18.6" "@safe-global/safe-apps-sdk": "npm:^9.1.0" "@svgr/webpack": "npm:^8.0.1" - "@tanstack/react-query": "npm:^5.29.0" + "@tanstack/react-query": "npm:^5.51.1" "@types/lodash": "npm:^4.17.25" "@types/node": "npm:^17.0.12" "@types/react": "npm:18.2.45" @@ -10845,7 +9606,7 @@ __metadata: tiny-invariant: "npm:^1.3.1" tsconfig: "npm:*" typechain: "npm:^8.3.0" - typescript: "npm:~5.9" + typescript: "npm:@typescript/typescript6@6.0.2" url-loader: "npm:^4.1.1" viem: "npm:2.51.3" wagmi: "npm:^3.6.21" @@ -10866,7 +9627,14 @@ __metadata: languageName: node linkType: hard -"detect-indent@npm:^7.0.1": +"detect-europe-js@npm:^0.1.2": + version: 0.1.2 + resolution: "detect-europe-js@npm:0.1.2" + checksum: 10/3d6dcf6ac451baa3050ff00e05cf1841e208bc4f27c69ec2c8df5fdf2375403cf2911f8059c9c18f258d7e176c8d308e4e0e8552500d0e30a9e95a514366ef13 + languageName: node + linkType: hard + +"detect-indent@npm:^7.0.1, detect-indent@npm:^7.0.2": version: 7.0.2 resolution: "detect-indent@npm:7.0.2" checksum: 10/ef215d1b55a14f677ce03e840973b25362b6f8cd3f566bc82831fa1abb2be6a95423729bc573dc2334b1371ad7be18d9ec67e1a9611b71a04cb6d63f0d8e54cc @@ -10919,22 +9687,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: "npm:^2.0.2" - checksum: 10/b4b28f1df5c563f7d876e7461254a4597b8cabe915abe94d7c5d1633fed263fcf9a85e8d3836591fc2d040108e822b0d32758e5ec1fe31c590dc7e08086e3e48 - languageName: node - linkType: hard - -"dom-accessibility-api@npm:^0.5.9": - version: 0.5.16 - resolution: "dom-accessibility-api@npm:0.5.16" - checksum: 10/377b4a7f9eae0a5d72e1068c369c99e0e4ca17fdfd5219f3abd32a73a590749a267475a59d7b03a891f9b673c27429133a818c44b2e47e32fec024b34274e2ca - languageName: node - linkType: hard - "dom-helpers@npm:^5.0.1": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -11114,6 +9866,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.439": + version: 1.5.452 + resolution: "electron-to-chromium@npm:1.5.452" + checksum: 10/0c256b0f0a48afe69f57f8074319a0777599a429d0b71e895e6bcd6ca5ff979a2f6afa2b3bc57921126dd4e2af1a7fa4c999f5c652a22e5ac54080dcdd31ac4d + languageName: node + linkType: hard + "elliptic@npm:6.5.4": version: 6.5.4 resolution: "elliptic@npm:6.5.4" @@ -11164,10 +9923,10 @@ __metadata: languageName: node linkType: hard -"empathic@npm:^2.0.1": - version: 2.0.1 - resolution: "empathic@npm:2.0.1" - checksum: 10/c5a37b78926e722c38779e5026342350098771fa1cacb52cb808e5329896ab39abb88cd2f1374671d6e5c98aa24cba2534f00da2938d04f11de1a2d012ee75c3 +"empathic@npm:^2.1.0": + version: 2.1.0 + resolution: "empathic@npm:2.1.0" + checksum: 10/8f90322f559a0097c4da7abd177131a2589334a9056e5af9b71c79861b76f4f5b7c8043f93ad6a88f1016b21ee683c0fe3be564b87c8db4bfa9ed360be962aac languageName: node linkType: hard @@ -11225,6 +9984,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^8.1.0": + version: 8.1.0 + resolution: "entities@npm:8.1.0" + checksum: 10/bd2fadbcabcf2cbd5de6b8155289acec9394d004fc095b9c7b3fdb4135468d8823a6de12275b07085e5dc077a142ede24e71098ffeb064000312d2a6960330a2 + languageName: node + linkType: hard + "env-ci@npm:^11.0.0, env-ci@npm:^11.2.0": version: 11.2.0 resolution: "env-ci@npm:11.2.0" @@ -11277,7 +10043,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0, es-abstract@npm:^1.24.2": +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.2": version: 1.24.2 resolution: "es-abstract@npm:1.24.2" dependencies: @@ -11339,60 +10105,6 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2": - version: 1.23.2 - resolution: "es-abstract@npm:1.23.2" - dependencies: - array-buffer-byte-length: "npm:^1.0.1" - arraybuffer.prototype.slice: "npm:^1.0.3" - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - data-view-buffer: "npm:^1.0.1" - data-view-byte-length: "npm:^1.0.1" - data-view-byte-offset: "npm:^1.0.0" - es-define-property: "npm:^1.0.0" - es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-set-tostringtag: "npm:^2.0.3" - es-to-primitive: "npm:^1.2.1" - function.prototype.name: "npm:^1.1.6" - get-intrinsic: "npm:^1.2.4" - get-symbol-description: "npm:^1.0.2" - globalthis: "npm:^1.0.3" - gopd: "npm:^1.0.1" - has-property-descriptors: "npm:^1.0.2" - has-proto: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - hasown: "npm:^2.0.2" - internal-slot: "npm:^1.0.7" - is-array-buffer: "npm:^3.0.4" - is-callable: "npm:^1.2.7" - is-data-view: "npm:^1.0.1" - is-negative-zero: "npm:^2.0.3" - is-regex: "npm:^1.1.4" - is-shared-array-buffer: "npm:^1.0.3" - is-string: "npm:^1.0.7" - is-typed-array: "npm:^1.1.13" - is-weakref: "npm:^1.0.2" - object-inspect: "npm:^1.13.1" - object-keys: "npm:^1.1.1" - object.assign: "npm:^4.1.5" - regexp.prototype.flags: "npm:^1.5.2" - safe-array-concat: "npm:^1.1.2" - safe-regex-test: "npm:^1.0.3" - string.prototype.trim: "npm:^1.2.9" - string.prototype.trimend: "npm:^1.0.8" - string.prototype.trimstart: "npm:^1.0.7" - typed-array-buffer: "npm:^1.0.2" - typed-array-byte-length: "npm:^1.0.1" - typed-array-byte-offset: "npm:^1.0.2" - typed-array-length: "npm:^1.0.5" - unbox-primitive: "npm:^1.0.2" - which-typed-array: "npm:^1.1.15" - checksum: 10/f8fa0ef674b176f177f637f1af13fb895d10306e1eb1f57dc48a5aa64a643da307f96b222054ff76f3fd9029983295192c55fc54169f464ad2fcee992c5b7310 - languageName: node - linkType: hard - "es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": version: 1.0.1 resolution: "es-define-property@npm:1.0.1" @@ -11400,30 +10112,13 @@ __metadata: languageName: node linkType: hard -"es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": +"es-errors@npm:^1.3.0": version: 1.3.0 resolution: "es-errors@npm:1.3.0" checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 languageName: node linkType: hard -"es-get-iterator@npm:^1.1.3": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.1.3" - has-symbols: "npm:^1.0.3" - is-arguments: "npm:^1.1.1" - is-map: "npm:^2.0.2" - is-set: "npm:^2.0.2" - is-string: "npm:^1.0.7" - isarray: "npm:^2.0.5" - stop-iteration-iterator: "npm:^1.0.0" - checksum: 10/bc2194befbe55725f9489098626479deee3c801eda7e83ce0dff2eb266a28dc808edb9b623ff01d31ebc1328f09d661333d86b601036692c2e3c1a6942319433 - languageName: node - linkType: hard - "es-iterator-helpers@npm:^1.2.1": version: 1.4.0 resolution: "es-iterator-helpers@npm:1.4.0" @@ -11473,28 +10168,19 @@ __metadata: languageName: node linkType: hard -"es-set-tostringtag@npm:^2.0.3, es-set-tostringtag@npm:^2.1.0": +"es-set-tostringtag@npm:^2.1.0": version: 2.1.0 resolution: "es-set-tostringtag@npm:2.1.0" dependencies: es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.6" - has-tostringtag: "npm:^1.0.2" - hasown: "npm:^2.0.2" - checksum: 10/86814bf8afbcd8966653f731415888019d4bc4aca6b6c354132a7a75bb87566751e320369654a101d23a91c87a85c79b178bcf40332839bd347aff437c4fb65f - languageName: node - linkType: hard - -"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" - dependencies: - hasown: "npm:^2.0.0" - checksum: 10/6d3bf91f658a27cc7217cd32b407a0d714393a84d125ad576319b9e83a893bea165cf41270c29e9ceaa56d3cf41608945d7e2a2c31fd51c0009b0c31402b91c7 + get-intrinsic: "npm:^1.2.6" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10/86814bf8afbcd8966653f731415888019d4bc4aca6b6c354132a7a75bb87566751e320369654a101d23a91c87a85c79b178bcf40332839bd347aff437c4fb65f languageName: node linkType: hard -"es-shim-unscopables@npm:^1.1.0": +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": version: 1.1.0 resolution: "es-shim-unscopables@npm:1.1.0" dependencies: @@ -11503,17 +10189,6 @@ __metadata: languageName: node linkType: hard -"es-to-primitive@npm:^1.2.1": - version: 1.2.1 - resolution: "es-to-primitive@npm:1.2.1" - dependencies: - is-callable: "npm:^1.1.4" - is-date-object: "npm:^1.0.1" - is-symbol: "npm:^1.0.2" - checksum: 10/74aeeefe2714cf99bb40cab7ce3012d74e1e2c1bd60d0a913b467b269edde6e176ca644b5ba03a5b865fb044a29bca05671cd445c85ca2cdc2de155d7fc8fe9b - languageName: node - linkType: hard - "es-to-primitive@npm:^1.3.0": version: 1.3.4 resolution: "es-to-primitive@npm:1.3.4" @@ -11673,64 +10348,41 @@ __metadata: languageName: node linkType: hard -"eslint-config-airbnb-base@npm:^15.0.0": - version: 15.0.0 - resolution: "eslint-config-airbnb-base@npm:15.0.0" - dependencies: - confusing-browser-globals: "npm:^1.0.10" - object.assign: "npm:^4.1.2" - object.entries: "npm:^1.1.5" - semver: "npm:^6.3.0" - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - checksum: 10/daa68a1dcb7bff338747a952723b5fa9d159980ec3554c395a4b52a7f7d4f00a45e7b465420eb6d4d87a82cef6361e4cfd6dbb38c2f3f52f2140b6cf13654803 - languageName: node - linkType: hard - -"eslint-config-airbnb@npm:19.0.4": - version: 19.0.4 - resolution: "eslint-config-airbnb@npm:19.0.4" - dependencies: - eslint-config-airbnb-base: "npm:^15.0.0" - object.assign: "npm:^4.1.2" - object.entries: "npm:^1.1.5" - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.28.0 - eslint-plugin-react-hooks: ^4.3.0 - checksum: 10/f2086523cfd20c42fd620c757281bd028aa8ce9dadc7293c5c23ea60947a2d3ca04404ede77b40f5a65250fe3c04502acafc4f2f6946819fe6c257d76d9644e5 - languageName: node - linkType: hard - -"eslint-config-custom@npm:*, eslint-config-custom@workspace:packages/eslint-config-custom": - version: 0.0.0-use.local - resolution: "eslint-config-custom@workspace:packages/eslint-config-custom" - languageName: unknown - linkType: soft - -"eslint-config-prettier@npm:9.1.2": - version: 9.1.2 - resolution: "eslint-config-prettier@npm:9.1.2" +"eslint-config-prettier@npm:10.1.8": + version: 10.1.8 + resolution: "eslint-config-prettier@npm:10.1.8" peerDependencies: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: 10/e4bba2d76df9dc6e2adca2866e544bfd1ff32232fc483743c04cedd93918a90a327b56d4a7e3f9d3fa32d90bd50b034d09df987860260064b18c026b8bbd15aa + checksum: 10/03f8e6ea1a6a9b8f9eeaf7c8c52a96499ec4b275b9ded33331a6cc738ed1d56de734097dbd0091f136f0e84bc197388bd8ec22a52a4658105883f8c8b7d8921a languageName: node linkType: hard -"eslint-config-turbo@npm:2.10.12": - version: 2.10.12 - resolution: "eslint-config-turbo@npm:2.10.12" +"eslint-config-turbo@npm:2.11.7": + version: 2.11.7 + resolution: "eslint-config-turbo@npm:2.11.7" dependencies: - eslint-plugin-turbo: "npm:2.10.12" + eslint-plugin-turbo: "npm:2.11.7" peerDependencies: eslint: ">6.6.0" turbo: ">2.0.0" - checksum: 10/c931e169cacc1d31c03abe6a8d7aa7af1097c04f33c283d627524fa2ddbcd0231f8b40ee48f2fc6714c45c57bd6f63933e2f195456655decfbab4bacbab7f306 + checksum: 10/76902c42ad122472e1d61f47d0d89c2f6e9f63ba67952bdca83ace0b2aa8503618fb0474c6e909aa6fd0521cadb624bf11fe04e31eddcde5f24f8421854a02e4 + languageName: node + linkType: hard + +"eslint-import-context@npm:^0.1.8": + version: 0.1.9 + resolution: "eslint-import-context@npm:0.1.9" + dependencies: + get-tsconfig: "npm:^4.10.1" + stable-hash-x: "npm:^0.2.0" + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + checksum: 10/f0778126bb3aae57c8c68946c71c4418927e9d39f72099b799d9c47a3b5712d6c9166b63ee8be58a020961dcc9216df09c856b825336af375ccbbdeedfc82a99 languageName: node linkType: hard @@ -11745,17 +10397,17 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-typescript@npm:3.10.1": - version: 3.10.1 - resolution: "eslint-import-resolver-typescript@npm:3.10.1" +"eslint-import-resolver-typescript@npm:4.4.5": + version: 4.4.5 + resolution: "eslint-import-resolver-typescript@npm:4.4.5" dependencies: - "@nolyfill/is-core-module": "npm:1.0.39" - debug: "npm:^4.4.0" - get-tsconfig: "npm:^4.10.0" + debug: "npm:^4.4.1" + eslint-import-context: "npm:^0.1.8" + get-tsconfig: "npm:^4.10.1" is-bun-module: "npm:^2.0.0" - stable-hash: "npm:^0.0.5" - tinyglobby: "npm:^0.2.13" - unrs-resolver: "npm:^1.6.2" + stable-hash-x: "npm:^0.2.0" + tinyglobby: "npm:^0.2.14" + unrs-resolver: "npm:^1.7.11" peerDependencies: eslint: "*" eslint-plugin-import: "*" @@ -11765,7 +10417,7 @@ __metadata: optional: true eslint-plugin-import-x: optional: true - checksum: 10/b8d6a9b2045c70f043f722f78c9e65bc0283126f0ad92c8f07473f7647d77f7b1562f765a472f17e06b81897b407091c0ec9f2e4592b158c9fd92d0b0c33de89 + checksum: 10/f889b885abbe8b3517286de7f30289cf9318357b124ef2b92948c77d662901dd6b8fba0dffebedf64fb68a2bee0a416b5ccbf1f67f6502736964f972a72cef8e languageName: node linkType: hard @@ -11822,24 +10474,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jest@npm:27.9.0": - version: 27.9.0 - resolution: "eslint-plugin-jest@npm:27.9.0" - dependencies: - "@typescript-eslint/utils": "npm:^5.10.0" - peerDependencies: - "@typescript-eslint/eslint-plugin": ^5.0.0 || ^6.0.0 || ^7.0.0 - eslint: ^7.0.0 || ^8.0.0 - jest: "*" - peerDependenciesMeta: - "@typescript-eslint/eslint-plugin": - optional: true - jest: - optional: true - checksum: 10/bca54347280c06c56516faea76042134dd74355c2de6c23361ba0e8736ecc01c62b144eea7eda7570ea4f4ee511c583bb8dab00d7153a1bd1740eb77b0038fd4 - languageName: node - linkType: hard - "eslint-plugin-jsx-a11y@npm:6.10.2": version: 6.10.2 resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" @@ -11885,21 +10519,29 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-promise@npm:6.6.0": - version: 6.6.0 - resolution: "eslint-plugin-promise@npm:6.6.0" +"eslint-plugin-promise@npm:7.3.0": + version: 7.3.0 + resolution: "eslint-plugin-promise@npm:7.3.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10/c2b5604efd7e1390c132fcbf06cb2f072c956ffa65c14a991cb74ba1e2327357797239cb5b9b292d5e4010301bb897bd85a6273d7873fb157edc46aa2d95cbd9 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + checksum: 10/9f84fbd033eea686ba3d55c31fade8172a8ea0578b64af1ba22537c05c4bcffac92cc0696325a4adc0f8bad3e65b61e33164b92463be4807235ea0f2f27b93f8 languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:4.6.2": - version: 4.6.2 - resolution: "eslint-plugin-react-hooks@npm:4.6.2" +"eslint-plugin-react-hooks@npm:7.1.1": + version: 7.1.1 + resolution: "eslint-plugin-react-hooks@npm:7.1.1" + dependencies: + "@babel/core": "npm:^7.24.4" + "@babel/parser": "npm:^7.24.4" + hermes-parser: "npm:^0.25.1" + zod: "npm:^3.25.0 || ^4.0.0" + zod-validation-error: "npm:^3.5.0 || ^4.0.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10/5a0680941f34e70cf505bcb6082df31a3e445d193ee95a88ff3483041eb944f4cefdaf7e81b0eb1feb4eeceee8c7c6ddb8a2a6e8c4c0388514a42e16ac7b7a69 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + checksum: 10/9dfe543af9813343f7cc7c5079b02da94a3b4c15df5cefdeef731f220120df26471d0db24c943222d2d9c6b43c3b78faea47ada9acc9dfd9c28492153cbc6902 languageName: node linkType: hard @@ -11931,144 +10573,160 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-sonarjs@npm:0.25.1": - version: 0.25.1 - resolution: "eslint-plugin-sonarjs@npm:0.25.1" +"eslint-plugin-sonarjs@npm:4.2.2": + version: 4.2.2 + resolution: "eslint-plugin-sonarjs@npm:4.2.2" + dependencies: + "@eslint-community/regexpp": "npm:^4.12.2" + "@sonarsource/analyzer-commons-configurations": "npm:^2.31.0-5284" + builtin-modules: "npm:^3.3.0" + bytes: "npm:^3.1.2" + functional-red-black-tree: "npm:^1.0.1" + globals: "npm:^17.12.0" + jsx-ast-utils-x: "npm:^0.1.0" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^10.2.6" + scslre: "npm:^0.3.0" + semver: "npm:^7.8.5" + ts-api-utils: "npm:^2.5.0" + typescript: "npm:>=5 <6.1.0" + yaml: "npm:^2.9.1" peerDependencies: - eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 10/ea94da85493dd005b39c8d55fb4e198d433874e75653136ae7d6042f31f4396ab25665fb264972ac17b891efa84ec0c6cf9fdde315a312b2a87d7e06bcb2148e + eslint: ^8.0.0 || ^9.0.0 || ^10.0.0 + checksum: 10/32ee89cbdb131c8690d4dff5a988d64b2c53132fd958a55b45f740a90cc8df502a03d48be4642af37726339951d675fe9d3f0ff59f8f549120d44eee2cd56022 languageName: node linkType: hard -"eslint-plugin-turbo@npm:2.10.12": - version: 2.10.12 - resolution: "eslint-plugin-turbo@npm:2.10.12" +"eslint-plugin-turbo@npm:2.11.7": + version: 2.11.7 + resolution: "eslint-plugin-turbo@npm:2.11.7" dependencies: dotenv: "npm:16.0.3" peerDependencies: eslint: ">6.6.0" turbo: ">2.0.0" - checksum: 10/04090450cfc39458bd907e0222c725aac1842e8b1cd72bdfce99e2c03ba19314bd08f89185523966353d1d1839f528ff991cbe2fd3c746a9a98f64eb10be0b3a + checksum: 10/88ea7178e929245c144ed4f33c8add1a78ef5ea70c0e239c1e99f7fe2f603f3a0832ceabdaafd156acd94eaae55fb5343902754bd44e2036ef7d3a38a856333d languageName: node linkType: hard -"eslint-plugin-unicorn@npm:48.0.1": - version: 48.0.1 - resolution: "eslint-plugin-unicorn@npm:48.0.1" +"eslint-plugin-unicorn@npm:77.0.0": + version: 77.0.0 + resolution: "eslint-plugin-unicorn@npm:77.0.0" dependencies: - "@babel/helper-validator-identifier": "npm:^7.22.5" - "@eslint-community/eslint-utils": "npm:^4.4.0" - ci-info: "npm:^3.8.0" - clean-regexp: "npm:^1.0.0" - esquery: "npm:^1.5.0" - indent-string: "npm:^4.0.0" - is-builtin-module: "npm:^3.2.1" - jsesc: "npm:^3.0.2" - lodash: "npm:^4.17.21" + "@eslint-community/eslint-utils": "npm:^4.10.1" + "@eslint/css-tree": "npm:^4.1.1" + browserslist: "npm:^4.29.1" + change-case: "npm:^5.4.4" + ci-info: "npm:^4.4.0" + core-js-compat: "npm:^3.50.0" + detect-indent: "npm:^7.0.2" + entities: "npm:^8.1.0" + find-up-simple: "npm:^1.0.1" + globals: "npm:^17.12.0" + identifier-regex: "npm:^1.1.0" + indent-string: "npm:^5.0.0" + is-builtin-module: "npm:^5.0.0" pluralize: "npm:^8.0.0" - read-pkg-up: "npm:^7.0.1" - regexp-tree: "npm:^0.1.27" - regjsparser: "npm:^0.10.0" - semver: "npm:^7.5.4" - strip-indent: "npm:^3.0.0" + quote-js-string: "npm:^0.1.0" + regjsparser: "npm:^0.13.3" + reserved-identifiers: "npm:^1.2.0" + semver: "npm:^7.8.5" + strip-indent: "npm:^4.1.1" + yaml: "npm:^2.9.1" peerDependencies: - eslint: ">=8.44.0" - checksum: 10/c7ee2d2c031f74bc84ebd44a59462eaee93387fef4df29e9ec9489b2d7d92564962a35626aacc1c4a136c2f92f605c7749f38654ad51fd7a8c4bcc2aa7439b74 - languageName: node - linkType: hard - -"eslint-scope@npm:^5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^4.1.1" - checksum: 10/c541ef384c92eb5c999b7d3443d80195fcafb3da335500946f6db76539b87d5826c8f2e1d23bf6afc3154ba8cd7c8e566f8dc00f1eea25fdf3afc8fb9c87b238 + eslint: ">=10.4" + checksum: 10/3715d91bd0dd499f2f8ea9acc3b37cb3d803e4f5a783c13eef47aa883a9f76931fcbf16d445d49e5e65e2eef6d0d9fd224e2fc6f11b243847ed8826c32aca379 languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^9.1.2": + version: 9.1.2 + resolution: "eslint-scope@npm:9.1.2" dependencies: + "@types/esrecurse": "npm:^4.3.1" + "@types/estree": "npm:^1.0.8" esrecurse: "npm:^4.3.0" estraverse: "npm:^5.2.0" - checksum: 10/5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 + checksum: 10/d102a22525020be99a6897c0d5570b16a387b251e661ba70cedb4f983536d5acd45b9ea2ee05b63ab04f6c35e4f2ed00a113d1c6fb5f61ff879d92e46d0c2f15 languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b languageName: node linkType: hard -"eslint@npm:8.57.0": - version: 8.57.0 - resolution: "eslint@npm:8.57.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.0" - "@humanwhocodes/config-array": "npm:^0.11.14" +"eslint-visitor-keys@npm:^5.0.0, eslint-visitor-keys@npm:^5.0.1": + version: 5.0.1 + resolution: "eslint-visitor-keys@npm:5.0.1" + checksum: 10/f9cc1a57b75e0ef949545cac33d01e8367e302de4c1483266ed4d8646ee5c306376660196bbb38b004e767b7043d1e661cb4336b49eff634a1bbe75c1db709ec + languageName: node + linkType: hard + +"eslint@npm:10.12.0": + version: 10.12.0 + resolution: "eslint@npm:10.12.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.8.0" + "@eslint-community/regexpp": "npm:^4.12.2" + "@eslint/config-array": "npm:^0.23.5" + "@eslint/config-helpers": "npm:^0.7.0" + "@eslint/core": "npm:^1.2.1" + "@eslint/plugin-kit": "npm:^0.7.3" + "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" + "@humanwhocodes/retry": "npm:^0.4.2" + "@types/estree": "npm:^1.0.6" + ajv: "npm:^6.14.0" + cross-spawn: "npm:^7.0.6" debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" + eslint-scope: "npm:^9.1.2" + eslint-visitor-keys: "npm:^5.0.1" + espree: "npm:^11.2.0" + esquery: "npm:^1.7.0" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" + file-entry-cache: "npm:11.1.5 || >11.1.6 <12" find-up: "npm:^5.0.0" glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" + minimatch: "npm:^10.2.5" natural-compare: "npm:^1.4.0" optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: 10/00496e218b23747a7a9817bf58b522276d0dc1f2e546dceb4eea49f9871574088f72f1f069a6b560ef537efa3a75261b8ef70e51ef19033da1cc4c86a755ef15 + checksum: 10/1cff87e4db79d4c9b6bd0af4c2aa483d88936a16f70e73af192a2aeee5ec597ad1de5d42ba1242336c27b25be6f0e503e4ea41ca036ab134eb5f4b4c24af15b9 languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"espree@npm:^11.2.0": + version: 11.2.0 + resolution: "espree@npm:11.2.0" dependencies: - acorn: "npm:^8.9.0" + acorn: "npm:^8.16.0" acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 + eslint-visitor-keys: "npm:^5.0.1" + checksum: 10/5cc4233b8f150010c70713669ef8231f07fe9b6391870cfa0a292a07f723ed5c2922064b978e627f7cabf7753280e64c5bde41d3840caaa40946989df7009a51 languageName: node linkType: hard -"esquery@npm:^1.4.2, esquery@npm:^1.5.0": - version: 1.5.0 - resolution: "esquery@npm:1.5.0" +"esquery@npm:^1.7.0": + version: 1.7.0 + resolution: "esquery@npm:1.7.0" dependencies: estraverse: "npm:^5.1.0" - checksum: 10/e65fcdfc1e0ff5effbf50fb4f31ea20143ae5df92bb2e4953653d8d40aa4bc148e0d06117a592ce4ea53eeab1dafdfded7ea7e22a5be87e82d73757329a1b01d + checksum: 10/4afaf3089367e1f5885caa116ef386dffd8bfd64da21fd3d0e56e938d2667cfb2e5400ab4a825aa70e799bb3741e5b5d63c0b94d86e2d4cf3095c9e64b2f5a15 languageName: node linkType: hard @@ -12081,13 +10739,6 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.1.1": - version: 4.3.0 - resolution: "estraverse@npm:4.3.0" - checksum: 10/3f67ad02b6dbfaddd9ea459cf2b6ef4ecff9a6082a7af9d22e445b9abc082ad9ca47e1825557b293fcdae477f4714e561123e30bb6a5b2f184fb2bad4a9497eb - languageName: node - linkType: hard - "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -12243,7 +10894,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.2": +"fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" dependencies: @@ -12375,12 +11026,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:11.1.5 || >11.1.6 <12": + version: 11.1.5 + resolution: "file-entry-cache@npm:11.1.5" dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10/099bb9d4ab332cb93c48b14807a6918a1da87c45dce91d4b61fd40e6505d56d0697da060cb901c729c90487067d93c9243f5da3dc9c41f0358483bfdebca736b + flat-cache: "npm:^6.1.23" + checksum: 10/a4a6c45c9561fbceb6511b3483e299e636e5c67e225ea4445c8cbdbe6c571da8505b29b29fc4c62fe9cf28ffe33314f401fad3da09e4b62321c92f0d3a113135 languageName: node linkType: hard @@ -12393,17 +11044,6 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^3.3.1": - version: 3.3.2 - resolution: "find-cache-dir@npm:3.3.2" - dependencies: - commondir: "npm:^1.0.1" - make-dir: "npm:^3.0.2" - pkg-dir: "npm:^4.1.0" - checksum: 10/3907c2e0b15132704ed67083686cd3e68ab7d9ecc22e50ae9da20678245d488b01fa22c0e34c0544dc6edc4354c766f016c8c186a787be7c17f7cde8c5281e85 - languageName: node - linkType: hard - "find-replace@npm:^3.0.0": version: 3.0.0 resolution: "find-replace@npm:3.0.0" @@ -12429,7 +11069,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -12459,21 +11099,21 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^6.1.23": + version: 6.1.23 + resolution: "flat-cache@npm:6.1.23" dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10/02381c6ece5e9fa5b826c9bbea481d7fd77645d96e4b0b1395238124d581d10e56f17f723d897b6d133970f7a57f0fab9148cbbb67237a0a0ffe794ba60c0c70 + cacheable: "npm:^2.5.0" + flatted: "npm:^3.4.2" + hookified: "npm:^1.15.0" + checksum: 10/63ad3682f399e3e7b7255493b07469f80c418034a10e12e1c7043b41d666ff69b20be924984a0b91cd767a4f71540e4fb4421651d15adc736fca1c04b8505758 languageName: node linkType: hard -"flatted@npm:^3.2.9": - version: 3.4.2 - resolution: "flatted@npm:3.4.2" - checksum: 10/a9e78fe5c2c1fcd98209a015ccee3a6caa953e01729778e83c1fe92e68601a63e1e69cd4e573010ca99eaf585a581b80ccf1018b99283e6cbc2117bcba1e030f +"flatted@npm:^3.4.2": + version: 3.4.4 + resolution: "flatted@npm:3.4.4" + checksum: 10/5a6682ab87ed15e125419c61352c4bef26f310adceece03eae5f22c119d64ed47bfc0ee1948a77d0122559eaa86395ea06ef45b59bfe3db4fb13fb4cdff876de languageName: node linkType: hard @@ -12525,7 +11165,7 @@ __metadata: languageName: node linkType: hard -"form-data@npm:^4.0.6": +"form-data@npm:^4.0.4, form-data@npm:^4.0.6": version: 4.0.6 resolution: "form-data@npm:4.0.6" dependencies: @@ -12569,13 +11209,6 @@ __metadata: languageName: node linkType: hard -"fs-readdir-recursive@npm:^1.1.0": - version: 1.1.0 - resolution: "fs-readdir-recursive@npm:1.1.0" - checksum: 10/d5e3fd8456b8e5d57a43f169a9eaf65c70fa82c4a22f1d4361cdba4ea5e61c60c5c2b4ac481ea137a4d43b2b99b3ea2fae95ac2730255c4206d61af645866c3a - languageName: node - linkType: hard - "fs.realpath@npm:^1.0.0": version: 1.0.0 resolution: "fs.realpath@npm:1.0.0" @@ -12583,7 +11216,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": +"fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -12593,7 +11226,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": +"fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -12616,19 +11249,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.6": - version: 1.1.6 - resolution: "function.prototype.name@npm:1.1.6" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - functions-have-names: "npm:^1.2.3" - checksum: 10/4d40be44d4609942e4e90c4fff77a811fa936f4985d92d2abfcf44f673ba344e2962bf223a33101f79c1a056465f36f09b072b9c289d7660ca554a12491cd5a2 - languageName: node - linkType: hard - -"function.prototype.name@npm:^1.1.8": +"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8": version: 1.2.0 resolution: "function.prototype.name@npm:1.2.0" dependencies: @@ -12645,6 +11266,13 @@ __metadata: languageName: node linkType: hard +"functional-red-black-tree@npm:^1.0.1": + version: 1.0.1 + resolution: "functional-red-black-tree@npm:1.0.1" + checksum: 10/debe73e92204341d1fa5f89614e44284d3add26dee660722978d8c50829170f87d1c74768f68c251d215ae461c11db7bac13101c77f4146ff051da75466f7a12 + languageName: node + linkType: hard + "functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" @@ -12680,7 +11308,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": version: 1.3.1 resolution: "get-intrinsic@npm:1.3.1" dependencies: @@ -12735,17 +11363,6 @@ __metadata: languageName: node linkType: hard -"get-symbol-description@npm:^1.0.2": - version: 1.0.2 - resolution: "get-symbol-description@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.5" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - checksum: 10/e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 - languageName: node - linkType: hard - "get-symbol-description@npm:^1.1.0": version: 1.1.0 resolution: "get-symbol-description@npm:1.1.0" @@ -12757,16 +11374,16 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:5.0.0-beta.5": - version: 5.0.0-beta.5 - resolution: "get-tsconfig@npm:5.0.0-beta.5" +"get-tsconfig@npm:5.0.0-beta.6": + version: 5.0.0-beta.6 + resolution: "get-tsconfig@npm:5.0.0-beta.6" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/4946c4820cb2dc8c98073b341331b411db126c89b793d9bfe79c0d88843866e6fa7ebe9db43b51e9664d24e4cf10674e4137ad00881b10d4106c896d25c0e4fb + checksum: 10/748cfc5d08e47126245b12fd14d5573464445f5da6ac3f408a5e13ae355756c66bed61dbbaa206c057d058719ffd164295e5012c63517cd3fc30787c489533ff languageName: node linkType: hard -"get-tsconfig@npm:^4.10.0": +"get-tsconfig@npm:^4.10.1": version: 4.14.3 resolution: "get-tsconfig@npm:4.14.3" dependencies: @@ -12789,7 +11406,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": +"glob-parent@npm:^5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -12848,35 +11465,10 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.3, glob@npm:^7.2.0": - version: 7.2.3 - resolution: "glob@npm:7.2.3" - dependencies: - fs.realpath: "npm:^1.0.0" - inflight: "npm:^1.0.4" - inherits: "npm:2" - minimatch: "npm:^3.1.1" - once: "npm:^1.3.0" - path-is-absolute: "npm:^1.0.0" - checksum: 10/59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b - languageName: node - linkType: hard - -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10/62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e - languageName: node - linkType: hard - -"globalthis@npm:^1.0.3": - version: 1.0.3 - resolution: "globalthis@npm:1.0.3" - dependencies: - define-properties: "npm:^1.1.3" - checksum: 10/45ae2f3b40a186600d0368f2a880ae257e8278b4c7704f0417d6024105ad7f7a393661c5c2fa1334669cd485ea44bc883a08fdd4516df2428aec40c99f52aa89 +"globals@npm:17.13.0, globals@npm:^17.12.0": + version: 17.13.0 + resolution: "globals@npm:17.13.0" + checksum: 10/f723714cfb07bcf3163d44661d63b2a6076d93fd2f3724622b22084c62bcbbdb3ea3c601ec39635f1430d5cdf60bbf6fd7e458f12b5381ed422ed355c699537b languageName: node linkType: hard @@ -12890,20 +11482,6 @@ __metadata: languageName: node linkType: hard -"globby@npm:^11.1.0": - version: 11.1.0 - resolution: "globby@npm:11.1.0" - dependencies: - array-union: "npm:^2.1.0" - dir-glob: "npm:^3.0.1" - fast-glob: "npm:^3.2.9" - ignore: "npm:^5.2.0" - merge2: "npm:^1.4.1" - slash: "npm:^3.0.0" - checksum: 10/288e95e310227bbe037076ea81b7c2598ccbc3122d87abc6dab39e1eec309aa14f0e366a98cdc45237ffcfcbad3db597778c0068217dcb1950fef6249104e1b1 - languageName: node - linkType: hard - "gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" @@ -12925,13 +11503,6 @@ __metadata: languageName: node linkType: hard -"graphemer@npm:^1.4.0": - version: 1.4.0 - resolution: "graphemer@npm:1.4.0" - checksum: 10/6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 - languageName: node - linkType: hard - "graphql-request@npm:^6.1.0": version: 6.1.0 resolution: "graphql-request@npm:6.1.0" @@ -13020,10 +11591,10 @@ __metadata: languageName: node linkType: hard -"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": - version: 1.0.2 - resolution: "has-bigints@npm:1.0.2" - checksum: 10/4e0426c900af034d12db14abfece02ce7dbf53f2022d28af1a97913ff4c07adb8799476d57dc44fbca0e07d1dbda2a042c2928b1f33d3f09c15de0640a7fb81b +"has-bigints@npm:^1.0.2": + version: 1.1.0 + resolution: "has-bigints@npm:1.1.0" + checksum: 10/90fb1b24d40d2472bcd1c8bd9dd479037ec240215869bdbff97b2be83acef57d28f7e96bdd003a21bed218d058b49097f4acc8821c05b1629cc5d48dd7bfcccd languageName: node linkType: hard @@ -13050,13 +11621,6 @@ __metadata: languageName: node linkType: hard -"has-proto@npm:^1.0.3": - version: 1.0.3 - resolution: "has-proto@npm:1.0.3" - checksum: 10/0b67c2c94e3bea37db3e412e3c41f79d59259875e636ba471e94c009cdfb1fa82bf045deeffafc7dbb9c148e36cae6b467055aaa5d9fad4316e11b41e3ba551a - languageName: node - linkType: hard - "has-proto@npm:^1.2.0": version: 1.2.0 resolution: "has-proto@npm:1.2.0" @@ -13066,14 +11630,14 @@ __metadata: languageName: node linkType: hard -"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" checksum: 10/959385c98696ebbca51e7534e0dc723ada325efa3475350951363cce216d27373e0259b63edb599f72eb94d6cde8577b4b2375f080b303947e560f85692834fa languageName: node linkType: hard -"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": +"has-tostringtag@npm:^1.0.2": version: 1.0.2 resolution: "has-tostringtag@npm:1.0.2" dependencies: @@ -13092,6 +11656,15 @@ __metadata: languageName: node linkType: hard +"hashery@npm:^1.4.0, hashery@npm:^1.5.1": + version: 1.5.1 + resolution: "hashery@npm:1.5.1" + dependencies: + hookified: "npm:^1.15.0" + checksum: 10/34eebad3e4d4041ae5c2457f129169b7be8d067fce4717ec6b903017e82b420263808a4d89f15cc77fa21822ae36d16841dc06d945392b6833b49082d3653e82 + languageName: node + linkType: hard + "hashlru@npm:^2.3.0": version: 2.3.0 resolution: "hashlru@npm:2.3.0" @@ -13099,7 +11672,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -13108,7 +11681,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.3, hasown@npm:^2.0.4": +"hasown@npm:^2.0.4": version: 2.0.4 resolution: "hasown@npm:2.0.4" dependencies: @@ -13117,6 +11690,22 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.25.1": + version: 0.25.1 + resolution: "hermes-estree@npm:0.25.1" + checksum: 10/7b1eca98b264a25632064cffa5771360d30cf452e77db1e191f9913ee45cf78c292b2dbca707e92fb71b0870abb97e94b506a5ab80abd96ba237fee169b601fe + languageName: node + linkType: hard + +"hermes-parser@npm:^0.25.1": + version: 0.25.1 + resolution: "hermes-parser@npm:0.25.1" + dependencies: + hermes-estree: "npm:0.25.1" + checksum: 10/805efc05691420f236654349872c70731121791fa54de521c7ee51059eae34f84dd19f22ee846741dcb60372f8fb5335719b96b4ecb010d2aed7d872f2eff9cc + languageName: node + linkType: hard + "highlight.js@npm:^10.7.1": version: 10.7.3 resolution: "highlight.js@npm:10.7.3" @@ -13151,17 +11740,24 @@ __metadata: languageName: node linkType: hard -"hookable@npm:^6.1.1": - version: 6.1.1 - resolution: "hookable@npm:6.1.1" - checksum: 10/2f8b478ba1bb0782f0112d049b3d3d01aebf8245c250d3bdd306aa4bfdaba0f5d3c82d28fefa4290bb3c2bf4f1be22c6bed7ed50f0b39cd33742983202a32122 +"hookable@npm:^6.1.2": + version: 6.1.2 + resolution: "hookable@npm:6.1.2" + checksum: 10/1b561c862e7d5bce035c396f905e2ba3fd2852dcb65b1129879df19fa39c13080073f2f7abe66ad3fc4dabaa89a0485d15cf36e8d3c47661cbb96f915a8da356 + languageName: node + linkType: hard + +"hookified@npm:^1.15.0, hookified@npm:^1.15.1": + version: 1.15.1 + resolution: "hookified@npm:1.15.1" + checksum: 10/ecaee63506d9a213e8b78dfdb92346227f951d3bcd8ef60d14105c5590f61d466f130a908274e1ec87ee3b3668bd87d9250cad64547cf15cfa69932bcdbbea8f languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: 10/96da7d412303704af41c3819207a09ea2cab2de97951db4cf336bb8bce8d8e36b9a6821036ad2e55e67d3be0af8f967a7b57981203fbfb88bc05cd803407b8c3 +"hookified@npm:^2.1.1": + version: 2.2.0 + resolution: "hookified@npm:2.2.0" + checksum: 10/36be80a9645161c9747c90a0a26f75f074470984cf221fb73cf0e2f367667e0d4680797f7b4f27b83d1f4cd4a3b5913f685c91132b5d6eeb05522674081657a8 languageName: node linkType: hard @@ -13322,6 +11918,15 @@ __metadata: languageName: node linkType: hard +"identifier-regex@npm:^1.1.0": + version: 1.1.0 + resolution: "identifier-regex@npm:1.1.0" + dependencies: + reserved-identifiers: "npm:^1.0.0" + checksum: 10/df6358b7a336624315fca6f83659994314db8e74e4e801d9b8419d078a7182c33719e846e3af118c994b576852571bd8df3c7a4c0789856161c7b913a6dbd60b + languageName: node + linkType: hard + "ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -13338,13 +11943,27 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.0.5, ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"ignore@npm:^5.0.5": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": version: 5.3.1 resolution: "ignore@npm:5.3.1" checksum: 10/0a884c2fbc8c316f0b9f92beaf84464253b73230a4d4d286697be45fca081199191ca33e1c2e82d9e5f851f5e9a48a78e25a35c951e7eb41e59f150db3530065 languageName: node linkType: hard +"ignore@npm:^7.0.5": + version: 7.0.12 + resolution: "ignore@npm:7.0.12" + checksum: 10/9415f9f9ac68e361692a50922c2dc42eb4b996b8c242a781f00006e8348b9622dadc90246fb5ddc55bc579a33940e722f4ca08d02dff8349bc59646f486dd487 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -13372,10 +11991,10 @@ __metadata: languageName: node linkType: hard -"import-without-cache@npm:^0.4.0": - version: 0.4.0 - resolution: "import-without-cache@npm:0.4.0" - checksum: 10/935a7826f1263a612f72ea6f1044a2e7579b42556ce98941d22ddf1ef80d18345c4f5784cd00de56ff2a950f0e57e20efadc020fc050b39e06c1d59c23c68f95 +"import-without-cache@npm:^0.4.1": + version: 0.4.1 + resolution: "import-without-cache@npm:0.4.1" + checksum: 10/b52133c6619ebf7764569846ebe557698a03d659b44eed5ea6dd8606644fed3746af2f75ecfa022f6d801e99a0a2f8a2c15be188f2ca6e7714af25cd371e9ede languageName: node linkType: hard @@ -13386,13 +12005,6 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^4.0.0": - version: 4.0.0 - resolution: "indent-string@npm:4.0.0" - checksum: 10/cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 - languageName: node - linkType: hard - "indent-string@npm:^5.0.0": version: 5.0.0 resolution: "indent-string@npm:5.0.0" @@ -13479,17 +12091,6 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": - version: 1.0.7 - resolution: "internal-slot@npm:1.0.7" - dependencies: - es-errors: "npm:^1.3.0" - hasown: "npm:^2.0.0" - side-channel: "npm:^1.0.4" - checksum: 10/3e66720508831153ecf37d13def9f6856f9f2960989ec8a0a0476c98f887fca9eff0163127466485cb825c900c2d6fc601aa9117b7783b90ffce23a71ea5d053 - languageName: node - linkType: hard - "internal-slot@npm:^1.1.0": version: 1.1.0 resolution: "internal-slot@npm:1.1.0" @@ -13551,27 +12152,7 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.1.1": - version: 1.2.0 - resolution: "is-arguments@npm:1.2.0" - dependencies: - call-bound: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.2" - checksum: 10/471a8ef631b8ee8829c43a8ab05c081700c0e25180c73d19f3bf819c1a8448c426a9e8e601f278973eca68966384b16ceb78b8c63af795b099cd199ea5afc457 - languageName: node - linkType: hard - -"is-array-buffer@npm:^3.0.2, is-array-buffer@npm:^3.0.4": - version: 3.0.4 - resolution: "is-array-buffer@npm:3.0.4" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.1" - checksum: 10/34a26213d981d58b30724ef37a1e0682f4040d580fa9ff58fdfdd3cefcb2287921718c63971c1c404951e7b747c50fdc7caf6e867e951353fa71b369c04c969b - languageName: node - linkType: hard - -"is-array-buffer@npm:^3.0.5": +"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": version: 3.0.5 resolution: "is-array-buffer@npm:3.0.5" dependencies: @@ -13590,20 +12171,15 @@ __metadata: linkType: hard "is-async-function@npm:^2.0.0": - version: 2.0.0 - resolution: "is-async-function@npm:2.0.0" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/2cf336fbf8cba3badcf526aa3d10384c30bab32615ac4831b74492eb4e843ccb7d8439a119c27f84bcf217d72024e611b1373f870f433b48f3fa57d3d1b863f1 - languageName: node - linkType: hard - -"is-bigint@npm:^1.0.1": - version: 1.0.4 - resolution: "is-bigint@npm:1.0.4" + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" dependencies: - has-bigints: "npm:^1.0.1" - checksum: 10/cc981cf0564c503aaccc1e5f39e994ae16ae2d1a8fcd14721f14ad431809071f39ec568cfceef901cff408045f1a6d6bac90d1b43eeb0b8e3bc34c8eb1bdb4c4 + async-function: "npm:^1.0.0" + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10/7c2ac7efdf671e03265e74a043bcb1c0a32e226bc2a42dfc5ec8644667df668bbe14b91c08e6c1414f392f8cf86cd1d489b3af97756e2c7a49dd1ba63fd40ca6 languageName: node linkType: hard @@ -13616,25 +12192,6 @@ __metadata: languageName: node linkType: hard -"is-binary-path@npm:~2.1.0": - version: 2.1.0 - resolution: "is-binary-path@npm:2.1.0" - dependencies: - binary-extensions: "npm:^2.0.0" - checksum: 10/078e51b4f956c2c5fd2b26bb2672c3ccf7e1faff38e0ebdba45612265f4e3d9fc3127a1fa8370bbf09eab61339203c3d3b7af5662cbf8be4030f8fac37745b0e - languageName: node - linkType: hard - -"is-boolean-object@npm:^1.1.0": - version: 1.1.2 - resolution: "is-boolean-object@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.0" - checksum: 10/ba794223b56a49a9f185e945eeeb6b7833b8ea52a335cec087d08196cf27b538940001615d3bb976511287cefe94e5907d55f00bb49580533f9ca9b4515fcc2e - languageName: node - linkType: hard - "is-boolean-object@npm:^1.2.1": version: 1.2.2 resolution: "is-boolean-object@npm:1.2.2" @@ -13652,12 +12209,12 @@ __metadata: languageName: node linkType: hard -"is-builtin-module@npm:^3.2.1": - version: 3.2.1 - resolution: "is-builtin-module@npm:3.2.1" +"is-builtin-module@npm:^5.0.0": + version: 5.0.0 + resolution: "is-builtin-module@npm:5.0.0" dependencies: - builtin-modules: "npm:^3.3.0" - checksum: 10/e8f0ffc19a98240bda9c7ada84d846486365af88d14616e737d280d378695c8c448a621dcafc8332dbf0fcd0a17b0763b845400709963fa9151ddffece90ae88 + builtin-modules: "npm:^5.0.0" + checksum: 10/fcb1e458fa08e6d7e8763abaa84bc539ca943b298e15448ba92b79ab8f08c382664b8b1d5e32c59358e87026fed7b1e56e457b955436d7cc860cf0653002e4c6 languageName: node linkType: hard @@ -13670,7 +12227,7 @@ __metadata: languageName: node linkType: hard -"is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": +"is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 10/48a9297fb92c99e9df48706241a189da362bff3003354aea4048bd5f7b2eb0d823cd16d0a383cece3d76166ba16d85d9659165ac6fcce1ac12e6c649d66dbdb9 @@ -13686,7 +12243,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.1": +"is-core-module@npm:^2.16.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -13696,40 +12253,22 @@ __metadata: linkType: hard "is-core-module@npm:^2.16.2": - version: 2.16.2 - resolution: "is-core-module@npm:2.16.2" + version: 2.17.0 + resolution: "is-core-module@npm:2.17.0" dependencies: - hasown: "npm:^2.0.3" - checksum: 10/6ee7535d82bbe457685799c5f145daf4b7c6be3afbd8e90788429d557f663d6dee72a8e4b9a45d0d756c243fcb5028095999243df090e5f04c02b153786bc8c6 - languageName: node - linkType: hard - -"is-data-view@npm:^1.0.1": - version: 1.0.1 - resolution: "is-data-view@npm:1.0.1" - dependencies: - is-typed-array: "npm:^1.1.13" - checksum: 10/4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 + hasown: "npm:^2.0.4" + checksum: 10/0020f71b7eb525ccd684012cd1cfba235e7596e0addbc993732f7d8faff7ccd3a399e16dac7eb317b63459ea23f97efd661d6bf32584f6bf1d0a607fd8e21a6b languageName: node linkType: hard -"is-data-view@npm:^1.0.2": +"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2": version: 1.0.2 resolution: "is-data-view@npm:1.0.2" dependencies: - call-bound: "npm:^1.0.2" - get-intrinsic: "npm:^1.2.6" - is-typed-array: "npm:^1.1.13" - checksum: 10/357e9a48fa38f369fd6c4c3b632a3ab2b8adca14997db2e4b3fe94c4cd0a709af48e0fb61b02c64a90c0dd542fd489d49c2d03157b05ae6c07f5e4dec9e730a8 - languageName: node - linkType: hard - -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": - version: 1.0.5 - resolution: "is-date-object@npm:1.0.5" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/cc80b3a4b42238fa0d358b9a6230dae40548b349e64a477cb7c5eff9b176ba194c11f8321daaf6dd157e44073e9b7fd01f87db1f14952a88d5657acdcd3a56e2 + call-bound: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.6" + is-typed-array: "npm:^1.1.13" + checksum: 10/357e9a48fa38f369fd6c4c3b632a3ab2b8adca14997db2e4b3fe94c4cd0a709af48e0fb61b02c64a90c0dd542fd489d49c2d03157b05ae6c07f5e4dec9e730a8 languageName: node linkType: hard @@ -13788,7 +12327,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -13797,13 +12336,6 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.1, is-map@npm:^2.0.2": - version: 2.0.2 - resolution: "is-map@npm:2.0.2" - checksum: 10/60ba910f835f2eacb1fdf5b5a6c60fe1c702d012a7673e6546992bcc0c873f62ada6e13d327f9e48f1720d49c152d6cdecae1fa47a261ef3d247c3ce6f0e1d39 - languageName: node - linkType: hard - "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -13818,15 +12350,6 @@ __metadata: languageName: node linkType: hard -"is-number-object@npm:^1.0.4": - version: 1.0.7 - resolution: "is-number-object@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/8700dcf7f602e0a9625830541345b8615d04953655acbf5c6d379c58eb1af1465e71227e95d501343346e1d49b6f2d53cbc166b1fc686a7ec19151272df582f9 - languageName: node - linkType: hard - "is-number-object@npm:^1.1.1": version: 1.1.1 resolution: "is-number-object@npm:1.1.1" @@ -13851,13 +12374,6 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.3": - version: 3.0.3 - resolution: "is-path-inside@npm:3.0.3" - checksum: 10/abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 - languageName: node - linkType: hard - "is-plain-obj@npm:^4.1.0": version: 4.1.0 resolution: "is-plain-obj@npm:4.1.0" @@ -13872,7 +12388,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.1.4, is-regex@npm:^1.2.1": +"is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" dependencies: @@ -13891,13 +12407,6 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.1, is-set@npm:^2.0.2": - version: 2.0.2 - resolution: "is-set@npm:2.0.2" - checksum: 10/d89e82acdc7760993474f529e043f9c4a1d63ed4774d21cc2e331d0e401e5c91c27743cd7c889137028f6a742234759a4bd602368fbdbf0b0321994aefd5603f - languageName: node - linkType: hard - "is-set@npm:^2.0.3": version: 2.0.3 resolution: "is-set@npm:2.0.3" @@ -13905,15 +12414,6 @@ __metadata: languageName: node linkType: hard -"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": - version: 1.0.3 - resolution: "is-shared-array-buffer@npm:1.0.3" - dependencies: - call-bind: "npm:^1.0.7" - checksum: 10/bc5402900dc62b96ebb2548bf5b0a0bcfacc2db122236fe3ab3b3e3c884293a0d5eb777e73f059bcbf8dc8563bb65eae972fee0fb97e38a9ae27c8678f62bcfe - languageName: node - linkType: hard - "is-shared-array-buffer@npm:^1.0.4": version: 1.0.4 resolution: "is-shared-array-buffer@npm:1.0.4" @@ -13923,6 +12423,13 @@ __metadata: languageName: node linkType: hard +"is-standalone-pwa@npm:^0.1.1": + version: 0.1.1 + resolution: "is-standalone-pwa@npm:0.1.1" + checksum: 10/bbd2ee7cbea985139f66fe8785e7699f52311e9c14d74190659885222b79dd1e8845b02f69b9221a23a2b4b00e8d4bea0a5a2603b2f26cb6d2071d46093ccf84 + languageName: node + linkType: hard + "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -13944,15 +12451,6 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.5, is-string@npm:^1.0.7": - version: 1.0.7 - resolution: "is-string@npm:1.0.7" - dependencies: - has-tostringtag: "npm:^1.0.0" - checksum: 10/2bc292fe927493fb6dfc3338c099c3efdc41f635727c6ebccf704aeb2a27bca7acb9ce6fd34d103db78692b10b22111a8891de26e12bfa1c5e11e263c99d1fef - languageName: node - linkType: hard - "is-string@npm:^1.1.1": version: 1.1.1 resolution: "is-string@npm:1.1.1" @@ -13963,15 +12461,6 @@ __metadata: languageName: node linkType: hard -"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": - version: 1.0.4 - resolution: "is-symbol@npm:1.0.4" - dependencies: - has-symbols: "npm:^1.0.2" - checksum: 10/a47dd899a84322528b71318a89db25c7ecdec73197182dad291df15ffea501e17e3c92c8de0bfb50e63402747399981a687b31c519971b1fa1a27413612be929 - languageName: node - linkType: hard - "is-symbol@npm:^1.1.1": version: 1.1.1 resolution: "is-symbol@npm:1.1.1" @@ -13999,13 +12488,6 @@ __metadata: languageName: node linkType: hard -"is-weakmap@npm:^2.0.1": - version: 2.0.1 - resolution: "is-weakmap@npm:2.0.1" - checksum: 10/289fa4e8ba1bdda40ca78481266f6925b7c46a85599e6a41a77010bf91e5a24dfb660db96863bbf655ecdbda0ab517204d6a4e0c151dbec9d022c556321f3776 - languageName: node - linkType: hard - "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -14013,16 +12495,7 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2": - version: 1.0.2 - resolution: "is-weakref@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - checksum: 10/0023fd0e4bdf9c338438ffbe1eed7ebbbff7e7e18fb7cdc227caaf9d4bd024a2dcdf6a8c9f40c92192022eac8391243bb9e66cccebecbf6fe1d8a366108f8513 - languageName: node - linkType: hard - -"is-weakref@npm:^1.1.1": +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": version: 1.1.1 resolution: "is-weakref@npm:1.1.1" dependencies: @@ -14031,16 +12504,6 @@ __metadata: languageName: node linkType: hard -"is-weakset@npm:^2.0.1": - version: 2.0.2 - resolution: "is-weakset@npm:2.0.2" - dependencies: - call-bind: "npm:^1.0.2" - get-intrinsic: "npm:^1.1.1" - checksum: 10/8f2ddb9639716fd7936784e175ea1183c5c4c05274c34f34f6a53175313cb1c9c35a8b795623306995e2f7cc8f25aa46302f15a2113e51c5052d447be427195c - languageName: node - linkType: hard - "is-weakset@npm:^2.0.3": version: 2.0.4 resolution: "is-weakset@npm:2.0.4" @@ -14303,22 +12766,6 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:~0.5.0": - version: 0.5.0 - resolution: "jsesc@npm:0.5.0" - bin: - jsesc: bin/jsesc - checksum: 10/fab949f585c71e169c5cbe00f049f20de74f067081bbd64a55443bad1c71e1b5a5b448f2359bf2fe06f5ed7c07e2e4a9101843b01c823c30b6afc11f5bfaf724 - languageName: node - linkType: hard - -"json-buffer@npm:3.0.1": - version: 3.0.1 - resolution: "json-buffer@npm:3.0.1" - checksum: 10/82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c - languageName: node - linkType: hard - "json-parse-better-errors@npm:^1.0.1": version: 1.0.2 resolution: "json-parse-better-errors@npm:1.0.2" @@ -14434,6 +12881,13 @@ __metadata: languageName: node linkType: hard +"jsx-ast-utils-x@npm:^0.1.0": + version: 0.1.0 + resolution: "jsx-ast-utils-x@npm:0.1.0" + checksum: 10/ca28d2f2c9cf7e1c971f4a21d1f73197bb528659a9da50ab84065cdeedad422dacdf835e83cbc4264da4d84d41303f0c8fcca78d430d3fdbf22e10b7c7bf4724 + languageName: node + linkType: hard + "jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": version: 3.3.5 resolution: "jsx-ast-utils@npm:3.3.5" @@ -14472,12 +12926,12 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": - version: 4.5.4 - resolution: "keyv@npm:4.5.4" +"keyv@npm:^5.6.0": + version: 5.6.0 + resolution: "keyv@npm:5.6.0" dependencies: - json-buffer: "npm:3.0.1" - checksum: 10/167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + "@keyv/serialize": "npm:^1.1.1" + checksum: 10/f1de999fdf635d703d091981a0a3844fb20081e01d45c6743ada7d01f3a6570dc47d1882e10d0a98d31075b342db8e62b4ebe4f5bf473dcd0903064d718709c1 languageName: node linkType: hard @@ -14827,7 +13281,7 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": +"loader-utils@npm:^2.0.0": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" dependencies: @@ -14943,7 +13397,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.11, lodash@npm:^4.17.15, lodash@npm:^4.17.21, lodash@npm:^4.18.1": +"lodash@npm:^4.17.15, lodash@npm:^4.17.21, lodash@npm:^4.18.1": version: 4.18.1 resolution: "lodash@npm:4.18.1" checksum: 10/306fea53dfd39dad1f03d45ba654a2405aebd35797b673077f401edb7df2543623dc44b9effbb98f69b32152295fff725a4cec99c684098947430600c6af0c3f @@ -15014,15 +13468,6 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.5.0": - version: 1.5.0 - resolution: "lz-string@npm:1.5.0" - bin: - lz-string: bin/bin.js - checksum: 10/e86f0280e99a8d8cd4eef24d8601ddae15ce54e43ac9990dfcb79e1e081c255ad24424a30d78d2ad8e51a8ce82a66a930047fed4b4aa38c6f0b392ff9300edfc - languageName: node - linkType: hard - "magic-string@npm:^0.30.21": version: 0.30.21 resolution: "magic-string@npm:0.30.21" @@ -15050,25 +13495,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^2.1.0": - version: 2.1.0 - resolution: "make-dir@npm:2.1.0" - dependencies: - pify: "npm:^4.0.1" - semver: "npm:^5.6.0" - checksum: 10/043548886bfaf1820323c6a2997e6d2fa51ccc2586ac14e6f14634f7458b4db2daf15f8c310e2a0abd3e0cddc64df1890d8fc7263033602c47bb12cbfcf86aab - languageName: node - linkType: hard - -"make-dir@npm:^3.0.2, make-dir@npm:^3.1.0": - version: 3.1.0 - resolution: "make-dir@npm:3.1.0" - dependencies: - semver: "npm:^6.0.0" - checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 - languageName: node - linkType: hard - "make-fetch-happen@npm:^14.0.3": version: 14.0.3 resolution: "make-fetch-happen@npm:14.0.3" @@ -15173,6 +13599,13 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.35.0": + version: 2.35.0 + resolution: "mdn-data@npm:2.35.0" + checksum: 10/ce248cdb554a2c06079dc21ba3e75d7cbbce5711b9fc612e08b14a5a62d505c372b4033d95cf88f09be0c80d977c7fd037a5dfa8dcc0e2fc9fbdef929b79202f + languageName: node + linkType: hard + "meow@npm:^13.0.0": version: 13.2.0 resolution: "meow@npm:13.2.0" @@ -15187,7 +13620,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.3.0, merge2@npm:^1.4.1": +"merge2@npm:^1.3.0": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 @@ -15250,13 +13683,6 @@ __metadata: languageName: node linkType: hard -"min-indent@npm:^1.0.0": - version: 1.0.1 - resolution: "min-indent@npm:1.0.1" - checksum: 10/bfc6dd03c5eaf623a4963ebd94d087f6f4bbbfd8c41329a7f09706b0cb66969c4ddd336abeb587bc44bc6f08e13bf90f0b374f9d71f9f01e04adc2cd6f083ef1 - languageName: node - linkType: hard - "minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -15280,7 +13706,16 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^10.2.4, minimatch@npm:^10.2.6": + version: 10.2.6 + resolution: "minimatch@npm:10.2.6" + dependencies: + brace-expansion: "npm:^5.0.8" + checksum: 10/a5e43f7c57d6061a77da320b42aa35ffff826030cf67c83c0eee47a26ede4d66486935881492b968c609bf27a7d48cc4b9f54b2806643cd8fb792fcf9240cc1b + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.2": version: 3.1.5 resolution: "minimatch@npm:3.1.5" dependencies: @@ -15740,6 +14175,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.57": + version: 2.0.58 + resolution: "node-releases@npm:2.0.58" + checksum: 10/06039e07aef63b25e2f2597c4d68e147139977edbe1f147159d2d0379eb16a179709ab91ac25b294309cca0ff980266a7c4cffd079b6c5ac3dd9769204628051 + languageName: node + linkType: hard + "nopt@npm:^8.0.0": version: 8.1.0 resolution: "nopt@npm:8.1.0" @@ -15762,18 +14204,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: "npm:^2.1.4" - resolve: "npm:^1.10.0" - semver: "npm:2 || 3 || 4 || 5" - validate-npm-package-license: "npm:^3.0.1" - checksum: 10/644f830a8bb9b7cc9bf2f6150618727659ee27cdd0840d1c1f97e8e6cab0803a098a2c19f31c6247ad9d3a0792e61521a13a6e8cd87cc6bb676e3150612c03d4 - languageName: node - linkType: hard - "normalize-package-data@npm:^6.0.0": version: 6.0.2 resolution: "normalize-package-data@npm:6.0.2" @@ -15796,7 +14226,7 @@ __metadata: languageName: node linkType: hard -"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": +"normalize-path@npm:^3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" checksum: 10/88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 @@ -16020,13 +14450,6 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.1": - version: 1.13.1 - resolution: "object-inspect@npm:1.13.1" - checksum: 10/92f4989ed83422d56431bc39656d4c780348eb15d397ce352ade6b7fec08f973b53744bd41b94af021901e61acaf78fcc19e65bf464ecc0df958586a672700f0 - languageName: node - linkType: hard - "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -16034,16 +14457,6 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.3" - checksum: 10/75365aff5da4bebad5d20efd9f9a7a13597e603f5eb03d89da8f578c3f3937fe01c6cb5fce86c0611c48795c0841401fd37c943821db0de703c7b30a290576ad - languageName: node - linkType: hard - "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -16051,19 +14464,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.2, object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": - version: 4.1.5 - resolution: "object.assign@npm:4.1.5" - dependencies: - call-bind: "npm:^1.0.5" - define-properties: "npm:^1.2.1" - has-symbols: "npm:^1.0.3" - object-keys: "npm:^1.1.1" - checksum: 10/dbb22da4cda82e1658349ea62b80815f587b47131b3dd7a4ab7f84190ab31d206bbd8fe7e26ae3220c55b65725ac4529825f6142154211220302aa6b1518045d - languageName: node - linkType: hard - -"object.assign@npm:^4.1.7": +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7": version: 4.1.7 resolution: "object.assign@npm:4.1.7" dependencies: @@ -16077,17 +14478,6 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.5": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/2301918fbd1ee697cf6ff7cd94f060c738c0a7d92b22fd24c7c250e9b593642c9707ad2c44d339303c1439c5967d8964251cdfc855f7f6ec55db2dd79e8dc2a7 - languageName: node - linkType: hard - "object.entries@npm:^1.1.9": version: 1.1.9 resolution: "object.entries@npm:1.1.9" @@ -16123,18 +14513,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.6": - version: 1.1.7 - resolution: "object.values@npm:1.1.7" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - checksum: 10/20ab42c0bbf984405c80e060114b18cf5d629a40a132c7eac4fb79c5d06deb97496311c19297dcf9c61f45c2539cd4c7f7c5d6230e51db360ff297bbc9910162 - languageName: node - linkType: hard - -"object.values@npm:^1.2.1": +"object.values@npm:^1.1.6, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" dependencies: @@ -16153,10 +14532,10 @@ __metadata: languageName: node linkType: hard -"obug@npm:^2.1.4": - version: 2.1.4 - resolution: "obug@npm:2.1.4" - checksum: 10/05e3ac83f60ef18edb935d67703bada2cbc0feb1a1cef575240b1e48e6e877df95b74048e69bbe549759df18c57ad1808e1e60a9fc4f785525c8549bf7fe81db +"obug@npm:^3.0.0": + version: 3.0.0 + resolution: "obug@npm:3.0.0" + checksum: 10/34da05e0d4d517401bbeb99909b63a944b877b4c7736af84f49cd17fc9b50b2d04bffd85de5a1d183c8c55151b644464b58fb680da35acc67e569babf7f2a796 languageName: node linkType: hard @@ -16670,14 +15049,14 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": version: 2.3.2 resolution: "picomatch@npm:2.3.2" checksum: 10/b788ef8148a2415b9dec12f0bb350ae6a5830f8f1950e472abc2f5225494debf7d1b75eb031df0ceaea9e8ec3e7bad599e8dbf3c60d61b42be429ba41bff4426 languageName: node linkType: hard -"picomatch@npm:^4.0.3, picomatch@npm:^4.0.5": +"picomatch@npm:^4.0.3, picomatch@npm:^4.0.5, picomatch@npm:^4.0.7": version: 4.0.7 resolution: "picomatch@npm:4.0.7" checksum: 10/66e1df34bc39c72fa3756be4069f7887ea3e35e94bba1c3f6167763007698cb04b8a0a365161d186fda6e9571a2d3efb606b2966eb6a7dea6252911224dc2f48 @@ -16698,13 +15077,6 @@ __metadata: languageName: node linkType: hard -"pify@npm:^4.0.1": - version: 4.0.1 - resolution: "pify@npm:4.0.1" - checksum: 10/8b97cbf9dc6d4c1320cc238a2db0fc67547f9dc77011729ff353faf34f1936ea1a4d7f3c63b2f4980b253be77bcc72ea1e9e76ee3fd53cce2aafb6a8854d07ec - languageName: node - linkType: hard - "pino-abstract-transport@npm:^2.0.0": version: 2.0.0 resolution: "pino-abstract-transport@npm:2.0.0" @@ -16752,15 +15124,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^4.1.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" - dependencies: - find-up: "npm:^4.0.0" - checksum: 10/9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 - languageName: node - linkType: hard - "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -16782,14 +15145,7 @@ __metadata: languageName: node linkType: hard -"possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af - languageName: node - linkType: hard - -"possible-typed-array-names@npm:^1.1.0": +"possible-typed-array-names@npm:^1.0.0, possible-typed-array-names@npm:^1.1.0": version: 1.1.0 resolution: "possible-typed-array-names@npm:1.1.0" checksum: 10/2f44137b8d3dd35f4a7ba7469eec1cd9cfbb46ec164b93a5bc1f4c3d68599c9910ee3b91da1d28b4560e9cc8414c3cd56fedc07259c67e52cc774476270d3302 @@ -16883,17 +15239,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^27.0.2": - version: 27.5.1 - resolution: "pretty-format@npm:27.5.1" - dependencies: - ansi-regex: "npm:^5.0.1" - ansi-styles: "npm:^5.0.0" - react-is: "npm:^17.0.1" - checksum: 10/248990cbef9e96fb36a3e1ae6b903c551ca4ddd733f8d0912b9cc5141d3d0b3f9f8dfb4d799fb1c6723382c9c2083ffbfa4ad43ff9a0e7535d32d41fd5f01da6 - languageName: node - linkType: hard - "pretty-ms@npm:^9.2.0": version: 9.3.0 resolution: "pretty-ms@npm:9.3.0" @@ -17075,6 +15420,15 @@ __metadata: languageName: node linkType: hard +"qified@npm:^0.10.1": + version: 0.10.1 + resolution: "qified@npm:0.10.1" + dependencies: + hookified: "npm:^2.1.1" + checksum: 10/65eda075defad24a3c53a0bcb0056fdaffb8355ca5dbe33bffaf3143e767dd1f0ddb403a4d9402e3bd0bc54b8efdec934055fb13eb5b6e7070835a80bf517f79 + languageName: node + linkType: hard + "qr-code-styling@npm:^1.9.2": version: 1.9.2 resolution: "qr-code-styling@npm:1.9.2" @@ -17135,6 +15489,13 @@ __metadata: languageName: node linkType: hard +"quote-js-string@npm:^0.1.0": + version: 0.1.0 + resolution: "quote-js-string@npm:0.1.0" + checksum: 10/42989e9031948a95f825ce369784e603fdcd8639cdcca9de3e3d1ba77b5111aa45362b3e2f66f70e5c06e2230af10c48818e27dd6d22a9732812cc5d4b10d404 + languageName: node + linkType: hard + "rabin-wasm@npm:^0.1.5": version: 0.1.5 resolution: "rabin-wasm@npm:0.1.5" @@ -17212,7 +15573,7 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:18.2.0, react-dom@npm:^18.2.0": +"react-dom@npm:18.2.0": version: 18.2.0 resolution: "react-dom@npm:18.2.0" dependencies: @@ -17235,17 +15596,6 @@ __metadata: languageName: node linkType: hard -"react-error-boundary@npm:^3.1.0": - version: 3.1.4 - resolution: "react-error-boundary@npm:3.1.4" - dependencies: - "@babel/runtime": "npm:^7.12.5" - peerDependencies: - react: ">=16.13.1" - checksum: 10/7418637bf352b88f35ff3798e6faa094ee046df9d422fc08f54c017892c3c0738dac661ba3d64d97209464e7a60e7fbbeffdbeaee5edc38f3aaf5f1f4a8bf610 - languageName: node - linkType: hard - "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -17253,14 +15603,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^17.0.1": - version: 17.0.2 - resolution: "react-is@npm:17.0.2" - checksum: 10/73b36281e58eeb27c9cc6031301b6ae19ecdc9f18ae2d518bdb39b0ac564e65c5779405d623f1df9abf378a13858b79442480244bd579968afc1faf9a2ce5e05 - languageName: node - linkType: hard - -"react-jazzicon@npm:^1.0.4": +"react-jazzicon@npm:1.0.4, react-jazzicon@npm:^1.0.4": version: 1.0.4 resolution: "react-jazzicon@npm:1.0.4" dependencies: @@ -17379,17 +15722,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: "npm:^4.1.0" - read-pkg: "npm:^5.2.0" - type-fest: "npm:^0.8.1" - checksum: 10/e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44 - languageName: node - linkType: hard - "read-pkg@npm:^10.0.0": version: 10.1.0 resolution: "read-pkg@npm:10.1.0" @@ -17403,18 +15735,6 @@ __metadata: languageName: node linkType: hard -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" - dependencies: - "@types/normalize-package-data": "npm:^2.4.0" - normalize-package-data: "npm:^2.5.0" - parse-json: "npm:^5.0.0" - type-fest: "npm:^0.6.0" - checksum: 10/eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222 - languageName: node - linkType: hard - "read-pkg@npm:^9.0.0": version: 9.0.1 resolution: "read-pkg@npm:9.0.1" @@ -17470,15 +15790,6 @@ __metadata: languageName: node linkType: hard -"readdirp@npm:~3.6.0": - version: 3.6.0 - resolution: "readdirp@npm:3.6.0" - dependencies: - picomatch: "npm:^2.2.1" - checksum: 10/196b30ef6ccf9b6e18c4e1724b7334f72a093d011a99f3b5920470f0b3406a51770867b3e1ae9711f227ef7a7065982f6ee2ce316746b2cb42c88efe44297fe7 - languageName: node - linkType: hard - "real-require@npm:^0.2.0": version: 0.2.0 resolution: "real-require@npm:0.2.0" @@ -17497,22 +15808,39 @@ __metadata: version: 0.0.0-use.local resolution: "reef-knot@workspace:packages/reef-knot" dependencies: - "@reef-knot/connect-wallet-modal": "npm:*" - "@reef-knot/core-react": "npm:*" + "@ledgerhq/hw-app-eth": "npm:7.8.12" + "@ledgerhq/hw-transport": "npm:6.35.7" + "@ledgerhq/hw-transport-webhid": "npm:6.36.0" "@reef-knot/ledger-connector": "npm:*" - "@reef-knot/types": "npm:*" - "@reef-knot/ui-react": "npm:*" + "@reef-knot/wallet-adapter-ambire": "npm:*" + "@reef-knot/wallet-adapter-anchorage-digital": "npm:*" + "@reef-knot/wallet-adapter-bitkeep": "npm:*" + "@reef-knot/wallet-adapter-browser-extension": "npm:*" + "@reef-knot/wallet-adapter-coinbase-smart-wallet": "npm:*" + "@reef-knot/wallet-adapter-dapp-browser-injected": "npm:*" + "@reef-knot/wallet-adapter-imtoken": "npm:*" + "@reef-knot/wallet-adapter-ledger-hid": "npm:*" + "@reef-knot/wallet-adapter-ledger-live": "npm:*" + "@reef-knot/wallet-adapter-metamask": "npm:*" + "@reef-knot/wallet-adapter-okx": "npm:*" + "@reef-knot/wallet-adapter-safe": "npm:*" + "@reef-knot/wallet-adapter-walletconnect": "npm:*" "@reef-knot/wallets-helpers": "npm:*" - "@reef-knot/wallets-list": "npm:*" - "@reef-knot/web3-react": "npm:*" + "@types/react": "npm:18.2.45" + "@types/react-dom": "npm:18.2.17" build-config: "npm:*" - eslint-config-custom: "npm:*" + happy-dom: "npm:^20.0.0" + mipd: "npm:0.0.7" + react: "npm:18.2.0" + react-dom: "npm:18.2.0" + tsconfig: "npm:*" + viem: "npm:>=2.50" + vitest: "npm:^4.1.11" + wagmi: "npm:>=3.6" peerDependencies: - "@lidofinance/lido-ui": ^3.18.0 "@tanstack/react-query": ^5.51.1 react: ">=18" react-dom: ">=18" - styled-components: ^5.3.5 viem: ">=2.50" wagmi: ">=3.6" languageName: unknown @@ -17522,38 +15850,50 @@ __metadata: version: 0.0.0-use.local resolution: "reef-knot_root@workspace:." dependencies: - "@lidofinance/eslint-config": "npm:^0.63.0" + "@eslint/compat": "npm:2.1.1" + "@eslint/js": "npm:10.0.1" "@lidofinance/multi-semantic-release": "npm:^1.0.2" - "@next/eslint-plugin-next": "npm:^13.5.11" "@turbo/gen": "npm:2.10.12" "@types/react": "npm:18.2.45" "@types/react-dom": "npm:18.2.17" "@types/styled-components": "npm:5.1.12" - eslint: "npm:8.57.0" - eslint-config-airbnb: "npm:19.0.4" - eslint-config-prettier: "npm:9.1.2" - eslint-config-turbo: "npm:2.10.12" - eslint-import-resolver-typescript: "npm:3.10.1" + "@typescript-eslint/eslint-plugin": "npm:8.71.1" + "@typescript-eslint/parser": "npm:8.71.1" + "@typescript/native": "npm:typescript@7.0.2" + "@vitest/eslint-plugin": "npm:1.6.27" + eslint: "npm:10.12.0" + eslint-config-prettier: "npm:10.1.8" + eslint-config-turbo: "npm:2.11.7" + eslint-import-resolver-typescript: "npm:4.4.5" eslint-plugin-eslint-comments: "npm:3.2.0" eslint-plugin-import: "npm:2.32.0" - eslint-plugin-jest: "npm:27.9.0" eslint-plugin-jsx-a11y: "npm:6.10.2" eslint-plugin-prettier: "npm:5.5.6" - eslint-plugin-promise: "npm:6.6.0" + eslint-plugin-promise: "npm:7.3.0" eslint-plugin-react: "npm:7.37.5" - eslint-plugin-react-hooks: "npm:4.6.2" - eslint-plugin-sonarjs: "npm:0.25.1" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-react-hooks: "npm:7.1.1" + eslint-plugin-sonarjs: "npm:4.2.2" + eslint-plugin-unicorn: "npm:77.0.0" + globals: "npm:17.13.0" prettier: "npm:^3.9.6" - tsdown: "npm:0.22.14" + tsdown: "npm:0.23.1" tslib: "npm:2.8.1" turbo: "npm:latest" - typescript: "npm:~5.9" - typescript-eslint: "npm:^7.9.0" + typescript: "npm:@typescript/typescript6@6.0.2" + typescript-eslint: "npm:8.71.1" languageName: unknown linkType: soft -"reflect.getprototypeof@npm:^1.0.10, reflect.getprototypeof@npm:^1.0.9": +"refa@npm:^0.12.0, refa@npm:^0.12.1": + version: 0.12.1 + resolution: "refa@npm:0.12.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.8.0" + checksum: 10/b89411434e31637a519c065acd8fd1ec9eabc1dec38eec58dbc69a386ec21d88f97fa175e56fb3133e21c090ddb68fe7b5653ffc4bbcc9f069abc0e88c0d290c + languageName: node + linkType: hard + +"reflect.getprototypeof@npm:^1.0.10": version: 1.0.10 resolution: "reflect.getprototypeof@npm:1.0.10" dependencies: @@ -17585,28 +15925,17 @@ __metadata: languageName: node linkType: hard -"regexp-tree@npm:^0.1.27": - version: 0.1.27 - resolution: "regexp-tree@npm:0.1.27" - bin: - regexp-tree: bin/regexp-tree - checksum: 10/08c70c8adb5a0d4af1061bf9eb05d3b6e1d948c433d6b7008e4b5eb12a49429c2d6ca8e9106339a432aa0d07bd6e1bccc638d8f4ab0d045f3adad22182b300a2 - languageName: node - linkType: hard - -"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": - version: 1.5.2 - resolution: "regexp.prototype.flags@npm:1.5.2" +"regexp-ast-analysis@npm:^0.7.0": + version: 0.7.1 + resolution: "regexp-ast-analysis@npm:0.7.1" dependencies: - call-bind: "npm:^1.0.6" - define-properties: "npm:^1.2.1" - es-errors: "npm:^1.3.0" - set-function-name: "npm:^2.0.1" - checksum: 10/9fffc01da9c4e12670ff95bc5204364615fcc12d86fc30642765af908675678ebb0780883c874b2dbd184505fb52fa603d80073ecf69f461ce7f56b15d10be9c + "@eslint-community/regexpp": "npm:^4.8.0" + refa: "npm:^0.12.1" + checksum: 10/92299636d9c941ee27db7568a775354d36024504c104c5d7981a89dda1b0ff1e2a56db16f92d7e166a50a1164593788c0849c5840ec9d79b39c1c040d59c442c languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": +"regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -17650,25 +15979,25 @@ __metadata: languageName: node linkType: hard -"regjsparser@npm:^0.10.0": - version: 0.10.0 - resolution: "regjsparser@npm:0.10.0" +"regjsparser@npm:^0.13.0": + version: 0.13.0 + resolution: "regjsparser@npm:0.13.0" dependencies: - jsesc: "npm:~0.5.0" + jsesc: "npm:~3.1.0" bin: regjsparser: bin/parser - checksum: 10/06f7f0e59598de20769ce5637bbd8879387f67c0eeb8ccc8857331c623332718c25d8d20bd74df210bf636dde061474e8bd365cf73af20470f0b3cb42cd42019 + checksum: 10/eeaabd3454f59394cbb3bfeb15fd789e638040f37d0bee9071a9b0b85524ddc52b5f7aaaaa4847304c36fa37429e53d109c4dbf6b878cb5ffa4f4198c1042fb7 languageName: node linkType: hard -"regjsparser@npm:^0.13.0": - version: 0.13.0 - resolution: "regjsparser@npm:0.13.0" +"regjsparser@npm:^0.13.3": + version: 0.13.4 + resolution: "regjsparser@npm:0.13.4" dependencies: jsesc: "npm:~3.1.0" bin: regjsparser: bin/parser - checksum: 10/eeaabd3454f59394cbb3bfeb15fd789e638040f37d0bee9071a9b0b85524ddc52b5f7aaaaa4847304c36fa37429e53d109c4dbf6b878cb5ffa4f4198c1042fb7 + checksum: 10/e719ebf06b1f80ff443650d67a82ef94337deba90651b8ff843f36bc9f4652a8178a1afc6255015857d08ece4cefaf356ea6999d89dacfe8a6f80150516ecc21 languageName: node linkType: hard @@ -17693,6 +16022,13 @@ __metadata: languageName: node linkType: hard +"reserved-identifiers@npm:^1.0.0, reserved-identifiers@npm:^1.2.0": + version: 1.2.0 + resolution: "reserved-identifiers@npm:1.2.0" + checksum: 10/02722585aa97f25384a59a33055529a90c8fa8ce3d32f02be4bcec1454254fb385429fc3168a85fe56bb952ad632ea8fecb8fa2addb47e7d97a1ab4922827ad9 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -17714,7 +16050,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.22.11": +"resolve@npm:^1.22.11": version: 1.22.11 resolution: "resolve@npm:1.22.11" dependencies: @@ -17727,20 +16063,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.5": - version: 2.0.0-next.5 - resolution: "resolve@npm:2.0.0-next.5" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/2d6fd28699f901744368e6f2032b4268b4c7b9185fd8beb64f68c93ac6b22e52ae13560ceefc96241a665b985edf9ffd393ae26d2946a7d3a07b7007b7d51e79 - languageName: node - linkType: hard - -"resolve@npm:^2.0.0-next.6": +"resolve@npm:^2.0.0-next.5, resolve@npm:^2.0.0-next.6": version: 2.0.0-next.7 resolution: "resolve@npm:2.0.0-next.7" dependencies: @@ -17756,33 +16079,20 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": +"resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": version: 1.22.11 resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=9bd1a5" dependencies: - is-core-module: "npm:^2.16.1" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/c990146fed81dd7792c56c1d62c170a8c8330bee86ef5d2524f0b1db79cfd9a6e2b4ad3cd4742b2685e51117b67be5d6f8cfd6ffa9c57bd64a1c8c8c9ff4c965 - languageName: node - linkType: hard - -"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": - version: 2.0.0-next.5 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=9bd1a5" - dependencies: - is-core-module: "npm:^2.13.0" + is-core-module: "npm:^2.16.1" path-parse: "npm:^1.0.7" supports-preserve-symlinks-flag: "npm:^1.0.0" bin: resolve: bin/resolve - checksum: 10/76c221deb1d986c0a80cd576373b0ee09f42871e0085a1f76beda84f73ce04e0d21bab28dffd326eb006a7af83bbc582404566b384aa3b0baa217f56cf7e8618 + checksum: 10/c990146fed81dd7792c56c1d62c170a8c8330bee86ef5d2524f0b1db79cfd9a6e2b4ad3cd4742b2685e51117b67be5d6f8cfd6ffa9c57bd64a1c8c8c9ff4c965 languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^2.0.0-next.6#optional!builtin": +"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin, resolve@patch:resolve@npm%3A^2.0.0-next.6#optional!builtin": version: 2.0.0-next.7 resolution: "resolve@patch:resolve@npm%3A2.0.0-next.7#optional!builtin::version=2.0.0-next.7&hash=9bd1a5" dependencies: @@ -17812,31 +16122,21 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" - dependencies: - glob: "npm:^7.1.3" - bin: - rimraf: bin.js - checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 - languageName: node - linkType: hard - -"rolldown-plugin-dts@npm:^0.27.13": - version: 0.27.14 - resolution: "rolldown-plugin-dts@npm:0.27.14" +"rolldown-plugin-dts@npm:^0.28.7": + version: 0.28.8 + resolution: "rolldown-plugin-dts@npm:0.28.8" dependencies: dts-resolver: "npm:^3.0.0" - get-tsconfig: "npm:5.0.0-beta.5" - obug: "npm:^2.1.4" - yuku-ast: "npm:^0.8.0" - yuku-codegen: "npm:^0.8.0" - yuku-parser: "npm:^0.8.0" + get-tsconfig: "npm:5.0.0-beta.6" + obug: "npm:^3.0.0" + yuku-ast: "npm:^0.19.0" + yuku-codegen: "npm:^0.19.0" + yuku-parser: "npm:^0.19.0" peerDependencies: "@typescript/native-preview": "*" "@volar/typescript": ~2.4.0 - rolldown: ^1.0.0 + "@vue/language-core": ~3.2.0 || ~3.3.0 + rolldown: ^1.2.0 typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 vue-tsc: ~3.2.0 || ~3.3.0 peerDependenciesMeta: @@ -17844,34 +16144,36 @@ __metadata: optional: true "@volar/typescript": optional: true + "@vue/language-core": + optional: true typescript: optional: true vue-tsc: optional: true - checksum: 10/be827f55c4c0bdb4fc02aef1e59f3a0cfba016c7d5ae43d9c727bbffdcd6064c77ffea8a779985f65cb2544fa7a58992887e2850e5fea023ec579d2b3fafd3c7 - languageName: node - linkType: hard - -"rolldown@npm:~1.2.0": - version: 1.2.6 - resolution: "rolldown@npm:1.2.6" - dependencies: - "@oxc-project/types": "npm:=0.147.0" - "@rolldown/binding-android-arm-eabi": "npm:1.2.6" - "@rolldown/binding-android-arm64": "npm:1.2.6" - "@rolldown/binding-darwin-arm64": "npm:1.2.6" - "@rolldown/binding-darwin-x64": "npm:1.2.6" - "@rolldown/binding-freebsd-x64": "npm:1.2.6" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.6" - "@rolldown/binding-linux-arm64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-arm64-musl": "npm:1.2.6" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-s390x-gnu": "npm:1.2.6" - "@rolldown/binding-linux-x64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-x64-musl": "npm:1.2.6" - "@rolldown/binding-openharmony-arm64": "npm:1.2.6" - "@rolldown/binding-win32-arm64-msvc": "npm:1.2.6" - "@rolldown/binding-win32-x64-msvc": "npm:1.2.6" + checksum: 10/77adc8deff37eace9f004b671d021ef74c0e435c923308746dde8424609370f874ee411c66015f8ecabada8a9cd17f0941f2b55de40a4565bca73d20bc3358fb + languageName: node + linkType: hard + +"rolldown@npm:~1.2.13": + version: 1.2.13 + resolution: "rolldown@npm:1.2.13" + dependencies: + "@oxc-project/types": "npm:=0.153.0" + "@rolldown/binding-android-arm-eabi": "npm:1.2.13" + "@rolldown/binding-android-arm64": "npm:1.2.13" + "@rolldown/binding-darwin-arm64": "npm:1.2.13" + "@rolldown/binding-darwin-x64": "npm:1.2.13" + "@rolldown/binding-freebsd-x64": "npm:1.2.13" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.13" + "@rolldown/binding-linux-arm64-gnu": "npm:1.2.13" + "@rolldown/binding-linux-arm64-musl": "npm:1.2.13" + "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.13" + "@rolldown/binding-linux-s390x-gnu": "npm:1.2.13" + "@rolldown/binding-linux-x64-gnu": "npm:1.2.13" + "@rolldown/binding-linux-x64-musl": "npm:1.2.13" + "@rolldown/binding-openharmony-arm64": "npm:1.2.13" + "@rolldown/binding-win32-arm64-msvc": "npm:1.2.13" + "@rolldown/binding-win32-x64-msvc": "npm:1.2.13" "@rolldown/pluginutils": "npm:^1.0.0" dependenciesMeta: "@rolldown/binding-android-arm-eabi": @@ -17906,7 +16208,7 @@ __metadata: optional: true bin: rolldown: ./bin/cli.mjs - checksum: 10/29bff46d93bc551732503e4a34786fec5f69aed7186a9617b701fbfbb6f91415d54ce31af6b0dcd11a40eb296c90b47bb7c7d04fe9c1f912decb2f02aacfb65a + checksum: 10/7e602afd9c851e1e4c26711030211ec36c538f57a59e5c84ea74167a98db14eeecc8741a8c3564bcce8b9377ec0c5502973acc823bca4788da25ad6f70283416 languageName: node linkType: hard @@ -18008,18 +16310,6 @@ __metadata: languageName: node linkType: hard -"safe-array-concat@npm:^1.1.2": - version: 1.1.2 - resolution: "safe-array-concat@npm:1.1.2" - dependencies: - call-bind: "npm:^1.0.7" - get-intrinsic: "npm:^1.2.4" - has-symbols: "npm:^1.0.3" - isarray: "npm:^2.0.5" - checksum: 10/a54f8040d7cb696a1ee38d19cc71ab3cfb654b9b81bae00c6459618cfad8214ece7e6666592f9c925aafef43d0a20c5e6fbb3413a2b618e1ce9d516a2e6dcfc5 - languageName: node - linkType: hard - "safe-array-concat@npm:^1.1.3": version: 1.1.4 resolution: "safe-array-concat@npm:1.1.4" @@ -18105,17 +16395,6 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^2.6.5": - version: 2.7.1 - resolution: "schema-utils@npm:2.7.1" - dependencies: - "@types/json-schema": "npm:^7.0.5" - ajv: "npm:^6.12.4" - ajv-keywords: "npm:^3.5.2" - checksum: 10/86c3038798981dbc702d5f6a86d4e4a308a2ec6e8eb1bf7d1a3ea95cb3f1972491833b76ce1c86a068652417019126d5b68219c33a9ad069358dd10429d4096d - languageName: node - linkType: hard - "schema-utils@npm:^3.0.0": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" @@ -18139,6 +16418,17 @@ __metadata: languageName: node linkType: hard +"scslre@npm:^0.3.0": + version: 0.3.0 + resolution: "scslre@npm:0.3.0" + dependencies: + "@eslint-community/regexpp": "npm:^4.8.0" + refa: "npm:^0.12.0" + regexp-ast-analysis: "npm:^0.7.0" + checksum: 10/164ec9b9a9d819838240b1df613b6c60ae00c69c4472264f354a191f73b538c064d43c0ac3accf89f5c05880ddab33846077b0cda3ad383701623d468960c005 + languageName: node + linkType: hard + "semantic-release@npm:^25.0.5": version: 25.0.5 resolution: "semantic-release@npm:25.0.5" @@ -18184,15 +16474,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.6.0": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: 10/fca14418a174d4b4ef1fecb32c5941e3412d52a4d3d85165924ce3a47fbc7073372c26faf7484ceb4bbc2bde25880c6b97e492473dc7e9708fdfb1c6a02d546e - languageName: node - linkType: hard - "semver@npm:7.7.2": version: 7.7.2 resolution: "semver@npm:7.7.2" @@ -18211,7 +16492,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": +"semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -18220,7 +16501,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.4, semver@npm:^7.8.5": +"semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3, semver@npm:^7.7.4, semver@npm:^7.8.5": version: 7.8.5 resolution: "semver@npm:7.8.5" bin: @@ -18250,7 +16531,7 @@ __metadata: languageName: node linkType: hard -"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": +"set-function-name@npm:^2.0.2": version: 2.0.2 resolution: "set-function-name@npm:2.0.2" dependencies: @@ -18338,19 +16619,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.4": - version: 1.0.6 - resolution: "side-channel@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - es-errors: "npm:^1.3.0" - get-intrinsic: "npm:^1.2.4" - object-inspect: "npm:^1.13.1" - checksum: 10/eb10944f38cebad8ad643dd02657592fa41273ce15b8bfa928d3291aff2d30c20ff777cfe908f76ccc4551ace2d1245822fdc576657cce40e9066c638ca8fa4d - languageName: node - linkType: hard - -"side-channel@npm:^1.1.0": +"side-channel@npm:^1.1.0, side-channel@npm:^1.1.1": version: 1.1.1 resolution: "side-channel@npm:1.1.1" dependencies: @@ -18422,20 +16691,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^2.0.0": - version: 2.0.0 - resolution: "slash@npm:2.0.0" - checksum: 10/512d4350735375bd11647233cb0e2f93beca6f53441015eea241fe784d8068281c3987fbaa93e7ef1c38df68d9c60013045c92837423c69115297d6169aa85e6 - languageName: node - linkType: hard - -"slash@npm:^3.0.0": - version: 3.0.0 - resolution: "slash@npm:3.0.0" - checksum: 10/94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c - languageName: node - linkType: hard - "slow-redact@npm:^0.3.0": version: 0.3.2 resolution: "slow-redact@npm:0.3.2" @@ -18610,10 +16865,10 @@ __metadata: languageName: node linkType: hard -"stable-hash@npm:^0.0.5": - version: 0.0.5 - resolution: "stable-hash@npm:0.0.5" - checksum: 10/9222ea2c558e37c4a576cb4e406966b9e6aa05b93f5c4f09ef4aaabe3577439b9b8fbff407b16840b63e2ae83de74290c7b1c2da7360d571e480e46a4aec0a56 +"stable-hash-x@npm:^0.2.0": + version: 0.2.0 + resolution: "stable-hash-x@npm:0.2.0" + checksum: 10/136f05d0e4d441876012b423541476ff5b695c93b56d1959560be858b9e324ea6de6c16ecbd735a040ee8396427dd867bed0bf90b2cdb1fc422566747b91a0e5 languageName: node linkType: hard @@ -18645,15 +16900,6 @@ __metadata: languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" - dependencies: - internal-slot: "npm:^1.0.4" - checksum: 10/2a23a36f4f6bfa63f46ae2d53a3f80fe8276110b95a55345d8ed3d92125413494033bc8697eb774e8f7aeb5725f70e3d69753caa2ecacdac6258c16fa8aa8b0f - languageName: node - linkType: hard - "stop-iteration-iterator@npm:^1.1.0": version: 1.1.0 resolution: "stop-iteration-iterator@npm:1.1.0" @@ -18753,23 +16999,23 @@ __metadata: linkType: hard "string.prototype.matchall@npm:^4.0.12": - version: 4.0.12 - resolution: "string.prototype.matchall@npm:4.0.12" + version: 4.1.0 + resolution: "string.prototype.matchall@npm:4.1.0" dependencies: - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" + call-bind: "npm:^1.0.9" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.6" + es-abstract: "npm:^1.24.2" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.6" + es-object-atoms: "npm:^1.1.2" + get-intrinsic: "npm:^1.3.0" gopd: "npm:^1.2.0" has-symbols: "npm:^1.1.0" internal-slot: "npm:^1.1.0" - regexp.prototype.flags: "npm:^1.5.3" + regexp.prototype.flags: "npm:^1.5.4" set-function-name: "npm:^2.0.2" - side-channel: "npm:^1.1.0" - checksum: 10/e4ab34b9e7639211e6c5e9759adb063028c5c5c4fc32ad967838b2bd1e5ce83a66ae8ec755d24a79302849f090b59194571b2c33471e86e7821b21c0f56df316 + side-channel: "npm:^1.1.1" + checksum: 10/d8c54b52afad226eae80fa5930a9ab72f0277ea8e1a8b17cae674880d424a0e5f3b685f9381cad9168baf2e2ea8a0e77f6c6c02ea3fea6bb48d63190d840a4f3 languageName: node linkType: hard @@ -18799,29 +17045,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.9": - version: 1.2.9 - resolution: "string.prototype.trim@npm:1.2.9" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.0" - es-object-atoms: "npm:^1.0.0" - checksum: 10/b2170903de6a2fb5a49bb8850052144e04b67329d49f1343cdc6a87cb24fb4e4b8ad00d3e273a399b8a3d8c32c89775d93a8f43cb42fbff303f25382079fb58a - languageName: node - linkType: hard - -"string.prototype.trimend@npm:^1.0.8": - version: 1.0.8 - resolution: "string.prototype.trimend@npm:1.0.8" - dependencies: - call-bind: "npm:^1.0.7" - define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/c2e862ae724f95771da9ea17c27559d4eeced9208b9c20f69bbfcd1b9bc92375adf8af63a103194dba17c4cc4a5cb08842d929f415ff9d89c062d44689c8761b - languageName: node - linkType: hard - "string.prototype.trimend@npm:^1.0.9": version: 1.0.10 resolution: "string.prototype.trimend@npm:1.0.10" @@ -18834,17 +17057,6 @@ __metadata: languageName: node linkType: hard -"string.prototype.trimstart@npm:^1.0.7": - version: 1.0.7 - resolution: "string.prototype.trimstart@npm:1.0.7" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.2.0" - es-abstract: "npm:^1.22.1" - checksum: 10/6e594d3a61b127d243b8be1312e9f78683abe452cfe0bcafa3e0dc62ad6f030ccfb64d87ed3086fb7cb540fda62442c164d237cc5cc4d53c6e3eb659c29a0aeb - languageName: node - linkType: hard - "string.prototype.trimstart@npm:^1.0.8": version: 1.0.8 resolution: "string.prototype.trimstart@npm:1.0.8" @@ -18913,19 +17125,10 @@ __metadata: languageName: node linkType: hard -"strip-indent@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-indent@npm:3.0.0" - dependencies: - min-indent: "npm:^1.0.0" - checksum: 10/18f045d57d9d0d90cd16f72b2313d6364fd2cb4bf85b9f593523ad431c8720011a4d5f08b6591c9d580f446e78855c5334a30fb91aa1560f5d9f95ed1b4a0530 - languageName: node - linkType: hard - -"strip-json-comments@npm:^3.1.1": - version: 3.1.1 - resolution: "strip-json-comments@npm:3.1.1" - checksum: 10/492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 +"strip-indent@npm:^4.1.1": + version: 4.1.1 + resolution: "strip-indent@npm:4.1.1" + checksum: 10/d322bfdc59855006791a4aebe2a66e0892eab7004a5c064d74b86a0c6ecff2818974c9a5eda54b16d8af6aadbc90a6c02635ffcbec11ab33dd8979b1a6346fc0 languageName: node linkType: hard @@ -19187,7 +17390,7 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0, text-table@npm:~0.2.0": +"text-table@npm:~0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" checksum: 10/4383b5baaeffa9bb4cda2ac33a4aa2e6d1f8aaf811848bf73513a9b88fd76372dc461f6fd6d2e9cb5100f48b473be32c6f95bd983509b7d92bb4d92c10747452 @@ -19240,7 +17443,7 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.1.0, tiny-invariant@npm:^1.3.1": +"tiny-invariant@npm:^1.3.1": version: 1.3.1 resolution: "tiny-invariant@npm:1.3.1" checksum: 10/872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c @@ -19268,21 +17471,14 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^1.0.2": +"tinyexec@npm:^1.0.2, tinyexec@npm:^1.3.1": version: 1.3.1 resolution: "tinyexec@npm:1.3.1" checksum: 10/9c7a8ce2633f76c776d9ff663531c7b34d605f41909c2f97a27397e8c12bcaf721dae7680b6683232ffe7a6d465090be9926d5ffd00b5d7be9336a43b45289b1 languageName: node linkType: hard -"tinyexec@npm:^1.2.4": - version: 1.3.0 - resolution: "tinyexec@npm:1.3.0" - checksum: 10/749a8c5aac2ffe3f04220b8966f414636c6c324d4ae88895dfffb2319db61cf1c01c5d7e8f0fb8ab747389ea0be1f0f80d850a9cce88a9d96cc5ebcb345db018 - languageName: node - linkType: hard - -"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.17": +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.15, tinyglobby@npm:^0.2.17": version: 0.2.17 resolution: "tinyglobby@npm:0.2.17" dependencies: @@ -19366,12 +17562,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^1.3.0": - version: 1.3.0 - resolution: "ts-api-utils@npm:1.3.0" +"ts-api-utils@npm:^2.5.0": + version: 2.5.0 + resolution: "ts-api-utils@npm:2.5.0" peerDependencies: - typescript: ">=4.2.0" - checksum: 10/3ee44faa24410cd649b5c864e068d438aa437ef64e9e4a66a41646a6d3024d3097a695eeb3fb26ee364705d3cb9653a65756d009e6a53badb6066a5f447bf7ed + typescript: ">=4.8.4" + checksum: 10/d5f1936f5618c6ab6942a97b78802217540ced00e7501862ae1f578d9a3aa189fc06050e64cb8951d21f7088e5fd35f53d2bf0d0370a883861c7b05e993ebc44 languageName: node linkType: hard @@ -19416,34 +17612,33 @@ __metadata: languageName: unknown linkType: soft -"tsdown@npm:0.22.14": - version: 0.22.14 - resolution: "tsdown@npm:0.22.14" +"tsdown@npm:0.23.1": + version: 0.23.1 + resolution: "tsdown@npm:0.23.1" dependencies: - ansis: "npm:^4.3.1" - cac: "npm:^7.0.0" + cac: "npm:^7.0.1" defu: "npm:^6.1.7" - empathic: "npm:^2.0.1" - hookable: "npm:^6.1.1" - import-without-cache: "npm:^0.4.0" - obug: "npm:^2.1.4" - picomatch: "npm:^4.0.5" - rolldown: "npm:~1.2.0" - rolldown-plugin-dts: "npm:^0.27.13" - tinyexec: "npm:^1.2.4" + empathic: "npm:^2.1.0" + hookable: "npm:^6.1.2" + import-without-cache: "npm:^0.4.1" + obug: "npm:^3.0.0" + picomatch: "npm:^4.0.7" + rolldown: "npm:~1.2.13" + rolldown-plugin-dts: "npm:^0.28.7" + tinyexec: "npm:^1.3.1" tinyglobby: "npm:^0.2.17" tree-kill: "npm:^1.2.2" unconfig-core: "npm:^7.5.0" - verkit: "npm:^0.3.0" + verkit: "npm:^0.5.0" peerDependencies: "@arethetypeswrong/core": ^0.18.1 - "@tsdown/css": 0.22.14 - "@tsdown/exe": 0.22.14 + "@tsdown/css": 0.23.1 + "@tsdown/exe": 0.23.1 "@vitejs/devtools": "*" publint: ^0.3.8 tsx: "*" typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 - unplugin-unused: ^0.5.0 + unplugin-unused: ">=0.5.0" unrun: "*" peerDependenciesMeta: "@arethetypeswrong/core": @@ -19466,11 +17661,11 @@ __metadata: optional: true bin: tsdown: ./dist/run.mjs - checksum: 10/b3f2ab6ee28de09036251d175fb4b96fda214baacc8961eb2c679224d7ea66ffd7817446fc8b38aba18273ca96bcd0431e77783fa1927b7c1add7a61fb08d1cb + checksum: 10/e9fe64b4cee6f0b7526cbf011086859a80449e21539f6c5367587da9a3064b3103cd9466691ef81c37e0c128e4aa5d513a690200d2ce251d5b69e6b873cc7f15 languageName: node linkType: hard -"tslib@npm:1.14.1, tslib@npm:^1.8.1": +"tslib@npm:1.14.1": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 10/7dbf34e6f55c6492637adb81b555af5e3b4f9cc6b998fb440dac82d3b42bdc91560a35a5fb75e20e24a076c651438234da6743d139e4feabf0783f3cdfe1dddb @@ -19484,17 +17679,6 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: 10/ea036bec1dd024e309939ffd49fda7a351c0e87a1b8eb049570dd119d447250e2c56e0e6c00554e8205760e7417793fdebff752a46e573fbe07d4f375502a5b2 - languageName: node - linkType: hard - "tuf-js@npm:^4.1.0": version: 4.1.0 resolution: "tuf-js@npm:4.1.0" @@ -19551,27 +17735,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9 - languageName: node - linkType: hard - -"type-fest@npm:^0.6.0": - version: 0.6.0 - resolution: "type-fest@npm:0.6.0" - checksum: 10/9ecbf4ba279402b14c1a0614b6761bbe95626fab11377291fecd7e32b196109551e0350dcec6af74d97ced1b000ba8060a23eca33157091e642b409c2054ba82 - languageName: node - linkType: hard - -"type-fest@npm:^0.8.1": - version: 0.8.1 - resolution: "type-fest@npm:0.8.1" - checksum: 10/fd4a91bfb706aeeb0d326ebd2e9a8ea5263979e5dec8d16c3e469a5bd3a946e014a062ef76c02e3086d3d1c7209a56a20a4caafd0e9f9a5c2ab975084ea3d388 - languageName: node - linkType: hard - "type-fest@npm:^1.0.1": version: 1.4.0 resolution: "type-fest@npm:1.4.0" @@ -19624,7 +17787,7 @@ __metadata: languageName: node linkType: hard -"typed-array-buffer@npm:^1.0.2, typed-array-buffer@npm:^1.0.3": +"typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" dependencies: @@ -19635,19 +17798,6 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-length@npm:^1.0.1": - version: 1.0.1 - resolution: "typed-array-byte-length@npm:1.0.1" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10/e4a38329736fe6a73b52a09222d4a9e8de14caaa4ff6ad8e55217f6705b017d9815b7284c85065b3b8a7704e226ccff1372a72b78c2a5b6b71b7bf662308c903 - languageName: node - linkType: hard - "typed-array-byte-length@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-byte-length@npm:1.0.3" @@ -19661,46 +17811,17 @@ __metadata: languageName: node linkType: hard -"typed-array-byte-offset@npm:^1.0.2": - version: 1.0.2 - resolution: "typed-array-byte-offset@npm:1.0.2" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - checksum: 10/ac26d720ebb2aacbc45e231347c359e6649f52e0cfe0e76e62005912f8030d68e4cb7b725b1754e8fdd48e433cb68df5a8620a3e420ad1457d666e8b29bf9150 - languageName: node - linkType: hard - "typed-array-byte-offset@npm:^1.0.4": - version: 1.0.4 - resolution: "typed-array-byte-offset@npm:1.0.4" + version: 1.0.5 + resolution: "typed-array-byte-offset@npm:1.0.5" dependencies: available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.8" - for-each: "npm:^0.3.3" + call-bind: "npm:^1.0.9" + for-each: "npm:^0.3.5" gopd: "npm:^1.2.0" - has-proto: "npm:^1.2.0" is-typed-array: "npm:^1.1.15" - reflect.getprototypeof: "npm:^1.0.9" - checksum: 10/c2869aa584cdae24ecfd282f20a0f556b13a49a9d5bca1713370bb3c89dff0ccbc5ceb45cb5b784c98f4579e5e3e2a07e438c3a5b8294583e2bd4abbd5104fb5 - languageName: node - linkType: hard - -"typed-array-length@npm:^1.0.5": - version: 1.0.6 - resolution: "typed-array-length@npm:1.0.6" - dependencies: - call-bind: "npm:^1.0.7" - for-each: "npm:^0.3.3" - gopd: "npm:^1.0.1" - has-proto: "npm:^1.0.3" - is-typed-array: "npm:^1.1.13" - possible-typed-array-names: "npm:^1.0.0" - checksum: 10/05e96cf4ff836743ebfc593d86133b8c30e83172cb5d16c56814d7bacfed57ce97e87ada9c4b2156d9aaa59f75cdef01c25bd9081c7826e0b869afbefc3e8c39 + reflect.getprototypeof: "npm:^1.0.10" + checksum: 10/c7054706f6957a406c9546db88787ecd389f3e468182b1e05dd07175ca263fbf672c6f773074d38d1832a0cab20cdb2138a45f18960c828f4c9d46cac14a5696 languageName: node linkType: hard @@ -19718,59 +17839,50 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:^7.9.0": - version: 7.18.0 - resolution: "typescript-eslint@npm:7.18.0" +"typescript-eslint@npm:8.71.1": + version: 8.71.1 + resolution: "typescript-eslint@npm:8.71.1" dependencies: - "@typescript-eslint/eslint-plugin": "npm:7.18.0" - "@typescript-eslint/parser": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" + "@typescript-eslint/eslint-plugin": "npm:8.71.1" + "@typescript-eslint/parser": "npm:8.71.1" + "@typescript-eslint/typescript-estree": "npm:8.71.1" + "@typescript-eslint/utils": "npm:8.71.1" peerDependencies: - eslint: ^8.56.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/7c1ad00ecd7141d8631a99ff602cfabdab3d9f8a9be5b0282b8b3291125df1fc37c4baa13d1ef26562de8ed1393a5851a7e861ded0224127fe670ffae6fed6aa + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10/fd965ad7b08b66f92514bb2173bb82d7388782394f61d4f8442380eb41edcd67cb0468e233335489041bc4d7becb505f06e31e457d3ab1b2f0c3126e34d28d9f languageName: node linkType: hard -"typescript@npm:^4.7": - version: 4.9.5 - resolution: "typescript@npm:4.9.5" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10/458f7220ab11e0fc191514cc41be1707645ec9a8c2d609448a448e18c522cef9646f58728f6811185a4c35613dacdf6c98cf8965c88b3541d0288c47291e4300 - languageName: node - linkType: hard - -"typescript@npm:~5.9": - version: 5.9.3 - resolution: "typescript@npm:5.9.3" +"typescript@npm:@typescript/typescript6@6.0.2": + version: 6.0.2 + resolution: "@typescript/typescript6@npm:6.0.2" + dependencies: + "@typescript/old": "npm:typescript@^6" bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10/c089d9d3da2729fd4ac517f9b0e0485914c4b3c26f80dc0cffcb5de1719a17951e92425d55db59515c1a7ddab65808466debb864d0d56dcf43f27007d0709594 + tsc6: bin/tsc6 + checksum: 10/e214aa9b2783ac924498ebbb42a4419e1d8681acc10d26daa145e938d6da0ecde46ad36690fc4e9083a4b47cf73cdc83f2c2054f32e07f10920768956c2b00a1 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^4.7#optional!builtin": - version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#optional!builtin::version=4.9.5&hash=289587" +"typescript@patch:typescript@npm%3A>=5 <6.1.0#optional!builtin": + version: 6.0.3 + resolution: "typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/5659316360b5cc2d6f5931b346401fa534107b68b60179cf14970e27978f0936c1d5c46f4b5b8175f8cba0430f522b3ce355b4b724c0ea36ce6c0347fab25afd + checksum: 10/22b67a18dafedf9b1468b64ca20d9aa02ea61d449b65413d8aa6552aeb63f52ef369e86beb25b6b4c91a803d9726ee5c196f391a9b64201263263410a4223ee6 languageName: node linkType: hard -"typescript@patch:typescript@npm%3A~5.9#optional!builtin": - version: 5.9.3 - resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" +"typescript@patch:typescript@npm%3A@typescript/typescript6@6.0.2#optional!builtin": + version: 6.0.2 + resolution: "typescript@patch:@typescript/typescript6@npm%3A6.0.2#optional!builtin::version=6.0.2&hash=5786d5" + dependencies: + "@typescript/old": "npm:typescript@^6" bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10/696e1b017bc2635f4e0c94eb4435357701008e2f272f553d06e35b494b8ddc60aa221145e286c28ace0c89ee32827a28c2040e3a69bdc108b1a5dc8fb40b72e3 + tsc6: bin/tsc6 + checksum: 10/b190ec6b713b0fa95c059ff8019b740c17591ea83a3b60e6fe592d51d56d73c360b86abce48f616d25c39697cc5f4bb9efe8e2a231096f493758457cb175e11c languageName: node linkType: hard @@ -19788,6 +17900,13 @@ __metadata: languageName: node linkType: hard +"ua-is-frozen@npm:^0.1.2": + version: 0.1.2 + resolution: "ua-is-frozen@npm:0.1.2" + checksum: 10/0113bed77d437a3752323175f01057dd01911506225e9d33799799188a89a230ab63d2445b096d4399ea8eb94e3163608f7ac2425fb8edd0844d891490607e14 + languageName: node + linkType: hard + "ua-parser-js@npm:1.0.37, ua-parser-js@npm:^1.0.35": version: 1.0.37 resolution: "ua-parser-js@npm:1.0.37" @@ -19795,6 +17914,21 @@ __metadata: languageName: node linkType: hard +"ua-parser-js@npm:2.0.3": + version: 2.0.3 + resolution: "ua-parser-js@npm:2.0.3" + dependencies: + "@types/node-fetch": "npm:^2.6.12" + detect-europe-js: "npm:^0.1.2" + is-standalone-pwa: "npm:^0.1.1" + node-fetch: "npm:^2.7.0" + ua-is-frozen: "npm:^0.1.2" + bin: + ua-parser-js: script/cli.js + checksum: 10/f181f1c976d67a2a8cdd396f8c5cecc8bfe4ada7183e7ef06a81a09aa9dc98480048380240f6374189cf2ab7e6275b711f9732e26b7ed2a14f3e4fe3576b8842 + languageName: node + linkType: hard + "ufo@npm:^1.6.1, ufo@npm:^1.6.3": version: 1.6.3 resolution: "ufo@npm:1.6.3" @@ -19848,18 +17982,6 @@ __metadata: languageName: node linkType: hard -"unbox-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "unbox-primitive@npm:1.0.2" - dependencies: - call-bind: "npm:^1.0.2" - has-bigints: "npm:^1.0.2" - has-symbols: "npm:^1.0.3" - which-boxed-primitive: "npm:^1.0.2" - checksum: 10/06e1ee41c1095e37281cb71a975cb3350f7cb470a0665d2576f02cc9564f623bd90cfc0183693b8a7fdf2d242963dcc3010b509fa3ac683f540c765c0f3e7e43 - languageName: node - linkType: hard - "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -20031,7 +18153,7 @@ __metadata: languageName: node linkType: hard -"unrs-resolver@npm:^1.6.2": +"unrs-resolver@npm:^1.7.11": version: 1.12.2 resolution: "unrs-resolver@npm:1.12.2" dependencies: @@ -20196,6 +18318,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.3.3": + version: 1.3.4 + resolution: "update-browserslist-db@npm:1.3.4" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.1" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10/b572dffa5e87f5b31e2934fa72d91f537dc219fec97ee9d13d744ed2ded8d540118d3cd8fb10236b984106b27ac8a074a32d606ebe18b55b0377aad8854a7a86 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -20346,7 +18482,7 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-license@npm:^3.0.1, validate-npm-package-license@npm:^3.0.4": +"validate-npm-package-license@npm:^3.0.4": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" dependencies: @@ -20380,10 +18516,10 @@ __metadata: languageName: node linkType: hard -"verkit@npm:^0.3.0": - version: 0.3.2 - resolution: "verkit@npm:0.3.2" - checksum: 10/23e57c28094da170e381e27c020cddde0543fbac377b111c325a18440da4502d21c58446ef25794ecc1f2434df1d6297edf760910245ac5b90199a9bb18d8634 +"verkit@npm:^0.5.0": + version: 0.5.0 + resolution: "verkit@npm:0.5.0" + checksum: 10/82efcb8da3d8e20d8745a51ab6500046651297ff6446ea83ca83ee4d1f610347a4d4553adf9c74d483814ad6752e3eec8250313c32912f853ea34fd31203dbec languageName: node linkType: hard @@ -20623,19 +18759,6 @@ __metadata: languageName: node linkType: hard -"which-boxed-primitive@npm:^1.0.2": - version: 1.0.2 - resolution: "which-boxed-primitive@npm:1.0.2" - dependencies: - is-bigint: "npm:^1.0.1" - is-boolean-object: "npm:^1.1.0" - is-number-object: "npm:^1.0.4" - is-string: "npm:^1.0.5" - is-symbol: "npm:^1.0.3" - checksum: 10/9c7ca7855255f25ac47f4ce8b59c4cc33629e713fd7a165c9d77a2bb47bf3d9655a5664660c70337a3221cf96742f3589fae15a3a33639908d33e29aa2941efb - languageName: node - linkType: hard - "which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1": version: 1.1.1 resolution: "which-boxed-primitive@npm:1.1.1" @@ -20670,18 +18793,6 @@ __metadata: languageName: node linkType: hard -"which-collection@npm:^1.0.1": - version: 1.0.1 - resolution: "which-collection@npm:1.0.1" - dependencies: - is-map: "npm:^2.0.1" - is-set: "npm:^2.0.1" - is-weakmap: "npm:^2.0.1" - is-weakset: "npm:^2.0.1" - checksum: 10/85c95fcf92df7972ce66bed879e53d9dc752a30ef08e1ca4696df56bcf1c302e3b9965a39b04a20fa280a997fad6c170eb0b4d62435569b7f6c0bc7be910572b - languageName: node - linkType: hard - "which-collection@npm:^1.0.2": version: 1.0.2 resolution: "which-collection@npm:1.0.2" @@ -20701,24 +18812,9 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.16": - version: 1.1.20 - resolution: "which-typed-array@npm:1.1.20" - dependencies: - available-typed-arrays: "npm:^1.0.7" - call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.4" - for-each: "npm:^0.3.5" - get-proto: "npm:^1.0.1" - gopd: "npm:^1.2.0" - has-tostringtag: "npm:^1.0.2" - checksum: 10/e56da3fc995d330ff012f682476f7883c16b12d36c6717c87c7ca23eb5a5ef957fa89115dacb389b11a9b4e99d5dbe2d12689b4d5d08c050b5aed0eae385b840 - languageName: node - linkType: hard - -"which-typed-array@npm:^1.1.19": - version: 1.1.22 - resolution: "which-typed-array@npm:1.1.22" +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19": + version: 1.1.24 + resolution: "which-typed-array@npm:1.1.24" dependencies: available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.9" @@ -20727,7 +18823,7 @@ __metadata: get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-tostringtag: "npm:^1.0.2" - checksum: 10/59b0383347e2f3b0bc5be570c2dfae551b172a9c83e0a6b03c6e17401d6161dfa1d912c7657062fe9add254a0d3c25ef70593dbaec8fefa8714715ff69e0a3fc + checksum: 10/5b9abdc4ff046414312eac5c5b2fedab57b08979209882049fd2f4064166f8f97edd6831ff701cb6171313da19dbbd091ed46f30712e733e9b166f5f5388159e languageName: node linkType: hard @@ -20962,6 +19058,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.9.1": + version: 2.9.1 + resolution: "yaml@npm:2.9.1" + bin: + yaml: bin.mjs + checksum: 10/123c5e56a26f4962d3d5954971b2071a533d17041e00ae9ff6a5e634aed2503639bbdeea143b1610eac29613aad95a3a1d10f5fbda87b92203c039ce63934295 + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3" @@ -21055,105 +19160,86 @@ __metadata: languageName: node linkType: hard -"yuku-ast@npm:^0.8.0, yuku-ast@npm:^0.8.7": - version: 0.8.7 - resolution: "yuku-ast@npm:0.8.7" +"yuku-ast@npm:^0.19.0": + version: 0.19.0 + resolution: "yuku-ast@npm:0.19.0" dependencies: - "@yuku-toolchain/types": "npm:^0.8.7" - checksum: 10/93303e4851eadd4e02a9b09497758fab7f2e131445fa18447096c20fb715a7346cf247f0d7d8c0f34595d8214b14bcad8c83248d5a91994a4825da761f3bb4d2 + "@yuku-toolchain/types": "npm:^0.19.0" + checksum: 10/e73ef00316f9719286fff391b3b6cca2bc520c7528459ee5ae1611fb88439b8a597695bcf07dd4aa028e3f9573ace584a098dcb9ae6fa512817baef553595248 languageName: node linkType: hard -"yuku-codegen@npm:^0.8.0": - version: 0.8.7 - resolution: "yuku-codegen@npm:0.8.7" +"yuku-codegen@npm:^0.19.0": + version: 0.19.0 + resolution: "yuku-codegen@npm:0.19.0" dependencies: - "@yuku-codegen/binding-android-arm64": "npm:0.8.7" - "@yuku-codegen/binding-darwin-arm64": "npm:0.8.7" - "@yuku-codegen/binding-darwin-x64": "npm:0.8.7" - "@yuku-codegen/binding-freebsd-x64": "npm:0.8.7" - "@yuku-codegen/binding-linux-arm-gnu": "npm:0.8.7" - "@yuku-codegen/binding-linux-arm-musl": "npm:0.8.7" - "@yuku-codegen/binding-linux-arm64-gnu": "npm:0.8.7" - "@yuku-codegen/binding-linux-arm64-musl": "npm:0.8.7" - "@yuku-codegen/binding-linux-x64-gnu": "npm:0.8.7" - "@yuku-codegen/binding-linux-x64-musl": "npm:0.8.7" - "@yuku-codegen/binding-win32-arm64": "npm:0.8.7" - "@yuku-codegen/binding-win32-x64": "npm:0.8.7" - "@yuku-toolchain/types": "npm:^0.8.7" - dependenciesMeta: - "@yuku-codegen/binding-android-arm64": - optional: true - "@yuku-codegen/binding-darwin-arm64": - optional: true - "@yuku-codegen/binding-darwin-x64": - optional: true - "@yuku-codegen/binding-freebsd-x64": - optional: true - "@yuku-codegen/binding-linux-arm-gnu": - optional: true - "@yuku-codegen/binding-linux-arm-musl": - optional: true - "@yuku-codegen/binding-linux-arm64-gnu": - optional: true - "@yuku-codegen/binding-linux-arm64-musl": - optional: true - "@yuku-codegen/binding-linux-x64-gnu": - optional: true - "@yuku-codegen/binding-linux-x64-musl": - optional: true - "@yuku-codegen/binding-win32-arm64": - optional: true - "@yuku-codegen/binding-win32-x64": - optional: true - checksum: 10/01bebf5f87947790d6494c359f384412fcae7b37aaf748b6553ae084a906e4cd9bb656ac7f95ac98714f7a61dd06297a3fe2a9d5812b46191bbce48caafbc7c1 + "@yuku-toolchain/types": "npm:^0.19.0" + checksum: 10/5592a1619dc84ac3670eb58bda6c6b6e32eb61504e6125e61175779dfe0193fc5ad0ccf9734f87274f7cc46b5247ac8a14aebae7eecf1aeec7e2a7c623bdcfbc languageName: node linkType: hard -"yuku-parser@npm:^0.8.0": - version: 0.8.7 - resolution: "yuku-parser@npm:0.8.7" +"yuku-core@npm:0.19.0": + version: 0.19.0 + resolution: "yuku-core@npm:0.19.0" dependencies: - "@yuku-parser/binding-android-arm64": "npm:0.8.7" - "@yuku-parser/binding-darwin-arm64": "npm:0.8.7" - "@yuku-parser/binding-darwin-x64": "npm:0.8.7" - "@yuku-parser/binding-freebsd-x64": "npm:0.8.7" - "@yuku-parser/binding-linux-arm-gnu": "npm:0.8.7" - "@yuku-parser/binding-linux-arm-musl": "npm:0.8.7" - "@yuku-parser/binding-linux-arm64-gnu": "npm:0.8.7" - "@yuku-parser/binding-linux-arm64-musl": "npm:0.8.7" - "@yuku-parser/binding-linux-x64-gnu": "npm:0.8.7" - "@yuku-parser/binding-linux-x64-musl": "npm:0.8.7" - "@yuku-parser/binding-win32-arm64": "npm:0.8.7" - "@yuku-parser/binding-win32-x64": "npm:0.8.7" - "@yuku-toolchain/types": "npm:^0.8.7" - yuku-ast: "npm:^0.8.7" + "@yuku-core/binding-android-arm64": "npm:0.19.0" + "@yuku-core/binding-darwin-arm64": "npm:0.19.0" + "@yuku-core/binding-darwin-x64": "npm:0.19.0" + "@yuku-core/binding-freebsd-x64": "npm:0.19.0" + "@yuku-core/binding-linux-arm-gnu": "npm:0.19.0" + "@yuku-core/binding-linux-arm-musl": "npm:0.19.0" + "@yuku-core/binding-linux-arm64-gnu": "npm:0.19.0" + "@yuku-core/binding-linux-arm64-musl": "npm:0.19.0" + "@yuku-core/binding-linux-x64-gnu": "npm:0.19.0" + "@yuku-core/binding-linux-x64-musl": "npm:0.19.0" + "@yuku-core/binding-win32-arm64": "npm:0.19.0" + "@yuku-core/binding-win32-x64": "npm:0.19.0" + "@yuku-toolchain/types": "npm:^0.19.0" dependenciesMeta: - "@yuku-parser/binding-android-arm64": + "@yuku-core/binding-android-arm64": optional: true - "@yuku-parser/binding-darwin-arm64": + "@yuku-core/binding-darwin-arm64": optional: true - "@yuku-parser/binding-darwin-x64": + "@yuku-core/binding-darwin-x64": optional: true - "@yuku-parser/binding-freebsd-x64": + "@yuku-core/binding-freebsd-x64": optional: true - "@yuku-parser/binding-linux-arm-gnu": + "@yuku-core/binding-linux-arm-gnu": optional: true - "@yuku-parser/binding-linux-arm-musl": + "@yuku-core/binding-linux-arm-musl": optional: true - "@yuku-parser/binding-linux-arm64-gnu": + "@yuku-core/binding-linux-arm64-gnu": optional: true - "@yuku-parser/binding-linux-arm64-musl": + "@yuku-core/binding-linux-arm64-musl": optional: true - "@yuku-parser/binding-linux-x64-gnu": + "@yuku-core/binding-linux-x64-gnu": optional: true - "@yuku-parser/binding-linux-x64-musl": + "@yuku-core/binding-linux-x64-musl": optional: true - "@yuku-parser/binding-win32-arm64": + "@yuku-core/binding-win32-arm64": optional: true - "@yuku-parser/binding-win32-x64": + "@yuku-core/binding-win32-x64": optional: true - checksum: 10/875ac80f0a297712a23984648a36c729c16242356d805dab5addee82986a0a5008a10bc966cddb257842c06ff98bcb3a9366a7f8d1654287042b29cdac8ddba2 + checksum: 10/d642d445520efd746b78fdb248b7748603f3399f127d7b035ffa2e28a86bbfac2f74911bb909f3e7f5fbc2db889b5a240d3898243171e080832afbb480268dd5 + languageName: node + linkType: hard + +"yuku-parser@npm:^0.19.0": + version: 0.19.0 + resolution: "yuku-parser@npm:0.19.0" + dependencies: + "@yuku-toolchain/types": "npm:^0.19.0" + yuku-core: "npm:0.19.0" + checksum: 10/ba84acfd8fa56f1c7f21512e93d6bde362835024acadabb7d9c1288d4eaf33202bdabecfc63f46cb5e9b6eb8bceee4b4cdb076a704aedf1e8d1ec59c06c3c45b + languageName: node + linkType: hard + +"zod-validation-error@npm:^3.5.0 || ^4.0.0": + version: 4.0.2 + resolution: "zod-validation-error@npm:4.0.2" + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + checksum: 10/5e35ca8ebb4602dcb526e122d7e9fca695c4a479bd97535f3400a732d49160f24f7213a9ed64986fc9dc3a2e8a6c4e1241ec0c4d8a4e3e69ea91a0328ded2192 languageName: node linkType: hard @@ -21171,6 +19257,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.25.0 || ^4.0.0": + version: 4.6.6 + resolution: "zod@npm:4.6.6" + checksum: 10/ce628fb33400b531f48b63ad1bd9b5ab95ec3ac60d4e8025892d90af9ca5d03b168aaaf74071928345ad1b1bcd735a7d5cf33230ece7de885240bb0f2b7bb492 + languageName: node + linkType: hard + "zustand@npm:5.0.0": version: 5.0.0 resolution: "zustand@npm:5.0.0"