diff --git a/.changeset/sixty-steaks-smile.md b/.changeset/sixty-steaks-smile.md new file mode 100644 index 000000000..d9359329c --- /dev/null +++ b/.changeset/sixty-steaks-smile.md @@ -0,0 +1,5 @@ +--- +'hub': patch +--- + +test(hub): support e2e anvil deposit flows in deposit hooks diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d9ba23244..deeb39f34 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -23,9 +23,6 @@ on: required: false default: 'https://hub.status.network' -env: - METAMASK_VERSION: '13.18.1' - jobs: e2e: name: E2E Tests @@ -70,6 +67,10 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Read MetaMask version + id: metamask + run: echo "version=$(node -p 'require("./e2e/package.json").config.metamaskVersion')" >> "$GITHUB_OUTPUT" + - name: Install Playwright browsers run: cd e2e && pnpm exec playwright install chromium --with-deps @@ -78,12 +79,18 @@ jobs: uses: actions/cache@v4 with: path: e2e/.extensions/metamask - key: metamask-v${{ env.METAMASK_VERSION }}-${{ hashFiles('e2e/download-metamask-extension.ts') }} + key: metamask-v${{ steps.metamask.outputs.version }}-${{ hashFiles('e2e/download-metamask-extension.ts') }} - name: Download MetaMask extension if: steps.metamask-cache.outputs.cache-hit != 'true' run: cd e2e && pnpm setup:metamask + - name: Lint and typecheck E2E + run: cd e2e && pnpm lint && pnpm typecheck + + - name: Start Anvil forks + run: cd e2e && pnpm anvil:up + - name: Run E2E tests run: cd e2e && xvfb-run --auto-servernum -- pnpm test env: @@ -92,6 +99,10 @@ jobs: BASE_URL: ${{ steps.url.outputs.url }} CI: true + - name: Stop Anvil forks + if: always() + run: cd e2e && pnpm anvil:down + - name: Upload test report uses: actions/upload-artifact@v4 if: always() diff --git a/apps/hub/.env b/apps/hub/.env index 1c7130c27..7b04977a0 100644 --- a/apps/hub/.env +++ b/apps/hub/.env @@ -18,4 +18,8 @@ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="" NEXT_PUBLIC_STATUS_NETWORK_API_URL="http://localhost:3001/api/v1" -NEXT_PUBLIC_STATUS_API_URL="http://localhost:3030" \ No newline at end of file +NEXT_PUBLIC_STATUS_API_URL="http://localhost:3030" + +# Optional: override RPC endpoints (defaults to Status API proxy) +# NEXT_PUBLIC_MAINNET_RPC_URL= +# NEXT_PUBLIC_LINEA_RPC_URL= \ No newline at end of file diff --git a/apps/hub/README.md b/apps/hub/README.md index c40d4acbc..e9b034649 100644 --- a/apps/hub/README.md +++ b/apps/hub/README.md @@ -21,7 +21,7 @@ Then, pull environment variables: > \[!NOTE] > `NEXT_PUBLIC_STATUS_NETWORK_API_URL`: Base URL for the Status Network API used by the hub for auth, current user (`/auth/me`), karma/sybil (proof-of-work), predeposit vaults APR, and captcha. You can run this API locally by cloning the sn-api repo . If you do so don't forget to change the value of this variable to the local API's URL. > -> `NEXT_PUBLIC_STATUS_API_URL`: Base URL for the Status API used by the hub to fetch token exchange rates (market data). +> `NEXT_PUBLIC_STATUS_API_URL`: Base URL for the Status API used by the hub to fetch token exchange rates (market data) and as the default RPC proxy for Mainnet/Linea chain interactions (`/api/trpc/rpc.proxy`). If this variable is empty, wagmi's built-in public RPCs are used as fallback. You can override RPC endpoints per-chain with `NEXT_PUBLIC_MAINNET_RPC_URL` and `NEXT_PUBLIC_LINEA_RPC_URL`. > You can run this API locally by running `pnpm dev` the root or in the [api](https://github.com/status-im/status-web/tree/main/apps/api) project. If you do so don't forget to change the value of this variable to `http://localhost:3030`. Start the development server: diff --git a/apps/hub/src/app/_hooks/useDepositFlow.ts b/apps/hub/src/app/_hooks/useDepositFlow.ts index 8d3f4fe86..803f4481e 100644 --- a/apps/hub/src/app/_hooks/useDepositFlow.ts +++ b/apps/hub/src/app/_hooks/useDepositFlow.ts @@ -74,7 +74,10 @@ export function useDepositFlow({ chainId: vault.chainId, }) - const { data: depositLimits } = usePreDepositLimits({ vault }) + const { data: depositLimits } = usePreDepositLimits({ + vault, + enabled: !isGUSD, + }) const maxDeposit = isGUSD ? undefined : depositLimits?.maxDeposit const minDeposit = isGUSD ? undefined : depositLimits?.minDeposit diff --git a/apps/hub/src/app/_hooks/useGUSDPreDeposit.ts b/apps/hub/src/app/_hooks/useGUSDPreDeposit.ts index b64055a48..0a2c551c2 100644 --- a/apps/hub/src/app/_hooks/useGUSDPreDeposit.ts +++ b/apps/hub/src/app/_hooks/useGUSDPreDeposit.ts @@ -104,7 +104,7 @@ export function useGUSDPreDeposit(): UseGUSDPreDepositReturn { const remoteRecipient = addressToBytes32(address) sendPreDepositEvent({ - type: 'START_APPROVE_TOKEN', + type: 'START_PRE_DEPOSIT', amount, }) @@ -116,27 +116,12 @@ export function useGUSDPreDeposit(): UseGUSDPreDepositReturn { ] as const try { - const estimatedGas = await publicClient?.estimateContractGas({ - address: GENERIC_DEPOSITOR.address, - abi: GENERIC_DEPOSITOR.abi, - functionName: 'depositAndPredeposit', - args: contractArgs, - account: address, - }) - - const GAS_LIMIT_MULTIPLIER_PERCENT = 120n - - const gasLimit = estimatedGas - ? (estimatedGas * GAS_LIMIT_MULTIPLIER_PERCENT) / 100n - : undefined - const hash = await writeContractAsync({ address: GENERIC_DEPOSITOR.address, abi: GENERIC_DEPOSITOR.abi, functionName: 'depositAndPredeposit', args: contractArgs, chainId: mainnet.id, - gas: gasLimit, }) sendPreDepositEvent({ type: 'EXECUTE' }) diff --git a/apps/hub/src/app/_hooks/usePreDepositLimits.ts b/apps/hub/src/app/_hooks/usePreDepositLimits.ts index b1fb98345..c87ccb41e 100644 --- a/apps/hub/src/app/_hooks/usePreDepositLimits.ts +++ b/apps/hub/src/app/_hooks/usePreDepositLimits.ts @@ -12,6 +12,8 @@ import type { Vault } from '~constants/index' export interface MinPreDepositValueParams { /** Vault to query Min deposit for */ vault: Vault + /** Whether to enable the query (default: true) */ + enabled?: boolean } // ============================================================================ @@ -83,14 +85,17 @@ export interface MinPreDepositValueParams { * ``` * */ -export function usePreDepositLimits({ vault }: MinPreDepositValueParams) { +export function usePreDepositLimits({ + vault, + enabled = true, +}: MinPreDepositValueParams) { return useReadContract({ abi: vault.abi, address: vault.address, functionName: 'getDepositLimits', chainId: vault.chainId, query: { - enabled: vault !== null, + enabled: enabled && vault !== null, select: data => { return { minDeposit: data[0], diff --git a/e2e/.env.example b/e2e/.env.example index 4ade5334b..3c66ac163 100644 --- a/e2e/.env.example +++ b/e2e/.env.example @@ -16,10 +16,20 @@ WALLET_PASSWORD= # MetaMask Extension # ============================================================================ METAMASK_EXTENSION_PATH=.extensions/metamask -METAMASK_VERSION=13.18.1 +# Override MetaMask version (default: package.json → config.metamaskVersion) +# METAMASK_VERSION=13.18.1 # ============================================================================ -# Network Configuration -# ============================================================================ -STATUS_SEPOLIA_RPC_URL=https://public.sepolia.rpc.status.network -STATUS_SEPOLIA_CHAIN_ID=1660990954 +# Anvil Local Forks (used by docker-compose.anvil.yml + test fixtures) +# ============================================================================ +# Fork RPC endpoints (override for custom Anvil targets) +# ANVIL_MAINNET_RPC=http://localhost:8547 +# ANVIL_LINEA_RPC=http://localhost:8546 +# Docker Compose port mappings (must match ANVIL_*_RPC if both are set) +# MAINNET_FORK_PORT=8547 +# LINEA_FORK_PORT=8546 +# Fork source URLs (only used by Docker Compose) +# MAINNET_FORK_URL=https://ethereum-rpc.publicnode.com +# LINEA_FORK_URL=https://rpc.linea.build +# Auto-derived from WALLET_SEED_PHRASE if not set +# WALLET_ADDRESS= diff --git a/e2e/.gitignore b/e2e/.gitignore index 26b7ef759..46711921b 100644 --- a/e2e/.gitignore +++ b/e2e/.gitignore @@ -1,3 +1,6 @@ +# Dependencies +node_modules/ + # Test results test-results/ playwright-report/ @@ -8,3 +11,17 @@ extensions/ # Browser profiles .pw-chromium-profile/ + +# Environment files +.env +.env.local + +# TypeScript build +*.tsbuildinfo +dist/ + +# npm lockfile (project uses pnpm) +package-lock.json + +# OS files +.DS_Store diff --git a/e2e/README.md b/e2e/README.md index 61f82a2cc..a01fe893a 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -2,14 +2,17 @@ Playwright + TypeScript E2E tests for [Status Network Hub](https://hub.status.network). -## Quick Start +**Supported platforms:** macOS, Linux. Windows is supported only via [WSL2](https://learn.microsoft.com/en-us/windows/wsl/install) — run all commands inside a WSL2 distro (Ubuntu recommended). Native Windows is not supported because the test suite relies on Chromium extension loading, POSIX paths, and Docker `linux/amd64` images. -```bash -# From the monorepo root: -pnpm install +## Getting Started +First, follow the [root README](../../README.md#getting-started) to clone the repo, initialize submodules, and install dependencies. + +```bash +pnpm dev cd e2e -pnpm exec playwright install chromium +pnpm install +pnpm dlx playwright install chromium # Configure environment cp .env.example .env @@ -28,28 +31,215 @@ pnpm test:smoke pnpm test # All tests pnpm test:smoke # Smoke tests (@smoke tag, headless) pnpm test:wallet # Wallet tests (@wallet tag, headed + MetaMask) +pnpm test:anvil # Anvil deposit tests (starts Docker, runs tests, stops) +pnpm anvil:up # Start Anvil Docker forks only +pnpm anvil:down # Stop Anvil Docker forks pnpm test:headed # All tests with visible browser pnpm test:debug # Step-by-step debug mode pnpm test:ui # Interactive Playwright UI pnpm test:report # Open last HTML report -pnpm lint # ESLint -pnpm typecheck # TypeScript type check -pnpm format # Prettier formatting +pnpm lint # TypeScript type check pnpm clean # Remove test artifacts and extensions ``` Run a specific file: ```bash -pnpm exec playwright test tests/hub/pre-deposits/pre-deposits-display.spec.ts +pnpm dlx playwright test tests/hub/pre-deposits/pre-deposits-display.spec.ts ``` ## Tags -Tests use Playwright tags (`@smoke`, `@wallet`) mapped to projects in `playwright.config.ts`: +Tests use Playwright tags (`@smoke`, `@wallet`, `@anvil`) mapped to projects in `playwright.config.ts`: ```ts test('my test', { tag: '@smoke' }, async ({ page }) => { // ... }) ``` + +| Tag | Project | Description | +|-----|---------|-------------| +| `@smoke` | `smoke` | Basic page-level checks, no wallet needed | +| `@wallet` | `wallet-flows` | MetaMask wallet interactions (connect, switch network) | +| `@anvil` | `anvil-deposits` | Full deposit flows against local Anvil forks | + +## Architecture + +### Project Structure + +``` +e2e/ +├── src/ +│ ├── constants/ # Timeout, viewport, RPC host, vault constants +│ ├── fixtures/ # Playwright fixture hierarchy +│ │ ├── base.fixture.ts # Base fixture (shared config) +│ │ ├── metamask.fixture.ts # MetaMask browser launch +│ │ ├── wallet-connected.fixture.ts # Wallet connection flow +│ │ └── anvil.fixture.ts # Anvil fork + deposit fixtures +│ ├── helpers/ +│ │ ├── anvil-rpc.ts # AnvilRpcHelper (fund, snapshot, revert) +│ │ ├── service-worker-patch.ts # MetaMask SW fetch interceptor +│ │ ├── stx-patcher.ts # Smart Transactions disabler +│ │ └── hub-test-helpers.ts # Hub page interaction utilities +│ ├── pages/ # Page Object Models +│ │ ├── hub/ # Hub app pages (pre-deposits, deposit modal) +│ │ └── metamask/ # MetaMask pages (onboarding, notification) +│ └── config/ +│ └── env.ts # Environment config loader +├── tests/ +│ ├── hub/pre-deposits/ # Pre-deposit test specs +│ └── metamask/ # MetaMask extension tests +├── playwright.config.ts +├── docker-compose.anvil.yml +└── .env.example +``` + +### Fixture Hierarchy + +``` +base.fixture (shared config, env) + └── metamask.fixture (browser launch with MetaMask extension) + └── wallet-connected.fixture (dApp connection, hub page) + └── anvil.fixture (Anvil forks, SW patching, STX disable, + snapshot/revert, page objects) +``` + +The anvil fixture: +1. Patches MetaMask's service worker to redirect RPC calls to local Anvil forks +2. Disables Smart Transactions (STX) via file patching + SW fetch interception +3. Manages Anvil snapshot/revert for test isolation +4. Provides `anvilRpc`, `preDepositsPage`, `depositModal` fixtures + +### How Anvil Tests Work + +Anvil tests run against local Ethereum/Linea forks (via [Foundry Anvil](https://book.getfoundry.sh/anvil/)): + +1. **Docker starts two Anvil instances** — mainnet fork (port 8547) and Linea fork (port 8546) +2. **MetaMask SW is patched** — a fetch interceptor redirects RPC calls from real networks to local Anvil +3. **STX is disabled** — Smart Transactions are patched out to prevent MetaMask from using its own tx submission pipeline +4. **Each test**: fund wallet → navigate → deposit → verify, with snapshot/revert between tests + +Tests run with `workers: 1` because: +- MetaMask extension files are patched on disk — concurrent writes would conflict +- Anvil fork state (snapshot/revert) is shared across tests +- Module-level snapshot cache assumes single-worker execution + +## Anvil / Docker Setup + +### Prerequisites + +- **Docker** (Docker Desktop or Docker Engine) +- **Apple Silicon**: The Anvil Docker image defaults to `linux/amd64`, which requires Rosetta emulation. This is handled automatically by Docker Desktop with Rosetta enabled. If you experience issues: + ```bash + # Option 1: Enable Rosetta in Docker Desktop + # Settings → General → "Use Rosetta for x86_64/amd64 emulation on Apple Silicon" + + # Option 2: Override platform (if using native arm64 Foundry image) + DOCKER_PLATFORM=linux/arm64 pnpm anvil:up + ``` + +### Running Anvil Tests Locally + +```bash +cd e2e + +# 1. Start Anvil forks (Docker) +pnpm anvil:up + +# 2. Wait for health checks to pass (~10-30s) +docker compose -f docker-compose.anvil.yml ps + +# 3. Run tests +pnpm test:anvil + +# 4. Stop Anvil (automatic with test:anvil, or manual) +pnpm anvil:down +``` + +### Custom Fork URLs + +By default, Anvil forks from public RPCs. For faster/more reliable forks, set private RPC endpoints: + +```bash +# In .env or .env.local +MAINNET_FORK_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY +LINEA_FORK_URL=https://linea-mainnet.g.alchemy.com/v2/YOUR_KEY +``` + +### Hub RPC Configuration + +The Hub app (`apps/hub`) uses the Status API proxy as the default RPC transport. For Anvil E2E tests, the MetaMask service worker is patched to redirect RPC calls to local forks — no changes to Hub env vars are needed. + +If you need to point the Hub app itself at a custom RPC (e.g. for local development without the proxy), set these optional env vars in `apps/hub/.env.local`: + +```bash +NEXT_PUBLIC_MAINNET_RPC_URL=https://mainnet.infura.io/v3/YOUR_KEY +NEXT_PUBLIC_LINEA_RPC_URL=https://rpc.linea.build +``` + +## CI Setup + +### GitHub Secrets + +The E2E workflow requires two GitHub Actions secrets: + +| Secret | Description | +|--------|-------------| +| `E2E_WALLET_SEED_PHRASE` | BIP-39 mnemonic for the test wallet. **Use a dedicated test-only wallet** — never use a wallet holding real funds. | +| `E2E_WALLET_PASSWORD` | Password for MetaMask unlock during tests. Any value works (e.g. `TestPassword123!`). | + +To configure: +1. Go to repository **Settings → Secrets and variables → Actions** +2. Click **New repository secret** +3. Add `E2E_WALLET_SEED_PHRASE` and `E2E_WALLET_PASSWORD` + +### CI Triggers + +The E2E workflow (`.github/workflows/e2e.yml`) runs on: +- **Vercel deployment success** — tests the preview URL for Hub deployments +- **Push to `main`** — when `e2e/`, `apps/hub/`, or shared packages change +- **Manual dispatch** — with optional custom `base_url` + +### What CI Runs + +1. Install dependencies + Playwright browsers +2. Download and cache MetaMask extension +3. Lint + typecheck the e2e project +4. Start Anvil Docker forks +5. Run all tests (smoke + wallet + anvil) +6. Upload test report and failure artifacts + +## Debugging + +```bash +# Step-by-step debug mode (pauses at each action) +pnpm test:debug + +# Run with visible browser +pnpm test:headed + +# Interactive Playwright UI (pick and run tests) +pnpm test:ui + +# Run a single test file +pnpm exec playwright test tests/hub/pre-deposits/weth-deposit.spec.ts + +# View last test report +pnpm test:report + +# Check Anvil fork health +curl -s -X POST http://localhost:8547 \ + -H 'Content-Type: application/json' \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' +``` + +### Common Issues + +| Issue | Solution | +|-------|----------| +| MetaMask extension not found | Run `pnpm setup:metamask` to download it | +| Anvil connection refused | Run `pnpm anvil:up` and wait for health checks | +| Tests timeout on Apple Silicon | Enable Rosetta in Docker Desktop (see above) | +| `wallet_addEthereumChain` popup | The fixture blocks this via `addInitScript`; if it appears, check fixture setup | +| Smart Transactions interfering | STX is disabled via file patching; update patterns if MetaMask version changes | diff --git a/e2e/docker-compose.anvil.yml b/e2e/docker-compose.anvil.yml new file mode 100644 index 000000000..877aef028 --- /dev/null +++ b/e2e/docker-compose.anvil.yml @@ -0,0 +1,65 @@ +name: status-web-anvil + +services: + erpc: + image: ghcr.io/erpc/erpc:latest + platform: ${DOCKER_PLATFORM:-linux/amd64} + volumes: + - ./erpc.yaml:/erpc.yaml:ro + environment: + MAINNET_FORK_URL: ${MAINNET_FORK_URL:-https://ethereum-rpc.publicnode.com} + LINEA_FORK_URL: ${LINEA_FORK_URL:-https://rpc.linea.build} + + anvil-mainnet: + image: ghcr.io/foundry-rs/foundry:v1.4.0 + platform: ${DOCKER_PLATFORM:-linux/amd64} + entrypoint: anvil + depends_on: + erpc: + condition: service_started + restart: on-failure + command: + - --host=0.0.0.0 + - --port=8545 + - --fork-url=http://erpc:4000/main/evm/1 + - --chain-id=1 + - --silent + - --timeout=15000 + - --retries=2 + - --no-rate-limit + ports: + - '${MAINNET_FORK_PORT:-8547}:8545' + healthcheck: + test: + ['CMD', 'cast', 'block-number', '--rpc-url', 'http://localhost:8545'] + start_period: 30s + interval: 2s + timeout: 5s + retries: 15 + + anvil-linea: + image: ghcr.io/foundry-rs/foundry:v1.4.0 + platform: ${DOCKER_PLATFORM:-linux/amd64} + entrypoint: anvil + depends_on: + erpc: + condition: service_started + restart: on-failure + command: + - --host=0.0.0.0 + - --port=8545 + - --fork-url=http://erpc:4000/main/evm/59144 + - --chain-id=59144 + - --silent + - --timeout=15000 + - --retries=2 + - --no-rate-limit + ports: + - '${LINEA_FORK_PORT:-8546}:8545' + healthcheck: + test: + ['CMD', 'cast', 'block-number', '--rpc-url', 'http://localhost:8545'] + start_period: 30s + interval: 2s + timeout: 5s + retries: 15 diff --git a/e2e/download-metamask-extension.ts b/e2e/download-metamask-extension.ts index e63e117e5..c5100bc5c 100644 --- a/e2e/download-metamask-extension.ts +++ b/e2e/download-metamask-extension.ts @@ -3,7 +3,12 @@ import fs from 'node:fs' import os from 'node:os' import path from 'node:path' -const METAMASK_VERSION = process.env.METAMASK_VERSION ?? '13.18.1' +// Read default version from package.json (single source of truth) +const pkg = JSON.parse( + fs.readFileSync(path.resolve(import.meta.dirname, 'package.json'), 'utf-8'), +) as { config: { metamaskVersion: string } } +const METAMASK_VERSION = + process.env.METAMASK_VERSION ?? pkg.config.metamaskVersion const defaultDest = path.resolve(process.cwd(), '.extensions', 'metamask') const envPath = process.env.METAMASK_EXTENSION_PATH diff --git a/e2e/erpc.yaml b/e2e/erpc.yaml new file mode 100644 index 000000000..4e133647a --- /dev/null +++ b/e2e/erpc.yaml @@ -0,0 +1,46 @@ +logLevel: warn + +server: + httpHostV4: 0.0.0.0 + httpPortV4: 4000 + +database: + evmJsonRpcCache: + connectors: + - id: memory-cache + driver: memory + memory: + maxItems: 1000000 + policies: + # Cache immutable data permanently + - network: "evm:1|evm:59144" + method: "eth_getCode|eth_getBlockByNumber|eth_getBlockByHash|eth_getTransactionReceipt|eth_chainId" + finality: finalized + connector: memory-cache + ttl: 0 + # Cache state queries with short TTL + - network: "evm:1|evm:59144" + method: "eth_getStorageAt|eth_getBalance|eth_getTransactionCount" + connector: memory-cache + ttl: 60s + +projects: + - id: main + networks: + - architecture: evm + evm: + chainId: 1 + - architecture: evm + evm: + chainId: 59144 + upstreams: + - id: mainnet-primary + type: evm + endpoint: ${MAINNET_FORK_URL} + evm: + chainId: 1 + - id: linea-primary + type: evm + endpoint: ${LINEA_FORK_URL} + evm: + chainId: 59144 diff --git a/e2e/eslint.config.mjs b/e2e/eslint.config.mjs index c2c668922..71f9592f8 100644 --- a/e2e/eslint.config.mjs +++ b/e2e/eslint.config.mjs @@ -22,7 +22,6 @@ export default [ }, rules: { 'no-restricted-globals': 'off', - '@typescript-eslint/no-explicit-any': 'off', 'react-hooks/rules-of-hooks': 'off', 'no-empty-pattern': 'off', }, diff --git a/e2e/package.json b/e2e/package.json index 1a5f3ea4c..3a2c5cc44 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -2,11 +2,19 @@ "name": "e2e", "version": "0.1.1", "private": true, + "workspaces": { + "packages": [ + "packages/eslint-config" + ] + }, "type": "module", "scripts": { "test": "playwright test", "test:smoke": "playwright test --project=smoke", "test:wallet": "playwright test --project=wallet-flows", + "anvil:up": "test -f .env.local && ENV_FILES='--env-file .env --env-file .env.local' || ENV_FILES='--env-file .env'; docker compose $ENV_FILES -f docker-compose.anvil.yml up -d --wait", + "anvil:down": "test -f .env.local && ENV_FILES='--env-file .env --env-file .env.local' || ENV_FILES='--env-file .env'; docker compose $ENV_FILES -f docker-compose.anvil.yml down", + "test:anvil": "pnpm anvil:up && playwright test --project=anvil-deposits; EXIT=$?; pnpm anvil:down; exit $EXIT", "test:headed": "playwright test --headed", "test:debug": "playwright test --debug", "test:ui": "playwright test --ui", @@ -25,7 +33,10 @@ "eslint": "^9.14.0", "globals": "^15.12.0", "prettier": "^3.3.3", - "tsx": "^4.19.0" + "rimraf": "^5.0.0", + "tsx": "^4.19.0", + "typescript": "^5.7.0", + "viem": "^2.46.3" }, "lint-staged": { "*.ts": [ @@ -33,6 +44,9 @@ "prettier --write" ] }, + "config": { + "metamaskVersion": "13.18.1" + }, "engines": { "node": "22.x" } diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index b1183231c..40fc2f283 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -54,5 +54,13 @@ export default defineConfig({ headless: false, }, }, + { + name: 'anvil-deposits', + grep: /@anvil/, + timeout: 180_000, + use: { + headless: false, + }, + }, ], }) diff --git a/e2e/pnpm-lock.yaml b/e2e/pnpm-lock.yaml new file mode 100644 index 000000000..fdd079b3b --- /dev/null +++ b/e2e/pnpm-lock.yaml @@ -0,0 +1,4034 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@playwright/test': + specifier: ^1.50.0 + version: 1.58.2 + '@status-im/eslint-config': + specifier: workspace:* + version: link:../packages/eslint-config + '@types/node': + specifier: ^22.0.0 + version: 22.19.11 + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + eslint: + specifier: ^9.14.0 + version: 9.39.4(jiti@1.21.7) + globals: + specifier: ^15.12.0 + version: 15.15.0 + prettier: + specifier: ^3.3.3 + version: 3.8.1 + rimraf: + specifier: ^5.0.0 + version: 5.0.10 + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + viem: + specifier: ^2.46.3 + version: 2.47.6(typescript@5.9.3) + + ../packages/eslint-config: + dependencies: + '@eslint/eslintrc': + specifier: ^3.1.0 + version: 3.3.5 + '@eslint/js': + specifier: ^9.14.0 + version: 9.39.4 + eslint: + specifier: ^9.14.0 + version: 9.39.4(jiti@1.21.7) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.2(eslint@9.39.4(jiti@1.21.7)) + eslint-import-resolver-node: + specifier: ^0.3.9 + version: 0.3.9 + eslint-import-resolver-typescript: + specifier: ^3.6.3 + version: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-eslint-comments: + specifier: ^3.2.0 + version: 3.2.0(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-jsx-a11y: + specifier: ^6.10.2 + version: 6.10.2(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.5.5(eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@1.21.7)))(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1) + eslint-plugin-react: + specifier: ^7.37.2 + version: 7.37.5(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.2.0(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-simple-import-sort: + specifier: ^12.1.1 + version: 12.1.1(eslint@9.39.4(jiti@1.21.7)) + eslint-plugin-tailwindcss: + specifier: ^3.17.5 + version: 3.18.2(tailwindcss@3.4.19(tsx@4.21.0)) + globals: + specifier: ^15.12.0 + version: 15.15.0 + typescript-eslint: + specifier: ^8.13.0 + version: 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + +packages: + + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/cliui@9.0.0': + resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} + engines: {node: '>=18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@playwright/test@1.58.2': + resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==} + engines: {node: '>=18'} + hasBin: true + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@22.19.11': + resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==} + + '@typescript-eslint/eslint-plugin@8.57.1': + resolution: {integrity: sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.57.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.57.1': + resolution: {integrity: sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.57.1': + resolution: {integrity: sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.57.1': + resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.57.1': + resolution: {integrity: sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.57.1': + resolution: {integrity: sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.57.1': + resolution: {integrity: sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.57.1': + resolution: {integrity: sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.57.1': + resolution: {integrity: sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.57.1': + resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.11.1: + resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.2: + resolution: {integrity: sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==} + engines: {node: 20 || >=22} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + brace-expansion@5.0.2: + resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} + engines: {node: 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + es-abstract@1.24.1: + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.3.1: + resolution: {integrity: sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@9.1.2: + resolution: {integrity: sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-eslint-comments@3.2.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-prettier@5.5.5: + resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==} + engines: {node: ^14.18.0 || >=16.0.0} + 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 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-plugin-simple-import-sort@12.1.1: + resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + peerDependencies: + eslint: '>=5.0.0' + + eslint-plugin-tailwindcss@3.18.2: + resolution: {integrity: sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA==} + engines: {node: '>=18.12.0'} + peerDependencies: + tailwindcss: ^3.4.0 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jackspeak@4.2.3: + resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} + engines: {node: 20 || >=22} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + ox@0.14.7: + resolution: {integrity: sha512-zSQ/cfBdolj7U4++NAvH7sI+VG0T3pEohITCgcQj8KlawvTDY4vGVhDT64Atsm0d6adWfIYHDpu88iUBMMp+AQ==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} + engines: {node: '>=18'} + hasBin: true + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} + engines: {node: '>=6.0.0'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.11.12: + resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.57.1: + resolution: {integrity: sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + viem@2.47.6: + resolution: {integrity: sha512-zExmbI99NGvMdYa7fmqSTLgkwh48dmhgEqFrUgkpL4kfG4XkVefZ8dZqIKVUhZo6Uhf0FrrEXOsHm9LUyIvI2Q==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@adraffy/ens-normalize@1.11.1': {} + + '@alloc/quick-lru@5.2.0': {} + + '@emnapi/core@1.9.1': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@1.21.7))': + dependencies: + eslint: 9.39.4(jiti@1.21.7) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/cliui@9.0.0': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} + + '@playwright/test@1.58.2': + dependencies: + playwright: 1.58.2 + + '@rtsao/scc@1.1.0': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@22.19.11': + dependencies: + undici-types: 6.21.0 + + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/type-utils': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + eslint: 9.39.4(jiti@1.21.7) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.57.1 + debug: 4.4.3 + eslint: 9.39.4(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.57.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.57.1': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 + + '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@1.21.7) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.57.1': {} + + '@typescript-eslint/typescript-estree@8.57.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.9.3) + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/visitor-keys': 8.57.1 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.57.1 + '@typescript-eslint/types': 8.57.1 + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + eslint: 9.39.4(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.57.1': + dependencies: + '@typescript-eslint/types': 8.57.1 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + abitype@1.2.3(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.11.1: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.2: + dependencies: + jackspeak: 4.2.3 + + binary-extensions@2.3.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.2: + dependencies: + balanced-match: 4.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@4.1.1: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cssesc@3.0.0: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + didyoumean@1.2.2: {} + + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dotenv@16.6.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + es-abstract@1.24.1: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + safe-array-concat: 1.1.3 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@1.21.7)): + dependencies: + eslint: 9.39.4(jiti@1.21.7) + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@1.21.7)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.4(jiti@1.21.7) + get-tsconfig: 4.13.6 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.15 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@1.21.7)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@1.21.7)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.4(jiti@1.21.7) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4(jiti@1.21.7)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-eslint-comments@3.2.0(eslint@9.39.4(jiti@1.21.7)): + dependencies: + escape-string-regexp: 1.0.5 + eslint: 9.39.4(jiti@1.21.7) + ignore: 5.3.2 + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@1.21.7)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4(jiti@1.21.7) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4(jiti@1.21.7)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4(jiti@1.21.7)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.1 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.4(jiti@1.21.7) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-prettier@5.5.5(eslint-config-prettier@9.1.2(eslint@9.39.4(jiti@1.21.7)))(eslint@9.39.4(jiti@1.21.7))(prettier@3.8.1): + dependencies: + eslint: 9.39.4(jiti@1.21.7) + prettier: 3.8.1 + prettier-linter-helpers: 1.0.1 + synckit: 0.11.12 + optionalDependencies: + eslint-config-prettier: 9.1.2(eslint@9.39.4(jiti@1.21.7)) + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4(jiti@1.21.7)): + dependencies: + eslint: 9.39.4(jiti@1.21.7) + + eslint-plugin-react@7.37.5(eslint@9.39.4(jiti@1.21.7)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.1 + eslint: 9.39.4(jiti@1.21.7) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-plugin-simple-import-sort@12.1.1(eslint@9.39.4(jiti@1.21.7)): + dependencies: + eslint: 9.39.4(jiti@1.21.7) + + eslint-plugin-tailwindcss@3.18.2(tailwindcss@3.4.19(tsx@4.21.0)): + dependencies: + fast-glob: 3.3.3 + postcss: 8.5.8 + tailwindcss: 3.4.19(tsx@4.21.0) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4(jiti@1.21.7): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 1.21.7 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + eventemitter3@5.0.1: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globals@14.0.0: {} + + globals@15.15.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.4 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isows@1.0.7(ws@8.18.3): + dependencies: + ws: 8.18.3 + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jackspeak@4.2.3: + dependencies: + '@isaacs/cliui': 9.0.0 + + jiti@1.21.7: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.2 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + normalize-path@3.0.0: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + ox@0.14.7(typescript@5.9.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pirates@4.0.7: {} + + playwright-core@1.58.2: {} + + playwright@1.58.2: + dependencies: + playwright-core: 1.58.2 + optionalDependencies: + fsevents: 2.3.2 + + possible-typed-array-names@1.1.0: {} + + postcss-import@15.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.8): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.8 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.8 + tsx: 4.21.0 + + postcss-nested@6.2.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.1: + dependencies: + fast-diff: 1.3.0 + + prettier@3.8.1: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-is@16.13.1: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rimraf@5.0.10: + dependencies: + glob: 10.5.0 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.1 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.1 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.1 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.11.12: + dependencies: + '@pkgr/core': 0.2.9 + + tailwindcss@3.4.19(tsx@4.21.0): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-import: 15.1.0(postcss@8.5.8) + postcss-js: 4.1.0(postcss@8.5.8) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0) + postcss-nested: 6.2.0(postcss@8.5.8) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: + optional: true + + tsx@4.21.0: + dependencies: + esbuild: 0.27.3 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.57.1(eslint@9.39.4(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.4(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + viem@2.47.6(typescript@5.9.3): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3) + isows: 1.0.7(ws@8.18.3) + ox: 0.14.7(typescript@5.9.3) + ws: 8.18.3 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + ws@8.18.3: {} + + yocto-queue@0.1.0: {} diff --git a/e2e/pnpm-workspace.yaml b/e2e/pnpm-workspace.yaml new file mode 100644 index 000000000..156380382 --- /dev/null +++ b/e2e/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +# This file prevents pnpm from traversing up the directory tree +# and resolving against the monorepo root pnpm-workspace.yaml. +# It declares e2e/ as an independent workspace root. +packages: + - '../packages/eslint-config' diff --git a/e2e/src/config/env.ts b/e2e/src/config/env.ts index d5db18b86..9427cc3f3 100644 --- a/e2e/src/config/env.ts +++ b/e2e/src/config/env.ts @@ -1,6 +1,7 @@ import dotenv from 'dotenv' import fs from 'node:fs' import path from 'node:path' +import { mnemonicToAccount } from 'viem/accounts' export type EnvConfig = E2EEnvConfig @@ -13,17 +14,34 @@ export function loadEnvConfig(): EnvConfig { dotenv.config({ path: path.join(rootDir, '.env.local') }) dotenv.config({ path: path.join(rootDir, '.env') }) + // Read default MetaMask version from package.json (single source of truth) + const pkg = JSON.parse( + fs.readFileSync(path.join(rootDir, 'package.json'), 'utf-8'), + ) as { config: { metamaskVersion: string } } + + // Build Anvil RPC URLs from port env vars (same vars as docker-compose.anvil.yml) + const mainnetPort = process.env.MAINNET_FORK_PORT ?? '8547' + const lineaPort = process.env.LINEA_FORK_PORT ?? '8546' + + // Derive WALLET_ADDRESS from seed phrase if not explicitly set + const seedPhrase = process.env.WALLET_SEED_PHRASE ?? '' + let walletAddress = process.env.WALLET_ADDRESS ?? '' + if (!walletAddress && seedPhrase) { + walletAddress = mnemonicToAccount(seedPhrase).address + } + const config: EnvConfig = { BASE_URL: process.env.BASE_URL ?? 'https://hub.status.network', - WALLET_SEED_PHRASE: process.env.WALLET_SEED_PHRASE ?? '', + WALLET_SEED_PHRASE: seedPhrase, WALLET_PASSWORD: process.env.WALLET_PASSWORD ?? '', METAMASK_EXTENSION_PATH: resolveExtensionPath(rootDir), - METAMASK_VERSION: process.env.METAMASK_VERSION ?? '13.18.1', - STATUS_SEPOLIA_RPC_URL: - process.env.STATUS_SEPOLIA_RPC_URL ?? - 'https://public.sepolia.rpc.status.network', - STATUS_SEPOLIA_CHAIN_ID: - process.env.STATUS_SEPOLIA_CHAIN_ID ?? '1660990954', + METAMASK_VERSION: + process.env.METAMASK_VERSION ?? pkg.config.metamaskVersion, + ANVIL_MAINNET_RPC: + process.env.ANVIL_MAINNET_RPC || `http://localhost:${mainnetPort}`, + ANVIL_LINEA_RPC: + process.env.ANVIL_LINEA_RPC || `http://localhost:${lineaPort}`, + WALLET_ADDRESS: walletAddress, } cachedConfig = config diff --git a/e2e/src/constants/chain-ids.ts b/e2e/src/constants/chain-ids.ts new file mode 100644 index 000000000..31cb27a2b --- /dev/null +++ b/e2e/src/constants/chain-ids.ts @@ -0,0 +1,2 @@ +export const CHAIN_ID_MAINNET = 1 +export const CHAIN_ID_LINEA = 59144 diff --git a/e2e/src/constants/hub/vaults.ts b/e2e/src/constants/hub/vaults.ts index e2ecf2f61..f9eaf7ff0 100644 --- a/e2e/src/constants/hub/vaults.ts +++ b/e2e/src/constants/hub/vaults.ts @@ -1,35 +1,38 @@ +import { CHAIN_ID_LINEA, CHAIN_ID_MAINNET } from '@constants/chain-ids.js' +import { CONTRACTS } from '@helpers/anvil-rpc.js' + /** * Test vault data — simplified subset of apps/hub constants. - * If vault addresses or names change, update this file accordingly. + * Vault addresses reference CONTRACTS (single source of truth). */ export const TEST_VAULTS = { WETH: { id: 'WETH', name: 'WETH vault', token: 'WETH', - address: '0xc71Ec84Ee70a54000dB3370807bfAF4309a67a1f', - chainId: 1, + address: CONTRACTS.WETH_VAULT, + chainId: CHAIN_ID_MAINNET, }, SNT: { id: 'SNT', name: 'SNT Vault', token: 'SNT', - address: '0x493957E168aCCdDdf849913C3d60988c652935Cd', - chainId: 1, + address: CONTRACTS.SNT_VAULT, + chainId: CHAIN_ID_MAINNET, }, LINEA: { id: 'LINEA', name: 'LINEA Vault', token: 'LINEA', - address: '0xb223cA53A53A5931426b601Fa01ED2425D8540fB', - chainId: 59144, + address: CONTRACTS.LINEA_VAULT, + chainId: CHAIN_ID_LINEA, }, GUSD: { id: 'GUSD', name: 'GUSD Vault', token: 'GUSD', - address: '0x79B4cDb14A31E8B0e21C0120C409Ac14Af35f919', - chainId: 1, + address: CONTRACTS.GUSD_VAULT, + chainId: CHAIN_ID_MAINNET, }, } as const @@ -40,3 +43,25 @@ export const TEST_AMOUNTS = { STAKE_AMOUNT: '100', EXCEED_BALANCE: '999999999', } as const + +/** + * Amounts below vault minimum deposit thresholds (for below-minimum validation tests). + * Current minimums: WETH = 0.001, SNT = 1, LINEA = 1. + * Each value here must be strictly less than the corresponding minimum. + */ +export const BELOW_MIN_AMOUNTS = { + WETH: '0.0005', + SNT: '0.5', + LINEA: '0.5', +} as const + +/** Amounts for happy-path deposit tests (above minimum, reasonable values). */ +export const DEPOSIT_AMOUNTS = { + WETH: '0.01', + WETH_PARTIAL: '0.02', + SNT: '10', + LINEA: '10', + GUSD_USDT: '10', + GUSD_USDC: '10', + GUSD_USDS: '10', +} as const diff --git a/e2e/src/constants/rpc-hosts.ts b/e2e/src/constants/rpc-hosts.ts new file mode 100644 index 000000000..9bb256ae1 --- /dev/null +++ b/e2e/src/constants/rpc-hosts.ts @@ -0,0 +1,39 @@ +/** + * Known RPC provider hostnames and URL paths for chain detection. + * + * Used in both: + * - Service worker fetch patch (Layer 1 — MetaMask internal RPC) + * - Context-level route (Layer 2 — Hub page RPC) + * + * Keeping a single source of truth prevents list divergence + * that would leak requests to real chains during Anvil tests. + */ +export const KNOWN_MAINNET_HOSTS = [ + 'mainnet.infura.io', + 'eth.merkle.io', + 'ethereum-rpc.publicnode.com', + 'cloudflare-eth.com', + 'eth-mainnet.g.alchemy.com', + 'rpc.ankr.com', + '1rpc.io', +] as const + +export const KNOWN_LINEA_HOSTS = [ + 'rpc.linea.build', + 'linea-mainnet.infura.io', + 'linea.drpc.org', + 'linea-mainnet.quiknode.pro', +] as const + +/** + * Path fragments used by Hub's puzzle-authed RPC proxy (e.g. snt.eth-rpc.status.im). + * One host serves multiple chains, so hostname matching alone is insufficient — + * the path discriminates the chain. Mirrors `rpcProxyPaths` in + * apps/hub/src/app/_constants/chain.ts. + * + * `/status/hoodi` is intentionally omitted — hoodi has no Anvil fork, requests + * to it must pass through to the real RPC. + */ +export const KNOWN_MAINNET_PATHS = ['/ethereum/mainnet'] as const + +export const KNOWN_LINEA_PATHS = ['/linea/mainnet'] as const diff --git a/e2e/src/constants/timeouts.ts b/e2e/src/constants/timeouts.ts index 43fcd1a8f..09886e6e5 100644 --- a/e2e/src/constants/timeouts.ts +++ b/e2e/src/constants/timeouts.ts @@ -1,9 +1,3 @@ -/** Browser viewport dimensions */ -export const VIEWPORT = { - WIDTH: 1440, - HEIGHT: 900, -} as const - /** Timeouts for browser extension service workers and pages */ export const EXTENSION_TIMEOUTS = { /** Time to wait for MetaMask service worker to register */ @@ -24,6 +18,25 @@ export const NOTIFICATION_TIMEOUTS = { TRANSACTION_CONFIRM: 15_000, /** Time to wait for optional UI elements (e.g., "Use default" button) */ OPTIONAL_ELEMENT: 3_000, + /** + * Time to wait for notification page content to appear after opening. + * MetaMask v13 processes transactions asynchronously: gas estimation, + * fee calculation, and Blockaid security simulation must complete before + * the confirmation UI appears. This can take 10-60 seconds. + */ + NOTIFICATION_CONTENT: 45_000, + /** Quick DOM settle after tab click or minor re-render */ + DOM_SETTLE: 300, + /** Short wait for MetaMask service worker port release or DOM re-render */ + SHORT_SETTLE: 500, + /** Medium wait for page reopen or port reconnection */ + PAGE_REOPEN: 1_000, + /** Settle time after clicking Confirm before checking next step */ + POST_CLICK: 1_200, + /** Wait for UI content to render or MetaMask queue to process */ + CONTENT_CHECK: 2_000, + /** Polling interval in confirmation page scan loops */ + POLL_INTERVAL: 250, } as const /** Timeouts for MetaMask onboarding flow */ @@ -45,3 +58,11 @@ export const TEST_TIMEOUTS = { /** Time to wait for MetaMask onboarding UI elements */ ONBOARDING_ELEMENT: 15_000, } as const + +/** Timeouts for deposit transaction flows */ +export const DEPOSIT_TIMEOUTS = { + /** Time to wait for action button text to change after a tx confirms */ + BUTTON_STATE_CHANGE: 30_000, + /** Time to wait for modal to close after successful deposit */ + MODAL_CLOSE: 30_000, +} as const diff --git a/e2e/src/constants/viewport.ts b/e2e/src/constants/viewport.ts new file mode 100644 index 000000000..48d2ef719 --- /dev/null +++ b/e2e/src/constants/viewport.ts @@ -0,0 +1,5 @@ +/** Browser viewport dimensions */ +export const VIEWPORT = { + WIDTH: 1440, + HEIGHT: 900, +} as const diff --git a/e2e/src/fixtures/anvil.fixture.ts b/e2e/src/fixtures/anvil.fixture.ts new file mode 100644 index 000000000..91f57bdf1 --- /dev/null +++ b/e2e/src/fixtures/anvil.fixture.ts @@ -0,0 +1,525 @@ +import { + loadEnvConfig, + requireWalletPassword, + requireWalletSeedPhrase, +} from '@config/env.js' +import { CHAIN_ID_LINEA, CHAIN_ID_MAINNET } from '@constants/chain-ids.js' +import { + KNOWN_LINEA_HOSTS, + KNOWN_LINEA_PATHS, + KNOWN_MAINNET_HOSTS, + KNOWN_MAINNET_PATHS, +} from '@constants/rpc-hosts.js' +import { AnvilRpcHelper } from '@helpers/anvil-rpc.js' +import { + buildServiceWorkerPatch, + PATCH_MARKER, +} from '@helpers/service-worker-patch.js' +import { + disableSmartTransactionsInFiles, + restoreSmartTransactionsFiles, +} from '@helpers/stx-patcher.js' +import { PreDepositModalComponent } from '@pages/hub/components/pre-deposit-modal.component.js' +import { PreDepositsPage } from '@pages/hub/pre-deposits.page.js' +import { MetaMaskPage } from '@pages/metamask/metamask.page.js' +import fs from 'node:fs' +import path from 'node:path' + +import { test as walletTest } from './hub/wallet-connected.fixture.js' +import { launchMetaMaskContext } from './metamask.fixture.js' + +import type { Page } from '@playwright/test' + +/** + * Anvil fixture — deposit tests against local Anvil forks. + * + * Lifecycle: first test snapshots base state → each test reverts → re-snapshots → funds → runs. + * + * RPC interception (two layers): + * Layer 1: SW fetch patch (file-level, before LavaMoat) — MetaMask internal RPC + * Layer 2: context.route() — Hub frontend RPC (wagmi http transports) + * + * Playwright's context.route() does NOT intercept service worker fetch(). + * Worker.evaluate() is blocked by LavaMoat. Hence the file-level patch. + */ + +// --- Retry / timing knobs --- +/** How many times to retry MetaMask onboarding before giving up */ +const MAX_ONBOARDING_ATTEMPTS = 2 +/** How many times to retry connecting the Hub page + MetaMask before giving up */ +const MAX_CONNECT_ATTEMPTS = 2 +/** How many times to probe an unknown RPC with eth_chainId before caching null */ +const MAX_CHAIN_ID_PROBE_ATTEMPTS = 2 +/** Delay between onboarding / connect retry attempts (ms) */ +const RETRY_DELAY_MS = 2_000 +/** Time to wait for Hub page to reach DOMContentLoaded (ms) */ +const HUB_PAGE_LOAD_TIMEOUT_MS = 60_000 + +// --- Anvil funding / RPC constants --- +/** ETH balance funded to the wallet on each Anvil fork before tests (10 ETH) */ +const ANVIL_FUND_ETH_WEI = 10n * 10n ** 18n +/** Mocked eth_estimateGas response for gas-sensitive flows (10M gas) */ +const MOCK_GAS_ESTIMATE_HEX = '0x989680' + +// Module-level state — safe with workers: 1 +let baseSnapshots: { mainnet: string; linea: string } | null = null +let originalSwContent: string | null = null +let swFilePath: string | null = null + +interface AnvilFixtures { + anvilRpc: AnvilRpcHelper + preDepositsPage: PreDepositsPage + depositModal: PreDepositModalComponent +} + +export const test = walletTest.extend({ + extensionContext: async ({}, use) => { + const env = loadEnvConfig() + + await launchMetaMaskContext(use, { + beforeLaunch: extensionPath => { + swFilePath = path.join(extensionPath, 'scripts', 'app-init.js') + const currentContent = fs.readFileSync(swFilePath, 'utf-8') + + if (currentContent.includes(PATCH_MARKER)) { + // Previous run didn't clean up — strip old patch + const patchEnd = currentContent.indexOf('})();\n') + if (patchEnd !== -1) { + originalSwContent = currentContent.slice( + patchEnd + '})();\n'.length, + ) + } else { + originalSwContent = currentContent + } + } else { + originalSwContent = currentContent + } + + if (env.ANVIL_MAINNET_RPC && env.ANVIL_LINEA_RPC) { + const patch = buildServiceWorkerPatch( + env.ANVIL_MAINNET_RPC, + env.ANVIL_LINEA_RPC, + ) + fs.writeFileSync(swFilePath, patch + originalSwContent) + } + + disableSmartTransactionsInFiles(extensionPath) + }, + afterClose: () => { + if (originalSwContent !== null && swFilePath) { + fs.writeFileSync(swFilePath, originalSwContent) + } + restoreSmartTransactionsFiles() + }, + extraChromeArgs: [ + '--disable-gpu', + '--disable-software-rasterizer', + '--disable-dev-shm-usage', + ], + }) + }, + + metamask: async ({ extensionContext, extensionId }, use) => { + const metamask = new MetaMaskPage(extensionContext, extensionId) + const seedPhrase = requireWalletSeedPhrase() + const password = requireWalletPassword() + + const onboardStart = Date.now() + + for (let attempt = 1; attempt <= MAX_ONBOARDING_ATTEMPTS; attempt++) { + try { + await metamask.onboarding.importWallet(seedPhrase, password) + console.log( + `[anvil-fixture] Onboarding done in ${Date.now() - onboardStart}ms`, + ) + break + } catch (err) { + console.warn( + `[anvil-fixture] Onboarding attempt ${attempt}/${MAX_ONBOARDING_ATTEMPTS} failed: ${err}`, + ) + if (attempt === MAX_ONBOARDING_ATTEMPTS) throw err + for (const page of extensionContext.pages()) { + if (page.url().includes('chrome-extension:')) + await page.close().catch(() => {}) + } + await new Promise(r => setTimeout(r, RETRY_DELAY_MS)) + } + } + + const homePage = await metamask.getExtensionPage() + await homePage.waitForLoadState('load') + console.log('[anvil-fixture] MetaMask home loaded (SW warm-up)') + + await use(metamask) + }, + + anvilRpc: async ({}, use, testInfo) => { + // Hard limit: module-level snapshot state races across workers. + if (testInfo.config.workers > 1) { + throw new Error( + 'anvil.fixture requires workers: 1 (module-level snapshot state is not worker-safe)', + ) + } + + const env = loadEnvConfig() + + if (!env.ANVIL_MAINNET_RPC || !env.ANVIL_LINEA_RPC) { + throw new Error( + 'ANVIL_MAINNET_RPC and ANVIL_LINEA_RPC must be set for anvil-deposits tests. ' + + 'Run: cd e2e && pnpm anvil:up', + ) + } + + const walletAddress = env.WALLET_ADDRESS + if (!walletAddress) { + throw new Error( + 'WALLET_ADDRESS could not be determined. ' + + 'Set WALLET_SEED_PHRASE in .env (address is auto-derived), ' + + 'or set WALLET_ADDRESS explicitly.', + ) + } + + const helper = new AnvilRpcHelper( + env.ANVIL_MAINNET_RPC, + env.ANVIL_LINEA_RPC, + walletAddress, + ) + + const anvilStart = Date.now() + + if (!baseSnapshots) { + await helper.requireHealthy() + + await Promise.all([ + helper.setEthBalance(ANVIL_FUND_ETH_WEI), + helper.setEthBalance(ANVIL_FUND_ETH_WEI, helper.lineaRpc), + ]) + await helper.enableAllVaults() + + baseSnapshots = await helper.snapshotBoth() + console.log( + `[anvil-fixture] Initial setup done in ${Date.now() - anvilStart}ms`, + ) + } else { + try { + const rt0 = Date.now() + await helper.revert(baseSnapshots.mainnet, helper.mainnetRpc) + const rt1 = Date.now() + await helper.revert(baseSnapshots.linea, helper.lineaRpc) + const rt2 = Date.now() + console.log( + `[anvil-fixture] revert mainnet: ${rt1 - rt0}ms, linea: ${rt2 - rt1}ms`, + ) + } catch (err) { + console.log( + `[anvil-fixture] revertBoth failed: ${err instanceof Error ? err.message : err}. ` + + `Re-establishing base state from current Anvil state.`, + ) + // Zero out stale token balances from previous test. + // SNT excluded: MiniMeToken uses checkpoint storage, can't be zeroed via slots. + await Promise.all([ + helper.setEthBalance(ANVIL_FUND_ETH_WEI), + helper.setEthBalance(ANVIL_FUND_ETH_WEI, helper.lineaRpc), + helper.fundWeth(0n), + helper.fundLinea(0n), + helper.fundUsdt(0n), + helper.fundUsdc(0n), + helper.fundUsds(0n), + ]) + await helper.enableAllVaults() + } + const st0 = Date.now() + const mainnetSnap = await helper.snapshot(helper.mainnetRpc) + const st1 = Date.now() + const lineaSnap = await helper.snapshot(helper.lineaRpc) + const st2 = Date.now() + baseSnapshots = { mainnet: mainnetSnap, linea: lineaSnap } + console.log( + `[anvil-fixture] snapshot mainnet: ${st1 - st0}ms, linea: ${st2 - st1}ms`, + ) + console.log( + `[anvil-fixture] Revert/snapshot done in ${Date.now() - anvilStart}ms`, + ) + } + + // Force auto-mining — interval mining can leave the second tx in + // approve → deposit flows pending with null receipt indefinitely + await helper.enableAutoMining() + await helper.enableAutoMining(helper.lineaRpc) + + await use(helper) + }, + + preDepositsPage: async ({ hubPage }, use) => { + await use(new PreDepositsPage(hubPage)) + }, + depositModal: async ({ hubPage }, use) => { + await use(new PreDepositModalComponent(hubPage)) + }, + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + hubPage: async ({ extensionContext, metamask, anvilRpc: _anvilRpc }, use) => { + const env = loadEnvConfig() + + // Context-level route: intercept Hub's own RPC calls (wagmi http transports). + // MetaMask SW requests are handled by Layer 1 (file-level fetch patch). + // + // Chain discovery: 1) ?chainId= query param, 2) path/hostname lookup, + // 3) eth_chainId probe. Path is checked before hostname because the puzzle-auth + // proxy (snt.eth-rpc.status.im) serves multiple chains under one host. + // Check Linea FIRST — 'linea-mainnet.infura.io' contains 'mainnet.infura.io'. + const getChainIdFromUrl = (url: string): number | null => { + try { + const parsed = new URL(url) + const { hostname, pathname } = parsed + if (KNOWN_LINEA_PATHS.some(p => pathname.includes(p))) + return CHAIN_ID_LINEA + if (KNOWN_MAINNET_PATHS.some(p => pathname.includes(p))) + return CHAIN_ID_MAINNET + if (KNOWN_LINEA_HOSTS.some(h => hostname.includes(h))) + return CHAIN_ID_LINEA + if (KNOWN_MAINNET_HOSTS.some(h => hostname.includes(h))) + return CHAIN_ID_MAINNET + } catch { + // ignore URL parsing errors + } + return null + } + + const rpcRedirectCache = new Map() + const txReceiptMethodPattern = /"method"\s*:\s*"eth_getTransactionReceipt"/ + + const hasNonNullRpcResult = (responseBody: string): boolean => { + try { + const parsed = JSON.parse(responseBody) as + | { result?: unknown } + | Array<{ result?: unknown }> + if (Array.isArray(parsed)) { + return parsed.some( + item => item && item.result !== null && item.result !== undefined, + ) + } + return parsed.result !== null && parsed.result !== undefined + } catch { + return false + } + } + + const forwardRpcToAnvil = async (anvilUrl: string, body: string) => { + const res = await fetch(anvilUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body, + }) + return { + status: res.status, + body: await res.text(), + } + } + + await extensionContext.route('**/*', async route => { + const request = route.request() + if (request.method() !== 'POST') return route.continue() + + const postData = request.postData() + if (!postData?.includes('"jsonrpc"')) return route.continue() + if (postData.includes('"method":"linea_')) return route.continue() + + if (postData.includes('"method":"eth_estimateGas"')) { + const idMatch = postData.match(/"id"\s*:\s*(\d+)/) + const id = idMatch ? idMatch[1] : '1' + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: `{"jsonrpc":"2.0","id":${id},"result":"${MOCK_GAS_ESTIMATE_HEX}"}`, + }) + } + + const url = request.url() + if (url.startsWith('chrome-extension:') || url.includes('localhost')) { + return route.continue() + } + + if (!rpcRedirectCache.has(url)) { + const chainIdParam = new URL(url).searchParams.get('chainId') + if (chainIdParam) { + const chainId = Number(chainIdParam) + if (chainId === CHAIN_ID_MAINNET) + rpcRedirectCache.set(url, env.ANVIL_MAINNET_RPC) + else if (chainId === CHAIN_ID_LINEA) + rpcRedirectCache.set(url, env.ANVIL_LINEA_RPC) + else rpcRedirectCache.set(url, null) + } else { + const knownChainId = getChainIdFromUrl(url) + if (knownChainId !== null) { + if (knownChainId === CHAIN_ID_MAINNET) + rpcRedirectCache.set(url, env.ANVIL_MAINNET_RPC) + else if (knownChainId === CHAIN_ID_LINEA) + rpcRedirectCache.set(url, env.ANVIL_LINEA_RPC) + else rpcRedirectCache.set(url, null) + } else { + let probeResult: string | null = null + for ( + let attempt = 0; + attempt < MAX_CHAIN_ID_PROBE_ATTEMPTS; + attempt++ + ) { + try { + const probe = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'eth_chainId', + params: [], + id: 1, + }), + }) + const json = (await probe.json()) as { result: string } + const chainId = parseInt(json.result, 16) + if (chainId === CHAIN_ID_MAINNET) + probeResult = env.ANVIL_MAINNET_RPC + else if (chainId === CHAIN_ID_LINEA) + probeResult = env.ANVIL_LINEA_RPC + break + } catch (err) { + if (attempt === 0) { + console.warn( + `[anvil-intercept] Probe attempt 1 failed for ${url}, retrying...`, + ) + await new Promise(r => setTimeout(r, 500)) + } else { + console.warn( + `[anvil-intercept] Probe failed permanently for ${url}: ${err}`, + ) + } + } + } + rpcRedirectCache.set(url, probeResult) + } + } + } + + const anvilUrl = rpcRedirectCache.get(url) + if (!anvilUrl) return route.continue() + + // Receipt requests may hit the wrong fork after network switches — + // try both forks before returning null + const isTxReceiptRequest = txReceiptMethodPattern.test(postData) + const fallbackAnvilUrl = + anvilUrl === env.ANVIL_LINEA_RPC + ? env.ANVIL_MAINNET_RPC + : env.ANVIL_LINEA_RPC + + try { + const primary = await forwardRpcToAnvil(anvilUrl, postData) + + if (!isTxReceiptRequest) { + return route.fulfill({ + status: primary.status, + contentType: 'application/json', + body: primary.body, + }) + } + + if (primary.status === 200 && hasNonNullRpcResult(primary.body)) { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: primary.body, + }) + } + + const fallback = await forwardRpcToAnvil(fallbackAnvilUrl, postData) + if (fallback.status === 200 && hasNonNullRpcResult(fallback.body)) { + return route.fulfill({ + status: 200, + contentType: 'application/json', + body: fallback.body, + }) + } + + return route.fulfill({ + status: primary.status, + contentType: 'application/json', + body: primary.body, + }) + } catch { + return route.abort('connectionrefused') + } + }) + + let connectedPage: Page | null = null + + for (let attempt = 1; attempt <= MAX_CONNECT_ATTEMPTS; attempt++) { + let page: Page | null = null + try { + page = await extensionContext.newPage() + + // Block wallet_addEthereumChain BEFORE navigation. + // addInitScript runs before any page script, eliminating the race + // where the Hub fires addEthereumChain before a post-goto evaluate(). + await page.addInitScript(() => { + function patchEthereum() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const eth = (window as any).ethereum + if (!eth || eth.__addChainBlocked) return false + eth.__addChainBlocked = true + const orig = eth.request.bind(eth) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + eth.request = async (args: any) => { + if (args.method === 'wallet_addEthereumChain') { + console.log('[eth-patch] blocked wallet_addEthereumChain') + return null + } + return orig(args) + } + return true + } + if (!patchEthereum()) { + const id = setInterval(() => { + if (patchEthereum()) clearInterval(id) + }, 10) + setTimeout(() => clearInterval(id), 5_000) + } + }) + + page.on('console', msg => { + const text = msg.text() + if (text.includes('[eth-patch]') || msg.type() === 'error') + console.log(`[hub-page][${msg.type()}] ${text}`) + }) + page.on('pageerror', err => { + console.log(`[hub-page][pageerror] ${err.message}`) + }) + + const connectStart = Date.now() + await page.goto(env.BASE_URL, { + waitUntil: 'domcontentloaded', + timeout: HUB_PAGE_LOAD_TIMEOUT_MS, + }) + console.log( + `[anvil-fixture] Hub loaded in ${Date.now() - connectStart}ms`, + ) + + await metamask.connectToDApp(page) + connectedPage = page + break + } catch (err) { + console.warn( + `[anvil-fixture] Connect attempt ${attempt}/${MAX_CONNECT_ATTEMPTS} failed: ${err}`, + ) + if (page) await page.close().catch(() => {}) + if (attempt === MAX_CONNECT_ATTEMPTS) throw err + await new Promise(r => setTimeout(r, RETRY_DELAY_MS)) + } + } + + // Dismiss any addEthereumChain that slipped through before the patch activated + await metamask.dismissPendingAddNetwork() + + await use(connectedPage!) + + await extensionContext.unrouteAll({ behavior: 'ignoreErrors' }) + }, +}) diff --git a/e2e/src/fixtures/index.ts b/e2e/src/fixtures/index.ts deleted file mode 100644 index 0ec1d364f..000000000 --- a/e2e/src/fixtures/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { test as baseTest, expect } from './base.fixture.js' -export { test as walletTest } from './hub/wallet-connected.fixture.js' -export { test as metamaskTest } from './metamask.fixture.js' diff --git a/e2e/src/fixtures/metamask.fixture.ts b/e2e/src/fixtures/metamask.fixture.ts index f7a1622b0..0ea5d2b6b 100644 --- a/e2e/src/fixtures/metamask.fixture.ts +++ b/e2e/src/fixtures/metamask.fixture.ts @@ -1,5 +1,6 @@ import { loadEnvConfig } from '@config/env.js' -import { EXTENSION_TIMEOUTS, VIEWPORT } from '@constants/timeouts.js' +import { EXTENSION_TIMEOUTS } from '@constants/timeouts.js' +import { VIEWPORT } from '@constants/viewport.js' import { MetaMaskPage } from '@pages/metamask/metamask.page.js' import { chromium, test as base } from '@playwright/test' import fs from 'node:fs' @@ -8,41 +9,71 @@ import path from 'node:path' import type { BrowserContext, Page } from '@playwright/test' -interface MetaMaskFixtures { +export interface MetaMaskFixtures { extensionContext: BrowserContext extensionId: string metamask: MetaMaskPage hubPage: Page } -export const test = base.extend({ - extensionContext: async ({}, use) => { - const env = loadEnvConfig() - const extensionPath = env.METAMASK_EXTENSION_PATH +export interface LaunchMetaMaskOptions { + /** Called with the extension path BEFORE the browser reads the extension files. */ + beforeLaunch?: (extensionPath: string) => void | Promise + /** Called after the browser context is closed. */ + afterClose?: () => void | Promise + /** Additional Chrome flags appended to the default set. */ + extraChromeArgs?: string[] +} + +/** + * Launch a persistent Chromium context with MetaMask loaded. + */ +export async function launchMetaMaskContext( + use: (context: BrowserContext) => Promise, + options: LaunchMetaMaskOptions = {}, +): Promise { + const env = loadEnvConfig() + const extensionPath = env.METAMASK_EXTENSION_PATH - if (!fs.existsSync(extensionPath)) { - throw new Error( - `MetaMask extension not found at ${extensionPath}. Run "pnpm setup:metamask" first.`, - ) - } + if (!fs.existsSync(extensionPath)) { + throw new Error( + `MetaMask extension not found at ${extensionPath}. Run "pnpm setup:metamask" first.`, + ) + } - const profileDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pw-metamask-')) + await options.beforeLaunch?.(extensionPath) - const context = await chromium.launchPersistentContext(profileDir, { - headless: false, - args: [ - `--disable-extensions-except=${extensionPath}`, - `--load-extension=${extensionPath}`, - '--no-first-run', - '--disable-default-apps', - ], - viewport: { width: VIEWPORT.WIDTH, height: VIEWPORT.HEIGHT }, - }) + const profileDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pw-metamask-')) - await use(context) + const launchStart = Date.now() + const context = await chromium.launchPersistentContext(profileDir, { + headless: false, + args: [ + `--disable-extensions-except=${extensionPath}`, + `--load-extension=${extensionPath}`, + '--no-first-run', + '--disable-default-apps', + ...(options.extraChromeArgs ?? []), + ], + viewport: { width: VIEWPORT.WIDTH, height: VIEWPORT.HEIGHT }, + }) + console.log( + `[metamask-fixture] Browser launched in ${Date.now() - launchStart}ms`, + ) + await use(context) + + try { await context.close() + } finally { fs.rmSync(profileDir, { recursive: true, force: true }) + await options.afterClose?.() + } +} + +export const test = base.extend({ + extensionContext: async ({}, use) => { + await launchMetaMaskContext(use) }, extensionId: async ({ extensionContext }, use) => { diff --git a/e2e/src/helpers/anvil-rpc.ts b/e2e/src/helpers/anvil-rpc.ts new file mode 100644 index 000000000..46e433c60 --- /dev/null +++ b/e2e/src/helpers/anvil-rpc.ts @@ -0,0 +1,712 @@ +/** + * AnvilRpcHelper — JSON-RPC helper for Anvil fork state management. + * + * Provides: + * - Snapshot/revert for test isolation + * - ETH balance manipulation + * - SNT minting via MiniMeToken controller impersonation + * - LINEA token funding via storage slot manipulation + * + * All operations use raw fetch() — no external dependencies needed. + */ + +// Well-known contract addresses +export const CONTRACTS = { + // Mainnet tokens + SNT: '0x744d70FDBE2Ba4CF95131626614a1763DF805B9E', + WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', + USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7', + USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + USDS: '0xdC035D45d973E3EC169d2276DDab16f1e407384F', + // Linea token + LINEA: '0x1789e0043623282D5DCc7F213d703C6D8BAfBB04', + // Vault contracts (mainnet unless noted) + WETH_VAULT: '0xc71Ec84Ee70a54000dB3370807bfAF4309a67a1f', + SNT_VAULT: '0x493957E168aCCdDdf849913C3d60988c652935Cd', + GUSD_VAULT: '0x79B4cDb14A31E8B0e21C0120C409Ac14Af35f919', + LINEA_VAULT: '0xb223cA53A53A5931426b601Fa01ED2425D8540fB', // Linea chain +} as const + +// OpenZeppelin v5 ERC20Upgradeable namespaced storage slot for _balances. +// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff)) +const OZ_V5_ERC20_BALANCE_SLOT = + 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00n + +// SNT (MiniMeToken) controller — can mint via generateTokens() +const SNT_CONTROLLER = '0x52aE2B53C847327f95A5084a7C38c0adb12fD302' + +// Function selectors (4 bytes) +const SELECTORS = { + // ERC20.balanceOf(address) + BALANCE_OF: '0x70a08231', + // ERC20.approve(address,uint256) + APPROVE: '0x095ea7b3', + // MiniMeToken.generateTokens(address,uint256) + GENERATE_TOKENS: '0x827f32c0', +} as const + +/** Encode an address as 32-byte ABI parameter (left-padded with zeros) */ +function encodeAddress(address: string): string { + return address.slice(2).toLowerCase().padStart(64, '0') +} + +/** Encode a uint256 as 32-byte ABI parameter */ +function encodeUint256(value: bigint): string { + return value.toString(16).padStart(64, '0') +} + +/** Convert bigint to hex string with 0x prefix */ +function toHex(value: bigint): string { + return '0x' + value.toString(16) +} + +/** Transient RPC failure (network, 5xx, 429) — safe to retry */ +export class TransientRpcError extends Error { + constructor(message: string) { + super(message) + this.name = 'TransientRpcError' + } +} + +/** Deterministic RPC failure (invalid params, reverts) — do NOT retry */ +export class RpcError extends Error { + constructor(message: string) { + super(message) + this.name = 'RpcError' + } +} + +export interface FundingPreset { + /** ETH amount on mainnet fork (for gas). Linea ETH comes from base snapshot. */ + eth?: bigint + snt?: bigint + linea?: bigint + weth?: bigint + usdt?: bigint + usdc?: bigint + usds?: bigint +} + +// Module-level slot cache — survives across AnvilRpcHelper instances. +// Safe with workers: 1. Eliminates 240 RPC calls on fallback revert paths. +const globalSlotCache = new Map() +let globalLineaSlot: bigint | null = null + +export class AnvilRpcHelper { + private rpcIdCounter = 0 + private lineaTokenBalanceSlot: bigint | null = globalLineaSlot + private erc20BalanceSlotCache = globalSlotCache + + constructor( + readonly mainnetRpc: string, + readonly lineaRpc: string, + readonly walletAddress: string, + ) {} + + // --------------------------------------------------------------------------- + // Snapshot / Revert + // --------------------------------------------------------------------------- + + /** Take a snapshot of the current state. Returns snapshot ID. */ + async snapshot(rpc?: string): Promise { + return this.call(rpc ?? this.mainnetRpc, 'evm_snapshot', []) + } + + /** + * Revert to a snapshot. The snapshot is consumed (one-time use). + * Returns true if successful. + */ + async revert(snapshotId: string, rpc?: string): Promise { + return this.call(rpc ?? this.mainnetRpc, 'evm_revert', [snapshotId]) + } + + /** + * Take snapshots on both forks. Returns { mainnet, linea } snapshot IDs. + */ + async snapshotBoth(): Promise<{ mainnet: string; linea: string }> { + const [mainnet, linea] = await Promise.all([ + this.snapshot(this.mainnetRpc), + this.snapshot(this.lineaRpc), + ]) + return { mainnet, linea } + } + + /** + * Revert both forks to their snapshots. + */ + async revertBoth(ids: { mainnet: string; linea: string }): Promise { + await Promise.all([ + this.revert(ids.mainnet, this.mainnetRpc), + this.revert(ids.linea, this.lineaRpc), + ]) + } + + // --------------------------------------------------------------------------- + // Block mining + // --------------------------------------------------------------------------- + + /** + * Enable interval mining on Anvil — mine a block every `intervalSec` seconds. + * IMPORTANT: evm_setIntervalMining DISABLES auto-mining. Call enableAutoMining() + * after this to re-enable instant tx confirmation alongside periodic empty blocks. + */ + async enableIntervalMining(intervalSec: number, rpc?: string): Promise { + await this.call(rpc ?? this.mainnetRpc, 'evm_setIntervalMining', [ + intervalSec, + ]) + } + + /** + * Wait until eth_chainId returns the expected value. + * Useful after network switches to confirm Anvil fork is responsive. + */ + async waitForChain( + expectedChainId: number, + rpc?: string, + timeoutMs = 15_000, + ): Promise { + const target = rpc ?? this.mainnetRpc + const hex = '0x' + expectedChainId.toString(16) + const deadline = Date.now() + timeoutMs + while (Date.now() < deadline) { + const result = await this.call(target, 'eth_chainId', []).catch( + () => null, + ) + if (result === hex) return + await new Promise(r => setTimeout(r, 500)) + } + throw new Error( + `Chain ${expectedChainId} not ready on ${target} within ${timeoutMs}ms`, + ) + } + + /** Enable auto-mining — transactions are mined immediately when received. */ + async enableAutoMining(rpc?: string): Promise { + await this.call(rpc ?? this.mainnetRpc, 'evm_setAutomine', [true]) + } + + /** Mine a single block on Anvil */ + async mineBlock(rpc?: string): Promise { + await this.call(rpc ?? this.mainnetRpc, 'evm_mine', []) + } + + // --------------------------------------------------------------------------- + // Vault state + // --------------------------------------------------------------------------- + + /** Vault state storage slot (slot 8 = vault enabled flag) */ + private static readonly VAULT_STATE_SLOT = + '0x0000000000000000000000000000000000000000000000000000000000000008' + private static readonly VAULT_ENABLED_VALUE = + '0x0000000000000000000000000000000000000000000000000000000000000001' + + /** Enable a vault by setting its state storage slot to "enabled" */ + async enableVault(vaultAddress: string, rpc?: string): Promise { + await this.call(rpc ?? this.mainnetRpc, 'anvil_setStorageAt', [ + vaultAddress, + AnvilRpcHelper.VAULT_STATE_SLOT, + AnvilRpcHelper.VAULT_ENABLED_VALUE, + ]) + } + + /** Enable all test vaults on their respective forks */ + async enableAllVaults(): Promise { + await Promise.all([ + this.enableVault(CONTRACTS.WETH_VAULT), + this.enableVault(CONTRACTS.SNT_VAULT), + this.enableVault(CONTRACTS.GUSD_VAULT), + this.enableVault(CONTRACTS.LINEA_VAULT, this.lineaRpc), + ]) + } + + // --------------------------------------------------------------------------- + // ETH balance + // --------------------------------------------------------------------------- + + /** Set ETH balance directly via anvil_setBalance */ + async setEthBalance(amount: bigint, rpc?: string): Promise { + await this.call(rpc ?? this.mainnetRpc, 'anvil_setBalance', [ + this.walletAddress, + toHex(amount), + ]) + } + + // --------------------------------------------------------------------------- + // ERC-20 token funding + // --------------------------------------------------------------------------- + + /** + * Fund SNT tokens (18 decimals) via MiniMeToken.generateTokens(). + * SNT uses MiniMeToken which supports minting by the controller. + * Whale transfer won't work (Binance no longer holds SNT). + */ + async fundSnt(amount: bigint): Promise { + await this.call(this.mainnetRpc, 'anvil_setBalance', [ + SNT_CONTROLLER, + toHex(10n ** 18n), + ]) + + const data = + SELECTORS.GENERATE_TOKENS + + encodeAddress(this.walletAddress) + + encodeUint256(amount) + + await this.call(this.mainnetRpc, 'anvil_impersonateAccount', [ + SNT_CONTROLLER, + ]) + await this.call(this.mainnetRpc, 'eth_sendTransaction', [ + { + from: SNT_CONTROLLER, + to: CONTRACTS.SNT, + data, + }, + ]) + // Force-mine the block: interval mining disables auto-mine, so the tx + // sits in the mempool until the next 1-second tick. Mine explicitly to + // avoid a race between tx inclusion and the balance check below. + await this.mineBlock() + await this.call(this.mainnetRpc, 'anvil_stopImpersonatingAccount', [ + SNT_CONTROLLER, + ]) + + // Verify minting succeeded (tx could still revert on-chain) + const balance = await this.getErc20Balance(CONTRACTS.SNT, this.mainnetRpc) + if (balance < amount) { + throw new Error( + `SNT funding failed: expected >= ${amount}, got ${balance}. ` + + 'The MiniMeToken controller may have changed.', + ) + } + } + + // --------------------------------------------------------------------------- + // ERC-20 storage-based funding (for tokens without a known whale) + // --------------------------------------------------------------------------- + + /** Compute keccak256 via Anvil RPC (web3_sha3) — no external dependencies */ + private async keccak256(hexData: string, rpc: string): Promise { + return this.call(rpc, 'web3_sha3', [hexData]) + } + + /** Read ERC-20 balanceOf via eth_call (retries transient failures) */ + async getErc20Balance(token: string, rpc?: string): Promise { + const data = SELECTORS.BALANCE_OF + encodeAddress(this.walletAddress) + const result = await this.callWithRetry( + rpc ?? this.mainnetRpc, + 'eth_call', + [{ to: token, data }, 'latest'], + ) + return BigInt(result) + } + + /** + * Set ERC-20 balance by writing directly to the _balances mapping storage slot. + * @param token - ERC-20 contract address + * @param amount - balance in smallest unit + * @param balanceSlot - storage slot of the _balances mapping (bigint for OZ v5 namespaced slots) + * @param rpc - RPC endpoint + */ + private async setErc20BalanceViaStorage( + token: string, + amount: bigint, + balanceSlot: bigint, + rpc: string, + ): Promise { + // Storage key for mapping(address => uint256) at slot S: + // keccak256(abi.encode(address, S)) + const key = + '0x' + encodeAddress(this.walletAddress) + encodeUint256(balanceSlot) + const storagePosition = await this.keccak256(key, rpc) + + await this.call(rpc, 'anvil_setStorageAt', [ + token, + storagePosition, + '0x' + encodeUint256(amount), + ]) + } + + /** + * Find the storage slot of the _balances mapping by brute-force. + * Sets a unique test value at candidate slots and checks via balanceOf(). + * Non-destructive: uses snapshot/revert. + */ + private async findErc20BalanceSlot( + token: string, + rpc: string, + ): Promise { + const testAmount = 133742069n * 10n ** 18n + const candidateSlots: bigint[] = [ + 0n, + 1n, + 2n, + 3n, + 4n, + 5n, // Standard ERC-20 layouts + 6n, + 7n, + 8n, + 9n, + 10n, // Proxy / custom layouts (USDC FiatTokenV2 = slot 9) + OZ_V5_ERC20_BALANCE_SLOT, // OpenZeppelin v5 ERC20Upgradeable + ] + + const snapshotId = await this.snapshot(rpc) + + try { + for (const slot of candidateSlots) { + await this.setErc20BalanceViaStorage(token, testAmount, slot, rpc) + const balance = await this.getErc20Balance(token, rpc) + + if (balance === testAmount) { + return slot + } + } + + throw new Error( + `Could not find _balances storage slot for token ${token}. ` + + `Tried slots: ${candidateSlots.map(s => '0x' + s.toString(16)).join(', ')}`, + ) + } finally { + await this.revert(snapshotId, rpc) + } + } + + /** + * Fund LINEA tokens (18 decimals) on Linea fork via storage manipulation. + * Auto-discovers the _balances slot on first call and caches it. + */ + async fundLinea(amount: bigint): Promise { + if (this.lineaTokenBalanceSlot === null) { + this.lineaTokenBalanceSlot = await this.findErc20BalanceSlot( + CONTRACTS.LINEA, + this.lineaRpc, + ) + globalLineaSlot = this.lineaTokenBalanceSlot + } + + await this.setErc20BalanceViaStorage( + CONTRACTS.LINEA, + amount, + this.lineaTokenBalanceSlot, + this.lineaRpc, + ) + } + + /** + * Generic ERC-20 funding via storage slot manipulation. + * Auto-discovers the _balances slot on first call per token and caches it. + */ + async fundErc20ViaStorage( + token: string, + amount: bigint, + rpc: string, + ): Promise { + const cacheKey = `${token}:${rpc}` + if (!this.erc20BalanceSlotCache.has(cacheKey)) { + const slot = await this.findErc20BalanceSlot(token, rpc) + this.erc20BalanceSlotCache.set(cacheKey, slot) + } + await this.setErc20BalanceViaStorage( + token, + amount, + this.erc20BalanceSlotCache.get(cacheKey)!, + rpc, + ) + } + + /** Fund WETH via storage (simpler and faster than actual wrapping on Anvil) */ + async fundWeth(amount: bigint): Promise { + await this.fundErc20ViaStorage(CONTRACTS.WETH, amount, this.mainnetRpc) + } + + /** Fund USDT (6 decimals) via storage */ + async fundUsdt(amount: bigint): Promise { + await this.fundErc20ViaStorage(CONTRACTS.USDT, amount, this.mainnetRpc) + } + + /** Fund USDC (6 decimals) via storage */ + async fundUsdc(amount: bigint): Promise { + await this.fundErc20ViaStorage(CONTRACTS.USDC, amount, this.mainnetRpc) + } + + /** Fund USDS (18 decimals) via storage */ + async fundUsds(amount: bigint): Promise { + await this.fundErc20ViaStorage(CONTRACTS.USDS, amount, this.mainnetRpc) + } + + /** + * Reset ERC-20 allowance to 0 for a specific spender. + * Uses impersonation to call approve(spender, 0) from the wallet. + * Needed when the fork state has pre-existing allowances that cause the Hub + * to skip the approve step (showing "Deposit" instead of "Approve Deposit"). + */ + async resetAllowance( + token: string, + spender: string, + rpc?: string, + ): Promise { + const targetRpc = rpc ?? this.mainnetRpc + const data = SELECTORS.APPROVE + encodeAddress(spender) + encodeUint256(0n) + + await this.call(targetRpc, 'anvil_impersonateAccount', [this.walletAddress]) + await this.call(targetRpc, 'eth_sendTransaction', [ + { + from: this.walletAddress, + to: token, + data, + }, + ]) + await this.mineBlock(targetRpc) + await this.call(targetRpc, 'anvil_stopImpersonatingAccount', [ + this.walletAddress, + ]) + } + + /** + * Apply a funding preset: set ETH + fund specific tokens. + * Designed for test.beforeEach — call after revert to set exact preconditions. + */ + async fund(preset: FundingPreset): Promise { + if (preset.eth !== undefined) { + await this.setEthBalance(preset.eth) + } + if (preset.snt !== undefined && preset.snt > 0n) { + await this.fundSnt(preset.snt) + } + if (preset.linea !== undefined && preset.linea > 0n) { + await this.fundLinea(preset.linea) + } + if (preset.weth !== undefined && preset.weth > 0n) { + await this.fundWeth(preset.weth) + } + if (preset.usdt !== undefined && preset.usdt > 0n) { + await this.fundUsdt(preset.usdt) + } + if (preset.usdc !== undefined && preset.usdc > 0n) { + await this.fundUsdc(preset.usdc) + } + if (preset.usds !== undefined && preset.usds > 0n) { + await this.fundUsds(preset.usds) + } + } + + // --------------------------------------------------------------------------- + // Health check + // --------------------------------------------------------------------------- + + /** Check if an Anvil RPC endpoint is reachable (retries transient failures) */ + async healthCheck(rpc?: string): Promise { + try { + await this.callWithRetry( + rpc ?? this.mainnetRpc, + 'eth_blockNumber', + [], + 3, + 500, + ) + return true + } catch { + return false + } + } + + /** Check if a contract exists at the given address (has deployed bytecode) */ + async contractExists(address: string, rpc?: string): Promise { + const code = await this.callWithRetry( + rpc ?? this.mainnetRpc, + 'eth_getCode', + [address, 'latest'], + 3, + 500, + ) + return code !== '0x' && code !== '0x0' + } + + /** Check both forks are reachable and key contracts exist. Throws with a clear message if not. */ + async requireHealthy(): Promise { + const [mainnetOk, lineaOk] = await Promise.all([ + this.healthCheck(this.mainnetRpc), + this.healthCheck(this.lineaRpc), + ]) + + if (!mainnetOk || !lineaOk) { + const down = [ + !mainnetOk && `mainnet (${this.mainnetRpc})`, + !lineaOk && `linea (${this.lineaRpc})`, + ] + .filter(Boolean) + .join(', ') + + throw new Error( + `Anvil fork(s) not reachable: ${down}. ` + + 'Start them with: cd e2e && pnpm anvil:up', + ) + } + + // Verify key contracts exist on the fork (catches stale/incomplete forks) + const keyContracts = [ + { address: CONTRACTS.SNT, name: 'SNT', rpc: this.mainnetRpc }, + { address: CONTRACTS.WETH, name: 'WETH', rpc: this.mainnetRpc }, + { address: CONTRACTS.LINEA, name: 'LINEA', rpc: this.lineaRpc }, + ] + + const results = await Promise.all( + keyContracts.map(async ({ address, name, rpc }) => ({ + name, + address, + exists: await this.contractExists(address, rpc), + })), + ) + const missing = results.filter(r => !r.exists) + if (missing.length > 0) { + throw new Error( + `Contracts not found on fork: ${missing.map(m => `${m.name} (${m.address})`).join(', ')}. ` + + 'The fork state may be stale or incomplete.', + ) + } + } + + // --------------------------------------------------------------------------- + // Raw RPC + // --------------------------------------------------------------------------- + + private async call( + rpc: string, + method: string, + params: unknown[], + ): Promise { + const id = ++this.rpcIdCounter + + let response: Response + try { + response = await fetch(rpc, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ jsonrpc: '2.0', id, method, params }), + }) + } catch (error) { + // Network-level failure (DNS, connection refused, timeout) — transient + throw new TransientRpcError( + `Anvil RPC network error (${method}): ${error instanceof Error ? error.message : error}`, + ) + } + + if (!response.ok) { + const body = await response.text() + // 5xx and 429 are transient; other HTTP errors are not + if (response.status >= 500 || response.status === 429) { + throw new TransientRpcError( + `Anvil RPC HTTP ${response.status} (${method}): ${body}`, + ) + } + throw new RpcError( + `Anvil RPC HTTP ${response.status} (${method}): ${body}`, + ) + } + + let json: { result?: T; error?: { message?: string } } + try { + json = await response.json() + } catch { + throw new TransientRpcError( + `Anvil RPC invalid JSON response (${method}): status ${response.status}`, + ) + } + + if (json.error) { + // JSON-RPC semantic error — deterministic, do not retry + throw new RpcError( + `Anvil RPC error (${method}): ${json.error.message ?? JSON.stringify(json.error)}`, + ) + } + + return json.result as T + } + + /** + * RPC call with retry for transient failures only. + * Network errors, HTTP 5xx, and 429 are retried. + * JSON-RPC semantic errors (invalid params, reverts) throw immediately. + */ + private async callWithRetry( + rpc: string, + method: string, + params: unknown[], + maxRetries = 5, + delayMs = 200, + ): Promise { + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + return await this.call(rpc, method, params) + } catch (error) { + if (!(error instanceof TransientRpcError)) throw error + if (attempt === maxRetries) throw error + await new Promise(resolve => setTimeout(resolve, delayMs)) + } + } + throw new Error( + `callWithRetry: maxRetries must be >= 1 (got ${maxRetries})`, + ) + } +} + +// --------------------------------------------------------------------------- +// Common funding presets (convenience constants) +// --------------------------------------------------------------------------- + +const ETH = 10n ** 18n +const USDT_UNIT = 10n ** 6n +const USDC_UNIT = 10n ** 6n + +/** Funding presets for tests */ +export const FUNDING_PRESETS = { + // Below-minimum validation presets + /** W-4: Below minimum validation. ETH only (no WETH needed — validation fires first). */ + WETH_BELOW_MIN: { eth: 1n * ETH } satisfies FundingPreset, + + /** S-2: SNT below minimum. Need SNT > 0.5 to pass balance check. */ + SNT_BELOW_MIN: { eth: 1n * ETH, snt: 1n * ETH } satisfies FundingPreset, + + /** L-2: LINEA below minimum. Need LINEA > 0.5 to pass balance check. */ + LINEA_BELOW_MIN: { linea: 2n * ETH } satisfies FundingPreset, + + // Happy-path deposit presets + /** W-1: Wrap ETH then deposit. Only ETH, no WETH. */ + WETH_DEPOSIT_WRAP: { eth: 5n * ETH } satisfies FundingPreset, + + /** W-2: Direct deposit, pre-funded WETH. */ + WETH_DEPOSIT_DIRECT: { + eth: 1n * ETH, + weth: 1n * ETH, + } satisfies FundingPreset, + + /** W-3: Partial wrap. Some WETH + ETH to cover the rest. */ + WETH_DEPOSIT_PARTIAL: { + eth: 5n * ETH, + weth: ETH / 100n, + } satisfies FundingPreset, + + /** S-1: SNT deposit. */ + SNT_DEPOSIT: { eth: 1n * ETH, snt: 100n * ETH } satisfies FundingPreset, + + /** L-1: LINEA deposit. ETH on Linea comes from base snapshot. */ + LINEA_DEPOSIT: { linea: 100n * ETH } satisfies FundingPreset, + + /** G-1: GUSD via USDT. */ + GUSD_USDT_DEPOSIT: { + eth: 1n * ETH, + usdt: 100n * USDT_UNIT, + } satisfies FundingPreset, + + /** G-2: GUSD via USDC. */ + GUSD_USDC_DEPOSIT: { + eth: 1n * ETH, + usdc: 100n * USDC_UNIT, + } satisfies FundingPreset, + + /** G-3: GUSD via USDS. */ + GUSD_USDS_DEPOSIT: { + eth: 1n * ETH, + usds: 100n * ETH, + } satisfies FundingPreset, +} as const diff --git a/e2e/src/helpers/hub-test-helpers.ts b/e2e/src/helpers/hub-test-helpers.ts index 52257d149..43e423b34 100644 --- a/e2e/src/helpers/hub-test-helpers.ts +++ b/e2e/src/helpers/hub-test-helpers.ts @@ -3,6 +3,11 @@ import { NOTIFICATION_TIMEOUTS } from '@constants/timeouts.js' import type { MetaMaskPage } from '@pages/metamask/metamask.page.js' import type { Page } from '@playwright/test' +/** Minimal EIP-1193 shape for tests (injected `window.ethereum`). */ +type WindowEthereumProvider = { + request: (args: { method: string; params?: unknown[] }) => Promise +} + /** * Force-switch MetaMask to a specific chain via the hub page. * @@ -15,10 +20,26 @@ export async function switchMetaMaskToChain( metamask: MetaMaskPage, chainIdHex: string, ): Promise { + const currentChainId = await hubPage + .evaluate(() => { + const eth = (window as unknown as Record).ethereum as + | WindowEthereumProvider + | undefined + return eth?.request({ method: 'eth_chainId' }) + }) + .catch(() => null) + + if (currentChainId === chainIdHex) { + return + } + await metamask.dismissPendingAddNetwork() await hubPage.evaluate(chainId => { - ;(window as any).ethereum + const eth = (window as unknown as Record).ethereum as + | WindowEthereumProvider + | undefined + eth ?.request({ method: 'wallet_switchEthereumChain', params: [{ chainId }], diff --git a/e2e/src/helpers/service-worker-patch.ts b/e2e/src/helpers/service-worker-patch.ts new file mode 100644 index 000000000..634e7b7ce --- /dev/null +++ b/e2e/src/helpers/service-worker-patch.ts @@ -0,0 +1,376 @@ +import { CHAIN_ID_LINEA, CHAIN_ID_MAINNET } from '@constants/chain-ids.js' +import { + KNOWN_LINEA_HOSTS, + KNOWN_LINEA_PATHS, + KNOWN_MAINNET_HOSTS, + KNOWN_MAINNET_PATHS, +} from '@constants/rpc-hosts.js' + +export const PATCH_MARKER = '/* __ANVIL_RPC_PATCH__ */' + +/** + * Generate JS patch for MetaMask's service worker (prepended to app-init.js). + * Wraps globalThis.fetch to redirect RPC to Anvil. Runs BEFORE LavaMoat lockdown — + * must not reference any scuttled globals (URL, Intl, etc.), only primitives + fetch. + */ +export function buildServiceWorkerPatch( + mainnetRpc: string, + lineaRpc: string, +): string { + return `${PATCH_MARKER} +(function() { + const _f = globalThis.fetch; + const _R = globalThis.Response; + const _c = {}; + const _m = { '${CHAIN_ID_MAINNET}': '${mainnetRpc}', '${CHAIN_ID_LINEA}': '${lineaRpc}' }; + const _tx = {}; + let _stxCounter = 0; + const _stxHashes = {}; + + // Mock linea_estimateGas — returning instantly prevents MetaMask from + // re-rendering the confirmation page mid-click (async response race). + function _mockLineaEstimateGas(body) { + const idMatch = body.match(/"id"\\s*:\\s*(\\d+)/); + const id = idMatch ? idMatch[1] : '1'; + return Promise.resolve(new _R( + '{"jsonrpc":"2.0","id":' + id + ',"result":{"baseFeePerGas":"0x174876E800","priorityFeePerGas":"0x3b9aca00","gasLimit":"0x989680"}}', + { status: 200, headers: { 'Content-Type': 'application/json' } } + )); + } + + // Mock eth_estimateGas — same rationale: instant response prevents + // MetaMask gas estimation from stalling the confirmation UI when + // Anvil is slow after evm_revert (re-fetching contract state). + function _mockEthEstimateGas(body) { + const idMatch = body.match(/"id"\\s*:\\s*(\\d+)/); + const id = idMatch ? idMatch[1] : '1'; + return Promise.resolve(new _R( + '{"jsonrpc":"2.0","id":' + id + ',"result":"0x989680"}', + { status: 200, headers: { 'Content-Type': 'application/json' } } + )); + } + + // Hostname/path-based chain detection (from constants/rpc-hosts.ts). + // Paths are checked first — one puzzle-auth host (snt.eth-rpc.status.im) serves + // multiple chains, so the URL path is the only reliable discriminator there. + const _mainnetHosts = [${KNOWN_MAINNET_HOSTS.map(h => `'${h}'`).join(',')}]; + const _lineaHosts = [${KNOWN_LINEA_HOSTS.map(h => `'${h}'`).join(',')}]; + const _mainnetPaths = [${KNOWN_MAINNET_PATHS.map(p => `'${p}'`).join(',')}]; + const _lineaPaths = [${KNOWN_LINEA_PATHS.map(p => `'${p}'`).join(',')}]; + function _chainByHost(u) { + // Linea first: 'linea-mainnet.infura.io' contains 'mainnet.infura.io' + for (let lp = 0; lp < _lineaPaths.length; lp++) { if (u.indexOf(_lineaPaths[lp]) !== -1) return '${CHAIN_ID_LINEA}'; } + for (let mp = 0; mp < _mainnetPaths.length; mp++) { if (u.indexOf(_mainnetPaths[mp]) !== -1) return '${CHAIN_ID_MAINNET}'; } + for (let j = 0; j < _lineaHosts.length; j++) { if (u.indexOf(_lineaHosts[j]) !== -1) return '${CHAIN_ID_LINEA}'; } + for (let i = 0; i < _mainnetHosts.length; i++) { if (u.indexOf(_mainnetHosts[i]) !== -1) return '${CHAIN_ID_MAINNET}'; } + return null; + } + + function _txHashFromBody(body) { + if (!body || typeof body !== 'string') return null; + const m = body.match(/"params"\\s*:\\s*\\[\\s*"(0x[a-fA-F0-9]{64})"/); + return m ? m[1].toLowerCase() : null; + } + + function _isReceiptRequest(body) { + return !!(body && typeof body === 'string' + && (body.indexOf('"method":"eth_getTransactionReceipt"') !== -1 + || body.indexOf('"method":"eth_getTransactionByHash"') !== -1)); + } + + function _rememberTxHash(anvilUrl, response) { + try { + const c = response.clone(); + return c.text().then(function(text) { + const m = text.match(/"result"\\s*:\\s*"(0x[a-fA-F0-9]{64})"/); + if (m) _tx[m[1].toLowerCase()] = anvilUrl; + return response; + }).catch(function() { + return response; + }); + } catch (_) { + return Promise.resolve(response); + } + } + + // Forward to Anvil. After sendRawTransaction, fire-and-forget evm_mine + // (must NOT await — blocking the fetch response causes MetaMask timeouts). + const _mineInit = { method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: '{"jsonrpc":"2.0","method":"evm_mine","params":[],"id":99998}' }; + function _fwd(anvilUrl, init) { + const p = _f(anvilUrl, init); + if (init && init.body && typeof init.body === 'string' + && init.body.indexOf('eth_sendRawTransaction') !== -1) { + return p.then(function(res) { + return _rememberTxHash(anvilUrl, res).then(function(r) { + _f(anvilUrl, _mineInit).catch(function() {}); + return r; + }); + }); + } + return p; + } + + function _hasNonNullRpcResult(response) { + try { + const c = response.clone(); + return c.text().then(function(text) { + try { + const parsed = JSON.parse(text); + if (Array.isArray(parsed)) { + for (let i = 0; i < parsed.length; i++) { + if (parsed[i] && parsed[i].result !== null && parsed[i].result !== undefined) return true; + } + return false; + } + return parsed.result !== null && parsed.result !== undefined; + } catch (_) { return false; } + }).catch(function() { + return false; + }); + } catch (_) { + return Promise.resolve(false); + } + } + + // Receipt may be on either fork after network switch — try both. + function _fwdReceiptWithFallback(init, preferredAnvilUrl) { + const main = _m['${CHAIN_ID_MAINNET}']; + const linea = _m['${CHAIN_ID_LINEA}']; + const first = preferredAnvilUrl || main; + const second = first === linea ? main : linea; + if (!first) return _fwd(linea, init); + if (!second || second === first) return _fwd(first, init); + + return _fwd(first, init).then(function(r1) { + return _hasNonNullRpcResult(r1).then(function(ok1) { + if (ok1) return r1; + return _fwd(second, init).then(function(r2) { + return _hasNonNullRpcResult(r2).then(function(ok2) { + return ok2 ? r2 : r1; + }); + }); + }); + }); + } + + globalThis.fetch = function(input, init) { + // Intercept STX relay API — redirect tx submissions to Anvil instead of + // blocking (blocking causes MetaMask to mark txs as failed without fallback). + const _url = (typeof input === 'string') ? input + : (input && input.url) ? input.url : '' + input; + if (_url.indexOf('transaction.api') !== -1 + || _url.indexOf('smart-transactions') !== -1 + || _url.indexOf('tx-sentinel') !== -1) { + // A. submitTransactions — forward raw txs to Anvil, return fake uuid + try { + const _stxBody = (init && init.body && typeof init.body === 'string') ? init.body : ''; + if (_stxBody && (_stxBody.indexOf('rawTxs') !== -1 || _stxBody.indexOf('transactions') !== -1)) { + const _cidMatch = _url.match(/\\/networks\\/(\\d+)\\//); + const _cidQueryMatch = _url.match(/[?&]chainId=(\\d+)/); + const _stxChainId = _cidMatch ? _cidMatch[1] : (_cidQueryMatch ? _cidQueryMatch[1] : _chainByHost(_url)); + const _stxTargets = []; + if (_stxChainId && _m[_stxChainId]) { + _stxTargets.push(_m[_stxChainId]); + } else { + if (_m['${CHAIN_ID_MAINNET}']) _stxTargets.push(_m['${CHAIN_ID_MAINNET}']); + if (_m['${CHAIN_ID_LINEA}'] && _m['${CHAIN_ID_LINEA}'] !== _m['${CHAIN_ID_MAINNET}']) _stxTargets.push(_m['${CHAIN_ID_LINEA}']); + } + // Handles { rawTxs: ["0x..."] } and { transactions: [{ rawTx: "0x..." }] } + const _rawTxList = []; + try { + const _parsed = JSON.parse(_stxBody); + if (Array.isArray(_parsed.rawTxs) && _parsed.rawTxs.length) { + _rawTxList.push(..._parsed.rawTxs); + } else if (Array.isArray(_parsed.transactions) && _parsed.transactions.length) { + for (let _pi = 0; _pi < _parsed.transactions.length; _pi++) { + if (_parsed.transactions[_pi].rawTx) _rawTxList.push(_parsed.transactions[_pi].rawTx); + } + } + } catch (_parseErr) { + console.warn('[anvil-stx] Failed to parse STX body: ' + _parseErr); + } + if (_rawTxList.length === 0) { + console.warn('[anvil-stx] No raw txs extracted from STX body'); + } + console.log('[anvil-stx] submitTx chainId=' + _stxChainId + ' txCount=' + _rawTxList.length); + const _fakeUuid = 'anvil-stx-' + Date.now() + '-' + (++_stxCounter); + if (_rawTxList.length && _stxTargets.length) { + // Wait for Anvil response so hash is ready for batchStatus poll + const _fwdPromises = []; + for (let _ri = 0; _ri < _rawTxList.length; _ri++) { + for (let _ti = 0; _ti < _stxTargets.length; _ti++) { + _fwdPromises.push( + _fwd(_stxTargets[_ti], { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["' + _rawTxList[_ri] + '"],"id":99997}' + }).then(function(res) { + return res.clone().text().then(function(text) { + const hm = text.match(/"result"\\s*:\\s*"(0x[a-fA-F0-9]{64})"/); + return hm ? hm[1] : null; + }); + }).catch(function() { return null; }) + ); + } + } + // Store the first valid tx hash for batchStatus lookups + return Promise.all(_fwdPromises).then(function(hashes) { + for (let _hi = 0; _hi < hashes.length; _hi++) { + if (hashes[_hi]) { _stxHashes[_fakeUuid] = hashes[_hi]; break; } + } + return new _R('{"uuid":"' + _fakeUuid + '"}', { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + }); + } + // No raw txs found + return Promise.resolve(new _R('{"uuid":"' + _fakeUuid + '"}', { + status: 200, + headers: { 'Content-Type': 'application/json' } + })); + } + } catch (_stxErr) {} + + // B. batchStatus — return fake status keyed by UUID + if (_url.indexOf('batchStatus') !== -1) { + const _uuidsMatch = _url.match(/[?&]uuids=([^&]+)/); + if (_uuidsMatch) { + try { + const _uuidList = decodeURIComponent(_uuidsMatch[1]).split(','); + let _statusJson = '{'; + for (let _si = 0; _si < _uuidList.length; _si++) { + if (_si > 0) _statusJson += ','; + const _uid = _uuidList[_si]; + const _hash = _stxHashes[_uid]; + console.log('[anvil-stx] batchStatus uuid=' + _uid + ' hasHash=' + !!_hash); + if (_hash) { + _statusJson += '"' + _uid + '":{"minedTx":"success","minedHash":"' + _hash + '","cancellationReason":"not_cancelled"}'; + } else { + // Not ready — MetaMask will retry + _statusJson += '"' + _uid + '":{"minedTx":"not_mined","cancellationReason":"not_cancelled"}'; + } + } + _statusJson += '}'; + return Promise.resolve(new _R(_statusJson, { + status: 200, + headers: { 'Content-Type': 'application/json' } + })); + } catch (_bsErr) {} + } + } + + // C. All other STX API calls — empty success + return Promise.resolve(new _R('{}', { + status: 200, + headers: { 'Content-Type': 'application/json' } + })); + } + + // Handle fetch(Request) — decompose into (url, init) form + if (typeof input !== 'string' && input && typeof input.clone === 'function') { + const reqMethod = (init && init.method) || input.method || 'GET'; + if (reqMethod !== 'POST') return _f.apply(globalThis, arguments); + const _inp = input; + const _ini = init; + return _inp.clone().text().then(function(body) { + if (body.indexOf('"jsonrpc"') === -1) return _f(_inp, _ini); + if (body.indexOf('"method":"linea_estimateGas"') !== -1) return _mockLineaEstimateGas(body); + if (body.indexOf('"method":"eth_estimateGas"') !== -1) return _mockEthEstimateGas(body); + if (body.indexOf('"method":"linea_') !== -1) return _f(_inp, _ini); + const isReceipt = _isReceiptRequest(body); + const txh = _txHashFromBody(body); + if (isReceipt) { + const n1 = { method: 'POST', body: body, headers: { 'Content-Type': 'application/json' } }; + if (_ini) { for (const k1 in _ini) { if (!(k1 in n1)) n1[k1] = _ini[k1]; } } + return _fwdReceiptWithFallback(n1, txh && _tx[txh] ? _tx[txh] : null); + } + const ni = { method: 'POST', body: body, headers: { 'Content-Type': 'application/json' } }; + if (_ini) { for (const k in _ini) { if (!(k in ni)) ni[k] = _ini[k]; } } + return globalThis.fetch(_inp.url || ('' + _inp), ni); + }); + } + + let url; + if (typeof input === 'string') { url = input; } + else if (input && input.url) { url = input.url; } + else { url = '' + input; } + + if (!init || init.method !== 'POST' || typeof init.body !== 'string' + || init.body.indexOf('"jsonrpc"') === -1) { + return _f.apply(globalThis, arguments); + } + + const txh2 = _txHashFromBody(init.body); + if (_isReceiptRequest(init.body)) { + const _rxPref = txh2 && _tx[txh2] ? _tx[txh2] : null; + return _fwdReceiptWithFallback(init, _rxPref); + } + + // linea_estimateGas / eth_estimateGas → mock; other linea_* → passthrough + if (init.body.indexOf('"method":"linea_estimateGas"') !== -1) { + return _mockLineaEstimateGas(init.body); + } + if (init.body.indexOf('"method":"eth_estimateGas"') !== -1) { + return _mockEthEstimateGas(init.body); + } + if (init.body.indexOf('"method":"linea_') !== -1) { + return _f.apply(globalThis, arguments); + } + + if (url.indexOf('chrome-extension:') === 0 + || url.indexOf('localhost') !== -1 + || url.indexOf('127.0.0.1') !== -1) { + return _f.apply(globalThis, arguments); + } + + if (url in _c) { + const cached = _c[url]; + if (typeof cached === 'string') { + return _fwd(cached, init); + } + if (cached === null) return _f.apply(globalThis, arguments); + return cached.then(function(u) { + return u ? _fwd(u, init) : _f(url, init); + }); + } + + const ci = url.match(/[?&]chainId=(\\d+)/); + if (ci) { + _c[url] = _m[ci[1]] || null; + return _c[url] ? _fwd(_c[url], init) : _f.apply(globalThis, arguments); + } + + // Hostname-based lookup + const _hc = _chainByHost(url); + if (_hc) { + _c[url] = _m[_hc] || null; + return _c[url] ? _fwd(_c[url], init) : _f.apply(globalThis, arguments); + } + + const probe = _f(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":99999}' + }).then(function(r) { return r.json(); }) + .then(function(j) { + const cid = '' + parseInt(j.result, 16); + const target = _m[cid] || null; + _c[url] = target; + return target; + }) + .catch(function() { + // Don't cache null — permanent null leaks requests to real chain + delete _c[url]; + return null; + }); + + _c[url] = probe; + return probe.then(function(u) { + return u ? _fwd(u, init) : _f(url, init); + }); + }; +})(); +` +} diff --git a/e2e/src/helpers/stx-patcher.ts b/e2e/src/helpers/stx-patcher.ts new file mode 100644 index 000000000..1aad24d85 --- /dev/null +++ b/e2e/src/helpers/stx-patcher.ts @@ -0,0 +1,177 @@ +import fs from 'node:fs' +import path from 'node:path' + +interface StxPatchPattern { + name: string + detect: RegExp + transform: (content: string) => string + reverseTransform: (content: string) => string +} + +const stxPatchedFiles: Array<{ path: string; original: string }> = [] + +// Category A: property value patterns (stable — these are serialized storage keys). +// Category B: publish hook patterns (fragile — depend on Terser output shape). +// If B breaks on MetaMask update, SW fetch interceptor handles STX as fallback. +const STX_PATTERNS: StxPatchPattern[] = [ + // --- Category A: Property value patterns --- + { + name: 'STX opt-in default', + detect: /smartTransactionsOptInStatus:![01]/, + transform: content => + content.replace( + /smartTransactionsOptInStatus:![01]/g, + 'smartTransactionsOptInStatus:!1', + ), + reverseTransform: content => + content.replace( + /smartTransactionsOptInStatus:!1/g, + 'smartTransactionsOptInStatus:!0', + ), + }, + { + name: 'TX simulations default', + detect: /useTransactionSimulations:![01]/, + transform: content => + content.replace( + /useTransactionSimulations:![01]/g, + 'useTransactionSimulations:!1', + ), + reverseTransform: content => + content.replace( + /useTransactionSimulations:!1/g, + 'useTransactionSimulations:!0', + ), + }, + { + name: 'STX opt-in nullish coalescing fallback', + detect: /smartTransactionsOptInStatus\)\?\?![01]/, + transform: content => + content.replace( + /smartTransactionsOptInStatus\)\?\?![01]/g, + 'smartTransactionsOptInStatus)??!1', + ), + reverseTransform: content => + content.replace( + /smartTransactionsOptInStatus\)\?\?!1/g, + 'smartTransactionsOptInStatus)??!0', + ), + }, + + // --- Category B: Publish hook patterns --- + { + name: 'STX single-tx publish hook', + detect: + /(?:isSmartTransaction:\w+,featureFlags:\w+\}[^;]*getSmartTransactionCommonParams|featureFlags:\w+\}[^;]*getSmartTransactionCommonParams[^;]*\w+=!1,\w+=await)/, + transform: content => + content.replace( + /const\{isSmartTransaction:(\w+),featureFlags:(\w+)\}=\(0,(\w+)\.getSmartTransactionCommonParams\)\((\w+),(\w+)\.chainId\),(\w+)=await\(0,(\w+)\.isSendBundleSupported\)/g, + 'const{featureFlags:$2}=(0,$3.getSmartTransactionCommonParams)($4,$5.chainId),$1=!1,$6=await(0,$7.isSendBundleSupported)', + ), + reverseTransform: content => + content.replace( + /const\{featureFlags:(\w+)\}=\(0,(\w+)\.getSmartTransactionCommonParams\)\((\w+),(\w+)\.chainId\),(\w+)=!1,(\w+)=await\(0,(\w+)\.isSendBundleSupported\)/g, + 'const{isSmartTransaction:$5,featureFlags:$1}=(0,$2.getSmartTransactionCommonParams)($3,$4.chainId),$6=await(0,$7.isSendBundleSupported)', + ), + }, + { + name: 'STX batch-tx publish hook', + detect: + /isSmartTransaction:\w+,featureFlags:\w+\}[^;]*getSmartTransactionCommonParams[^;]*;return (?:\w+|!1)\?/, + transform: content => + content.replace( + /const\{isSmartTransaction:(\w+),featureFlags:(\w+)\}=\(0,(\w+)\.getSmartTransactionCommonParams\)\((\w+),(\w+)\.chainId\);return \1\?/g, + 'const{isSmartTransaction:$1,featureFlags:$2}=(0,$3.getSmartTransactionCommonParams)($4,$5.chainId);return !1?', + ), + reverseTransform: content => + content.replace( + /const\{isSmartTransaction:(\w+),featureFlags:(\w+)\}=\(0,(\w+)\.getSmartTransactionCommonParams\)\((\w+),(\w+)\.chainId\);return !1\?/g, + 'const{isSmartTransaction:$1,featureFlags:$2}=(0,$3.getSmartTransactionCommonParams)($4,$5.chainId);return $1?', + ), + }, +] + +/** + * Disable Smart Transactions by patching extension JS files. + * STX routes txs through MetaMask's relay → breaks Anvil (txs stay "Pending" forever). + */ +export function disableSmartTransactionsInFiles(extensionPath: string): void { + console.log('[anvil-fixture] Patching MetaMask extension for STX disable...') + + const jsFiles = fs + .readdirSync(extensionPath) + .filter(f => f.endsWith('.js')) + .sort() + + const patternMatchCounts = new Map( + STX_PATTERNS.map(p => [p.name, 0]), + ) + + for (const fileName of jsFiles) { + const filePath = path.join(extensionPath, fileName) + const content = fs.readFileSync(filePath, 'utf-8') + + const applicable = STX_PATTERNS.filter(p => p.detect.test(content)) + if (applicable.length === 0) continue + + // Reverse stale patches → re-apply fresh (idempotent) + let trueOriginal = content + for (const p of applicable) { + trueOriginal = p.reverseTransform(trueOriginal) + } + + let patched = trueOriginal + for (const p of applicable) { + patched = p.transform(patched) + } + + const patchNames = applicable.map(p => p.name).join(', ') + + if (patched !== content) { + stxPatchedFiles.push({ path: filePath, original: trueOriginal }) + fs.writeFileSync(filePath, patched) + for (const p of applicable) { + patternMatchCounts.set( + p.name, + (patternMatchCounts.get(p.name) ?? 0) + 1, + ) + } + if (trueOriginal !== content) { + console.log(`[anvil-fixture] ${fileName}: ${patchNames} - RE-PATCHED`) + } else { + console.log(`[anvil-fixture] ${fileName}: ${patchNames} - PATCHED`) + } + } else if (trueOriginal !== content) { + stxPatchedFiles.push({ path: filePath, original: trueOriginal }) + for (const p of applicable) { + patternMatchCounts.set( + p.name, + (patternMatchCounts.get(p.name) ?? 0) + 1, + ) + } + console.log( + `[anvil-fixture] ${fileName}: ${patchNames} - ALREADY PATCHED`, + ) + } + } + + for (const [name, count] of patternMatchCounts) { + if (count === 0) { + console.warn( + `[anvil-fixture] WARNING: pattern "${name}" matched 0 files. ` + + 'MetaMask version may have changed. SW fetch interceptor will handle STX as fallback.', + ) + } + } + + console.log( + `[anvil-fixture] STX patch complete: ${stxPatchedFiles.length} file(s) recorded for restore`, + ) +} + +export function restoreSmartTransactionsFiles(): void { + for (const { path: filePath, original } of stxPatchedFiles) { + fs.writeFileSync(filePath, original) + } + stxPatchedFiles.length = 0 +} diff --git a/e2e/src/pages/hub/components/pre-deposit-modal.component.ts b/e2e/src/pages/hub/components/pre-deposit-modal.component.ts index db6b66991..54aabf887 100644 --- a/e2e/src/pages/hub/components/pre-deposit-modal.component.ts +++ b/e2e/src/pages/hub/components/pre-deposit-modal.component.ts @@ -1,4 +1,8 @@ -import { HUB_TIMEOUTS, NOTIFICATION_TIMEOUTS } from '@constants/timeouts.js' +import { + DEPOSIT_TIMEOUTS, + HUB_TIMEOUTS, + NOTIFICATION_TIMEOUTS, +} from '@constants/timeouts.js' import { expect, type Locator, type Page } from '@playwright/test' export class PreDepositModalComponent { @@ -78,4 +82,48 @@ export class PreDepositModalComponent { timeout: HUB_TIMEOUTS.PAGE_READY, }) } + + /** + * Wait for the modal to settle after a network switch. + * The hub UI re-renders when wagmi detects a chain change, which can + * briefly unmount the action button. + */ + async waitForNetworkReady(): Promise { + await expect(this.switchNetworkButton).not.toBeVisible({ + timeout: NOTIFICATION_TIMEOUTS.OPTIONAL_ELEMENT, + }) + await expect(this.actionButton).toBeVisible({ + timeout: HUB_TIMEOUTS.PAGE_READY, + }) + } + + async clickActionButton(): Promise { + await this.actionButton.click() + } + + /** Wait for action button to become enabled and show expected text */ + async expectActionButtonReady(pattern: RegExp): Promise { + await expect(this.actionButton).toBeEnabled({ + timeout: DEPOSIT_TIMEOUTS.BUTTON_STATE_CHANGE, + }) + await expect(this.actionButton).toHaveText(pattern) + } + + /** Open token dropdown and select a token by label (e.g. "Tether USD, USDT") */ + async selectToken(tokenLabel: string): Promise { + const dropdownTrigger = this.dialog + .locator('button[type="button"]') + .filter({ + has: this.dialog.page().locator('.text-15'), + }) + .first() + await dropdownTrigger.click() + await this.dialog.page().getByRole('menuitem', { name: tokenLabel }).click() + } + + async expectModalClosed(): Promise { + await expect(this.dialog).not.toBeVisible({ + timeout: DEPOSIT_TIMEOUTS.MODAL_CLOSE, + }) + } } diff --git a/e2e/src/pages/metamask/home.page.ts b/e2e/src/pages/metamask/home.page.ts deleted file mode 100644 index 3cdef9ee2..000000000 --- a/e2e/src/pages/metamask/home.page.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { BrowserContext, Page } from '@playwright/test' - -export class MetaMaskHomePage { - constructor( - private readonly context: BrowserContext, - private readonly extensionId: string, - ) {} - - private get homeUrl(): string { - return `chrome-extension://${this.extensionId}/home.html` - } - - /** Open MetaMask home and return its page */ - async open(): Promise { - let mmPage = this.context - .pages() - .find(p => p.url().startsWith(`chrome-extension://${this.extensionId}`)) - - if (!mmPage) { - mmPage = await this.context.newPage() - } - - await mmPage.goto(this.homeUrl) - return mmPage - } - - /** Get the currently selected network name */ - async getNetworkName(page: Page): Promise { - const networkDisplay = page.getByTestId('network-display') - return networkDisplay.textContent() - } - - /** Get the account address */ - async getAccountAddress(page: Page): Promise { - const addressButton = page.getByTestId('account-options-menu-button') - await addressButton.click() - const address = await page - .getByTestId('address-copy-button-text') - .textContent() - await page.keyboard.press('Escape') - return address ?? '' - } -} diff --git a/e2e/src/pages/metamask/metamask.page.ts b/e2e/src/pages/metamask/metamask.page.ts index 936dce8f2..5c4d09b73 100644 --- a/e2e/src/pages/metamask/metamask.page.ts +++ b/e2e/src/pages/metamask/metamask.page.ts @@ -1,6 +1,5 @@ import { EXTENSION_TIMEOUTS } from '@constants/timeouts.js' -import { MetaMaskHomePage } from './home.page.js' import { NotificationPage } from './notification.page.js' import { OnboardingPage } from './onboarding.page.js' @@ -9,7 +8,6 @@ import type { BrowserContext, Page } from '@playwright/test' export class MetaMaskPage { readonly onboarding: OnboardingPage readonly notification: NotificationPage - readonly home: MetaMaskHomePage private readonly extensionPrefix: string @@ -20,7 +18,6 @@ export class MetaMaskPage { this.extensionPrefix = `chrome-extension://${extensionId}` this.onboarding = new OnboardingPage(context, extensionId) this.notification = new NotificationPage(context, extensionId) - this.home = new MetaMaskHomePage(context, extensionId) } /** Find the MetaMask extension page in the current context */ @@ -57,8 +54,8 @@ export class MetaMaskPage { } /** Approve a transaction in the MetaMask notification popup */ - async approveTransaction(): Promise { - await this.notification.approveTransaction() + async approveTransaction(contentTimeout?: number): Promise { + await this.notification.approveTransaction(contentTimeout) } /** Reject a transaction in the MetaMask notification popup */ diff --git a/e2e/src/pages/metamask/notification.page.ts b/e2e/src/pages/metamask/notification.page.ts index d0166b70d..9bbd5f67d 100644 --- a/e2e/src/pages/metamask/notification.page.ts +++ b/e2e/src/pages/metamask/notification.page.ts @@ -1,8 +1,17 @@ import { NOTIFICATION_TIMEOUTS } from '@constants/timeouts.js' -import type { BrowserContext, Page } from '@playwright/test' +import type { BrowserContext, Locator, Page } from '@playwright/test' + +/** Interval for progress logging inside waitConfirmable (ms) */ +const WAIT_CONFIRMABLE_LOG_INTERVAL_MS = 5_000 +/** Max iterations to walk past queued "Add network" popups in MetaMask */ +const MAX_ADD_NETWORK_CLEAR_ATTEMPTS = 10 +/** Default wall-clock budget for clearAddNetworkQueue (ms) */ +const CLEAR_ADD_NETWORK_DEADLINE_MS = 60_000 export class NotificationPage { + private cachedHomePage: Page | null = null + constructor( private readonly context: BrowserContext, private readonly extensionId: string, @@ -22,58 +31,386 @@ export class NotificationPage { } } - /** - * Get the MetaMask notification page. - * Checks for an already-open notification page first, - * then manually opens notification.html. - * - * MetaMask does not auto-open popups in automated (Playwright) contexts, - * so we always open notification.html directly. - */ - private async waitForNotificationPage(): Promise { - // Check if already open - const existing = this.context.pages().find(p => this.isMetaMaskPopup(p)) + private isMetaMaskHome(page: Page): boolean { + try { + const parsed = new URL(page.url()) + return ( + parsed.protocol === 'chrome-extension:' && + parsed.host === this.extensionId && + parsed.pathname.includes('home.html') + ) + } catch { + return false + } + } + + // MetaMask v13.18.1 uses different test IDs per confirmation type + private confirmButton(page: Page): Locator { + return page + .getByTestId('page-container-footer-next') + .or(page.getByTestId('confirmation-submit-button')) + .or(page.getByTestId('confirm-footer-button')) + .or(page.getByRole('button', { name: /^confirm$/i })) + } + private cancelButton(page: Page): Locator { + return page + .getByTestId('confirmation-cancel-button') + .or(page.getByTestId('confirm-footer-cancel-button')) + .or(page.getByRole('button', { name: /^cancel$/i })) + } + + private async isSpendingCapConfirmation(page: Page): Promise { + return page + .getByText( + /spending cap|permission to withdraw|allow this site to spend/i, + ) + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.SHORT_SETTLE }) + .catch(() => false) + } + + private async getOrCreateHomePage(): Promise { + if (this.cachedHomePage && !this.cachedHomePage.isClosed()) { + return this.cachedHomePage + } + + const existing = this.context + .pages() + .find(p => this.isMetaMaskHome(p) && !p.isClosed()) if (existing) { - await existing.waitForLoadState('domcontentloaded') + this.cachedHomePage = existing return existing } - // Open notification.html directly + const page = await this.context.newPage() + await page.goto(`chrome-extension://${this.extensionId}/home.html`, { + waitUntil: 'load', + }) + this.cachedHomePage = page + return page + } + + /** + * Check MetaMask Activity for any "Unapproved" tx. + * Used to verify approveTransaction() confirmed the right request, + * not a stale one from the queue. + */ + private async hasUnapprovedActivityEntry(): Promise { + const homePage = await this.getOrCreateHomePage() + + // Activity entries are only visible on the Activity tab, not default Tokens tab + const activityTab = homePage + .getByRole('tab', { name: /^activity$/i }) + .or(homePage.getByRole('button', { name: /^activity$/i })) + .or(homePage.getByText(/^activity$/i)) + if ( + await activityTab + .first() + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.CONTENT_CHECK }) + .catch(() => false) + ) { + await activityTab + .first() + .click() + .catch(() => {}) + await homePage.waitForTimeout(NOTIFICATION_TIMEOUTS.DOM_SETTLE) + } + + return homePage + .getByText(/unapproved/i) + .first() + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.CONTENT_CHECK }) + .catch(() => false) + } + + private async dismissToastOverlays(page: Page): Promise { + const toast = page.getByTestId('storage-error-toast-banner-base') + if ( + await toast + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.DOM_SETTLE }) + .catch(() => false) + ) { + const closeBtn = toast + .locator('[aria-label="Close"]') + .or(toast.getByRole('button', { name: /close|dismiss/i })) + .or(toast.locator('button').first()) + await closeBtn.click().catch(() => {}) + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.DOM_SETTLE) + } + } + + private async closeStaleNotificationPages(): Promise { + let closed = false + for (const p of this.context.pages()) { + if (this.isMetaMaskPopup(p) && !p.isClosed()) { + await p.close() + closed = true + } + } + // Wait for service worker to release the messaging port + if (closed) { + await new Promise(resolve => + setTimeout(resolve, NOTIFICATION_TIMEOUTS.SHORT_SETTLE), + ) + } + } + + /** + * Open notification.html and wait for MetaMask to push content. + * We open ONCE and wait patiently — rapid reloads disconnect the MV3 + * messaging port, which MetaMask may interpret as user rejection. + */ + private async waitForNotificationPage( + contentTimeout: number = NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, + ): Promise { + for (const p of this.context.pages()) { + if (this.isMetaMaskPopup(p) && !p.isClosed()) { + const hasContent = await p + .locator('button') + .first() + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.CONTENT_CHECK }) + .catch(() => false) + if (hasContent) return p + } + } + const page = await this.context.newPage() await page.goto( `chrome-extension://${this.extensionId}/notification.html`, - { waitUntil: 'domcontentloaded' }, + { waitUntil: 'load' }, ) + + // Can take 10-60s: gas estimation + Blockaid security checks + const hasContent = await page + .locator('button') + .first() + .isVisible({ timeout: contentTimeout }) + .catch(() => false) + + if (!hasContent) { + if (!page.isClosed()) await page.close() + await new Promise(resolve => + setTimeout(resolve, NOTIFICATION_TIMEOUTS.PAGE_REOPEN), + ) + + const freshPage = await this.context.newPage() + await freshPage.goto( + `chrome-extension://${this.extensionId}/notification.html`, + { waitUntil: 'load' }, + ) + await freshPage + .locator('button') + .first() + .isVisible({ timeout: contentTimeout }) + .catch(() => false) + return freshPage + } + return page } - /** Approve a dApp connection request */ + private async waitForConfirmablePopupPage(timeout: number): Promise { + const t0 = Date.now() + const deadline = t0 + timeout + let openedFallbackPage = false + let iterCount = 0 + let lastLog = t0 + + while (Date.now() < deadline) { + iterCount++ + const popups = this.context + .pages() + .filter(p => this.isMetaMaskPopup(p) && !p.isClosed()) + + for (const p of popups) { + const hasConfirm = await this.confirmButton(p) + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.DOM_SETTLE }) + .catch(() => false) + if (hasConfirm) return p + } + + // Log every 5s with current state + if (Date.now() - lastLog > WAIT_CONFIRMABLE_LOG_INTERVAL_MS) { + console.log( + `[waitConfirmable +${Date.now() - t0}ms] iters=${iterCount} popups=${popups.length} fallbackOpened=${openedFallbackPage}`, + ) + lastLog = Date.now() + } + + if (!openedFallbackPage) { + // Open notification.html so MetaMask can push queued confirmations. + const fallback = await this.context.newPage() + await fallback + .goto(`chrome-extension://${this.extensionId}/notification.html`, { + waitUntil: 'load', + }) + .catch(() => {}) + openedFallbackPage = true + console.log( + `[waitConfirmable +${Date.now() - t0}ms] opened fallback page`, + ) + } + + await new Promise(resolve => + setTimeout(resolve, NOTIFICATION_TIMEOUTS.POLL_INTERVAL), + ) + } + + throw new Error('MetaMask transaction confirmation button did not appear') + } + async approveConnection(): Promise { - const page = await this.waitForNotificationPage() + const t0 = Date.now() + const log = (msg: string) => + console.log(`[approveConnection +${Date.now() - t0}ms] ${msg}`) + + let page = this.context + .pages() + .find(p => this.isMetaMaskPopup(p) && !p.isClosed()) + + if (page) { + log('reusing existing popup') + } else { + page = await this.context.newPage() + await page.goto( + `chrome-extension://${this.extensionId}/notification.html`, + { waitUntil: 'load' }, + ) + log('opened notification.html') + } const connectButton = page .getByRole('button', { name: /^connect$/i }) .or(page.getByTestId('page-container-footer-next')) + log('waiting for Connect button...') await connectButton.click({ - timeout: NOTIFICATION_TIMEOUTS.TRANSACTION_CONFIRM, + timeout: NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, }) + log('Connect clicked') } /** Approve a transaction (Confirm button) */ - async approveTransaction(): Promise { - const page = await this.waitForNotificationPage() + async approveTransaction( + contentTimeout: number = NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, + ): Promise { + const t0 = Date.now() + const log = (msg: string) => + console.log(`[approveTransaction +${Date.now() - t0}ms] ${msg}`) - const confirmButton = page - .getByTestId('page-container-footer-next') - .or(page.getByRole('button', { name: /confirm/i })) - await confirmButton.click({ - timeout: NOTIFICATION_TIMEOUTS.TRANSACTION_CONFIRM, - }) + log('start') + const deadline = Date.now() + contentTimeout + let page: Page | null = null + + while (Date.now() < deadline) { + const remaining = Math.max( + NOTIFICATION_TIMEOUTS.PAGE_REOPEN, + deadline - Date.now(), + ) + page = await this.waitForConfirmablePopupPage(remaining) + log('found confirmable page') + page = await this.clearAddNetworkQueue( + page, + MAX_ADD_NETWORK_CLEAR_ATTEMPTS, + deadline, + ) + + // Skip stale spending-cap confirmation from approveTokenSpend() — + // otherwise we "confirm" the wrong request and the deposit stays pending + if (await this.isSpendingCapConfirmation(page)) { + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.SHORT_SETTLE) + continue + } + + const confirm = this.confirmButton(page) + const hasConfirm = await confirm + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.CONTENT_CHECK }) + .catch(() => false) + + if (!hasConfirm) { + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.SHORT_SETTLE) + continue + } + + // Dismiss toast overlays that block clicks, then force-click — MetaMask + // may re-render during gas estimation, detaching the DOM element + await this.dismissToastOverlays(page) + log('clicking Confirm...') + try { + await confirm.click({ + timeout: NOTIFICATION_TIMEOUTS.TRANSACTION_CONFIRM, + force: true, + }) + log('Confirm clicked') + } catch (err) { + const msg = err instanceof Error ? err.message : '' + log(`Confirm click error: ${msg}`) + if (!msg.includes('Timeout') && !msg.includes('detach')) throw err + + // Click may have succeeded despite error — check if button disappeared + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.SHORT_SETTLE) + const stillVisible = await this.confirmButton(page) + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.PAGE_REOPEN }) + .catch(() => false) + if (!stillVisible) { + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.PAGE_REOPEN) + const confirmedAfterError = !(await this.hasUnapprovedActivityEntry()) + if (confirmedAfterError) { + if (!page.isClosed()) await page.close() + return + } + } + continue + } + if (page.isClosed()) return + + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.POST_CLICK) + + if (page.isClosed()) return + + // MetaMask v13 two-step flow: Next → Confirm + const secondConfirm = this.confirmButton(page) + if ( + await secondConfirm + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.ELEMENT_VISIBLE }) + .catch(() => false) + ) { + try { + await secondConfirm.click({ + timeout: NOTIFICATION_TIMEOUTS.TRANSACTION_CONFIRM, + force: true, + }) + } catch (err) { + const msg = err instanceof Error ? err.message : '' + if (!msg.includes('Timeout') && !msg.includes('detach')) throw err + } + if (!page.isClosed()) + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.PAGE_REOPEN) + } + + if (page.isClosed()) return + + // Let service worker dispatch the tx before closing + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.CONTENT_CHECK) + const stillUnapproved = await this.hasUnapprovedActivityEntry() + if (stillUnapproved) { + if (!page.isClosed()) await page.close() + await new Promise(resolve => + setTimeout(resolve, NOTIFICATION_TIMEOUTS.SHORT_SETTLE), + ) + continue + } + + if (!page.isClosed()) await page.close() + log('done') + return + } + + log('TIMEOUT — confirm button never appeared') + if (page && !page.isClosed()) await page.close().catch(() => {}) + throw new Error('MetaMask transaction confirmation button did not appear') } - /** Reject a transaction (Cancel button) */ async rejectTransaction(): Promise { const page = await this.waitForNotificationPage() @@ -83,7 +420,6 @@ export class NotificationPage { await cancelButton.click() } - /** Approve adding/switching to a new network */ async approveNetworkSwitch(): Promise { const page = await this.waitForNotificationPage() @@ -96,39 +432,168 @@ export class NotificationPage { } /** - * Dismiss a pending "Add network" request queued by the hub on page load. - * Approves the request so the network is added and MetaMask switches to it. - * Safe to call when there are no pending requests (returns early). + * Dismiss pending "Add network" requests. Uses "Reject all" when multiple + * are queued (only safe before any transaction is pending). */ async dismissPendingAddNetwork(): Promise { - // Reuse an existing notification page if MetaMask kept one open - // after the connection step (MetaMask reuses it for the next pending request). - const page = await this.waitForNotificationPage() + const t0 = Date.now() + const log = (msg: string) => + console.log(`[dismissAddNetwork +${Date.now() - t0}ms] ${msg}`) - // MetaMask notification.html is a React SPA — buttons render after JS hydration. - // Wait for the hub's wallet_addEthereumChain request to arrive and render. - const confirmButton = page.getByRole('button', { name: /^confirm$/i }) - const hasPending = await confirmButton + log('start') + const page = await this.waitForNotificationPage( + NOTIFICATION_TIMEOUTS.ELEMENT_VISIBLE, + ) + log('notification page ready') + + const rejectAll = page + .getByTestId('confirm_nav__reject_all') + .or(page.getByText(/reject all/i)) + if ( + await rejectAll + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.BUTTON_TRANSITION }) + .catch(() => false) + ) { + log('found rejectAll — clicking') + await rejectAll.click() + await page.waitForLoadState('load').catch(() => {}) + if (!page.isClosed()) await page.close() + log('done (rejectAll)') + return + } + log('no rejectAll') + + const cancel = this.cancelButton(page) + const hasPending = await cancel .isVisible({ timeout: NOTIFICATION_TIMEOUTS.BUTTON_TRANSITION }) .catch(() => false) if (!hasPending) { + log('no pending — closing') if (!page.isClosed()) await page.close() + log('done (no pending)') return } - await confirmButton.click() + log('found cancel — clicking') + await cancel.click() + // await confirmButton.click() // Wait for MetaMask to finish processing, then close the page. await page.waitForLoadState('load').catch(() => {}) if (!page.isClosed()) await page.close() } - /** Approve a token spending allowance */ + /** + * Skip past any "Add network" popups in MetaMask's confirmation queue. + * Uses ">" (next) button to navigate past them without canceling — canceling + * triggers DOM re-renders that detach buttons mid-click. + */ + private async clearAddNetworkQueue( + page: Page, + maxAttempts = MAX_ADD_NETWORK_CLEAR_ATTEMPTS, + deadline = Date.now() + CLEAR_ADD_NETWORK_DEADLINE_MS, + ): Promise { + const currentPage = page + for (let i = 0; i < maxAttempts && Date.now() < deadline; i++) { + const anyButton = currentPage.locator('button') + const rendered = await anyButton + .first() + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.BUTTON_TRANSITION }) + .catch(() => false) + + if (!rendered) return currentPage + + const isAddNetwork = await currentPage + .getByText(/suggesting additional network/i) + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.CONTENT_CHECK }) + .catch(() => false) + + if (!isAddNetwork) return currentPage + + const nextBtn = currentPage + .getByTestId('confirm-nav__next-confirmation') + .or(currentPage.getByTestId('confirm_nav__right_btn')) + const hasNext = await nextBtn + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.PAGE_REOPEN }) + .catch(() => false) + + if (hasNext) { + await nextBtn.click().catch(() => {}) + await currentPage.waitForTimeout(NOTIFICATION_TIMEOUTS.SHORT_SETTLE) + continue + } + + // Last/only Add Network request — cancel it. + // Do NOT reload after: MetaMask auto-shows the next queued request, + // and a reload disconnects the port causing auto-reject of ALL pending requests. + const cancel = this.cancelButton(currentPage) + try { + await cancel.click({ timeout: NOTIFICATION_TIMEOUTS.ELEMENT_VISIBLE }) + } catch { + await currentPage.waitForTimeout(NOTIFICATION_TIMEOUTS.SHORT_SETTLE) + continue + } + await currentPage.waitForTimeout(NOTIFICATION_TIMEOUTS.CONTENT_CHECK) + } + return currentPage + } + + /** + * Approve a token spending allowance. + * Uses waitForNotificationPage (which has close+reopen fallback) — + * this is safe here because no transaction is pending yet at this point. + */ async approveTokenSpend(): Promise { - const page = await this.waitForNotificationPage() + const t0 = Date.now() + const log = (msg: string) => + console.log(`[approveTokenSpend +${Date.now() - t0}ms] ${msg}`) + + log('start') + await this.closeStaleNotificationPages() + + let page = await this.waitForNotificationPage() + log('notification page ready') + page = await this.clearAddNetworkQueue(page) + + // Wait for spending-cap text before clicking Confirm — the button appears + // before approval details are ready, and early clicks are silently ignored + const spendingCapText = page.getByText( + /spending cap|permission to withdraw/i, + ) + const contentVisible = await spendingCapText + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.ELEMENT_VISIBLE }) + .catch(() => false) + + if (!contentVisible) { + if (!page.isClosed()) await page.close() + await new Promise(resolve => + setTimeout(resolve, NOTIFICATION_TIMEOUTS.PAGE_REOPEN), + ) + + page = await this.context.newPage() + await page.goto( + `chrome-extension://${this.extensionId}/notification.html`, + { waitUntil: 'load' }, + ) + await page + .locator('button') + .first() + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT }) + .catch(() => false) + page = await this.clearAddNetworkQueue(page) + + const freshSpendingCapText = page.getByText( + /spending cap|permission to withdraw/i, + ) + await freshSpendingCapText + .waitFor({ + state: 'visible', + timeout: NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, + }) + .catch(() => {}) + } - // There may be a "Use default" or custom amount step const useDefaultButton = page.getByRole('button', { name: /use default/i, }) @@ -140,17 +605,46 @@ export class NotificationPage { await useDefaultButton.click() } - const nextButton = page.getByTestId('page-container-footer-next') - await nextButton.click() + await this.dismissToastOverlays(page) + log('clicking Confirm...') + await this.confirmButton(page).click({ + timeout: NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, + force: true, + }) + log('Confirm clicked') + + // MetaMask v13 may use 2-step approval: Next → Approve. + // On Anvil the approval confirms instantly and the Hub immediately fires + // the deposit tx, so a second Confirm may belong to the DEPOSIT, not + // a second approval step. Only click if still on the spending-cap page. + await page.waitForTimeout(NOTIFICATION_TIMEOUTS.CONTENT_CHECK) + const secondConfirm = this.confirmButton(page) + if ( + await secondConfirm + .isVisible({ timeout: NOTIFICATION_TIMEOUTS.ELEMENT_VISIBLE }) + .catch(() => false) + ) { + if (await this.isSpendingCapConfirmation(page)) { + await this.dismissToastOverlays(page) + await secondConfirm.click({ + timeout: NOTIFICATION_TIMEOUTS.NOTIFICATION_CONTENT, + force: true, + }) + } + } + + // Do NOT close — the Hub fires the deposit tx immediately after approval. + // Closing disconnects the messaging port → service worker auto-rejects + // any tx arriving during reconnection. approveTransaction() reuses this page. } /** Sign a message (SIWE or EIP-712) */ async signMessage(): Promise { const page = await this.waitForNotificationPage() - const signButton = page - .getByTestId('page-container-footer-next') - .or(page.getByRole('button', { name: /sign/i })) + const signButton = this.confirmButton(page).or( + page.getByRole('button', { name: /sign/i }), + ) await signButton.click() } } diff --git a/e2e/src/types/env.d.ts b/e2e/src/types/env.d.ts index 9fb7f55c0..1ceee140d 100644 --- a/e2e/src/types/env.d.ts +++ b/e2e/src/types/env.d.ts @@ -5,8 +5,9 @@ interface E2EEnvConfig { WALLET_PASSWORD: string METAMASK_EXTENSION_PATH: string METAMASK_VERSION: string - STATUS_SEPOLIA_RPC_URL: string - STATUS_SEPOLIA_CHAIN_ID: string + ANVIL_MAINNET_RPC: string + ANVIL_LINEA_RPC: string + WALLET_ADDRESS: string } declare namespace NodeJS { diff --git a/e2e/tests/hub/pre-deposits/below-minimum-validation.spec.ts b/e2e/tests/hub/pre-deposits/below-minimum-validation.spec.ts new file mode 100644 index 000000000..9ddeca073 --- /dev/null +++ b/e2e/tests/hub/pre-deposits/below-minimum-validation.spec.ts @@ -0,0 +1,82 @@ +import { BELOW_MIN_AMOUNTS } from '@constants/hub/vaults.js' +import { test } from '@fixtures/anvil.fixture.js' +import { FUNDING_PRESETS } from '@helpers/anvil-rpc.js' + +import type { FundingPreset } from '@helpers/anvil-rpc.js' + +const BELOW_MIN_TESTS: Array<{ + id: string + vault: 'WETH' | 'SNT' | 'LINEA' + preset: FundingPreset + amount: string + errorPattern: RegExp + /** LINEA vault shows "Switch Network" instead of a disabled action button */ + expectSwitchNetwork?: boolean +}> = [ + { + id: 'W-4', + vault: 'WETH', + preset: FUNDING_PRESETS.WETH_BELOW_MIN, + amount: BELOW_MIN_AMOUNTS.WETH, + errorPattern: /below minimum deposit\. min: 0\.00/i, + }, + { + id: 'S-2', + vault: 'SNT', + preset: FUNDING_PRESETS.SNT_BELOW_MIN, + amount: BELOW_MIN_AMOUNTS.SNT, + errorPattern: /below minimum deposit\. min: 1/i, + }, + { + id: 'L-2', + vault: 'LINEA', + preset: FUNDING_PRESETS.LINEA_BELOW_MIN, + amount: BELOW_MIN_AMOUNTS.LINEA, + errorPattern: /below minimum deposit\. min: 1/i, + expectSwitchNetwork: true, + }, +] + +test.describe('Below minimum deposit validation', () => { + for (const tc of BELOW_MIN_TESTS) { + test( + `${tc.id}: ${tc.vault} — shows below minimum error (amount: ${tc.amount})`, + { tag: '@anvil' }, + async ({ anvilRpc, preDepositsPage, depositModal }) => { + await test.step('Fund wallet', async () => { + await anvilRpc.fund(tc.preset) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step(`Open deposit modal for ${tc.vault} Vault`, async () => { + await preDepositsPage.clickDepositForVault(tc.vault) + await depositModal.waitForOpen() + }) + + await test.step(`Enter amount below minimum (${tc.amount})`, async () => { + await depositModal.enterAmount(tc.amount) + }) + + await test.step('Verify below minimum error message', async () => { + await depositModal.expectErrorMessageMatching(tc.errorPattern) + }) + + await test.step('Verify action is blocked', async () => { + if (tc.expectSwitchNetwork) { + await depositModal.expectSwitchNetworkButtonVisible() + } else { + await depositModal.expectActionButtonDisabled() + } + }) + + await test.step('Close modal', async () => { + await depositModal.close() + }) + }, + ) + } +}) diff --git a/e2e/tests/hub/pre-deposits/gusd-deposit.spec.ts b/e2e/tests/hub/pre-deposits/gusd-deposit.spec.ts new file mode 100644 index 000000000..170198e34 --- /dev/null +++ b/e2e/tests/hub/pre-deposits/gusd-deposit.spec.ts @@ -0,0 +1,89 @@ +import { DEPOSIT_AMOUNTS, TEST_VAULTS } from '@constants/hub/vaults.js' +import { test } from '@fixtures/anvil.fixture.js' +import { CONTRACTS, FUNDING_PRESETS } from '@helpers/anvil-rpc.js' + +const GUSD_TOKENS = [ + { + id: 'G-1', + label: 'Tether USD, USDT', + symbol: 'USDT', + preset: 'GUSD_USDT_DEPOSIT' as const, + amount: DEPOSIT_AMOUNTS.GUSD_USDT, + contract: CONTRACTS.USDT, + }, + { + id: 'G-2', + label: 'USD Coin, USDC', + symbol: 'USDC', + preset: 'GUSD_USDC_DEPOSIT' as const, + amount: DEPOSIT_AMOUNTS.GUSD_USDC, + contract: CONTRACTS.USDC, + }, + { + id: 'G-3', + label: 'USDS Stablecoin, USDS', + symbol: 'USDS', + preset: 'GUSD_USDS_DEPOSIT' as const, + amount: DEPOSIT_AMOUNTS.GUSD_USDS, + contract: CONTRACTS.USDS, + }, +] + +test.describe('GUSD Vault - Happy path deposits', () => { + for (const token of GUSD_TOKENS) { + test( + `${token.id}: deposit via ${token.symbol}`, + { tag: '@anvil' }, + async ({ anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step(`Fund wallet with ${token.symbol}`, async () => { + await anvilRpc.fund(FUNDING_PRESETS[token.preset]) + }) + + await test.step('Reset token allowance for GUSD vault', async () => { + await anvilRpc.resetAllowance( + token.contract, + TEST_VAULTS.GUSD.address, + ) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for GUSD vault', async () => { + await preDepositsPage.clickDepositForVault('GUSD') + await depositModal.waitForOpen() + }) + + // Default selected stablecoin is USDT — only select if different + if (token.symbol !== 'USDT') { + await test.step(`Select ${token.symbol} from dropdown`, async () => { + await depositModal.selectToken(token.label) + }) + } + + await test.step('Enter deposit amount', async () => { + await depositModal.enterAmount(token.amount) + }) + + await test.step('Verify "Approve Deposit" button', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + await metamask.approveTransaction() + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) + } +}) diff --git a/e2e/tests/hub/pre-deposits/linea-deposit.spec.ts b/e2e/tests/hub/pre-deposits/linea-deposit.spec.ts new file mode 100644 index 000000000..7657b5b42 --- /dev/null +++ b/e2e/tests/hub/pre-deposits/linea-deposit.spec.ts @@ -0,0 +1,86 @@ +import { DEPOSIT_AMOUNTS } from '@constants/hub/vaults.js' +import { test } from '@fixtures/anvil.fixture.js' +import { FUNDING_PRESETS } from '@helpers/anvil-rpc.js' +import { expect } from '@playwright/test' + +const NETWORK_SWITCH_TIMEOUT = 15_000 +const NETWORK_SWITCH_POLL_INTERVAL = 500 + +test.describe('LINEA Vault - Happy path deposit', () => { + test( + 'L-1: deposit LINEA tokens with network switch', + { tag: '@anvil' }, + async ({ hubPage, anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step('Fund wallet with LINEA tokens', async () => { + await anvilRpc.fund(FUNDING_PRESETS.LINEA_DEPOSIT) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for LINEA vault', async () => { + await preDepositsPage.clickDepositForVault('LINEA') + await depositModal.waitForOpen() + }) + + await test.step('Switch to Linea network', async () => { + await depositModal.expectSwitchNetworkButtonVisible() + await depositModal.clickSwitchNetwork() + await depositModal.expectSwitchNetworkButtonGone() + }) + + await test.step('Verify Linea chain is active in browser provider', async () => { + await expect + .poll( + async () => { + return hubPage.evaluate(() => { + const eth = ( + window as { + ethereum?: { + request: (a: { method: string }) => Promise + } + } + ).ethereum + return ( + eth?.request({ method: 'eth_chainId' }).catch(() => null) ?? + null + ) + }) + }, + { + timeout: NETWORK_SWITCH_TIMEOUT, + intervals: [NETWORK_SWITCH_POLL_INTERVAL], + }, + ) + .toBe('0xe708') + }) + + await test.step('Enter deposit amount', async () => { + await depositModal.enterAmount(DEPOSIT_AMOUNTS.LINEA) + }) + + await test.step('Verify "Approve Deposit" button', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + await metamask.approveTransaction() + }) + + await test.step('Ensure deposit tx is mined on Linea fork', async () => { + await anvilRpc.mineBlock(anvilRpc.lineaRpc) + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) +}) diff --git a/e2e/tests/hub/pre-deposits/snt-deposit.spec.ts b/e2e/tests/hub/pre-deposits/snt-deposit.spec.ts new file mode 100644 index 000000000..b4c10ed1a --- /dev/null +++ b/e2e/tests/hub/pre-deposits/snt-deposit.spec.ts @@ -0,0 +1,48 @@ +import { DEPOSIT_AMOUNTS } from '@constants/hub/vaults.js' +import { test } from '@fixtures/anvil.fixture.js' +import { FUNDING_PRESETS } from '@helpers/anvil-rpc.js' + +test.describe('SNT Vault - Happy path deposit', () => { + test( + 'S-1: deposit SNT tokens', + { tag: '@anvil' }, + async ({ anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step('Fund wallet with SNT + gas ETH', async () => { + await anvilRpc.fund(FUNDING_PRESETS.SNT_DEPOSIT) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for SNT vault', async () => { + await preDepositsPage.clickDepositForVault('SNT') + await depositModal.waitForOpen() + }) + + await test.step('Enter deposit amount', async () => { + await depositModal.enterAmount(DEPOSIT_AMOUNTS.SNT) + }) + + await test.step('Verify "Approve Deposit" button', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + // After approval, Hub auto-fires the deposit tx via performDeposit(). + // This creates a new MetaMask confirmation that needs user approval. + await metamask.approveTransaction() + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) +}) diff --git a/e2e/tests/hub/pre-deposits/weth-deposit.spec.ts b/e2e/tests/hub/pre-deposits/weth-deposit.spec.ts new file mode 100644 index 000000000..6a58686f7 --- /dev/null +++ b/e2e/tests/hub/pre-deposits/weth-deposit.spec.ts @@ -0,0 +1,164 @@ +import { DEPOSIT_AMOUNTS } from '@constants/hub/vaults.js' +import { test } from '@fixtures/anvil.fixture.js' +import { FUNDING_PRESETS } from '@helpers/anvil-rpc.js' + +const FALLBACK_WRAP_WETH_AMOUNT = 1n * 10n ** 18n +const UI_SETTLE_DELAY = 1_500 + +test.describe('WETH Vault - Happy path deposits', () => { + test( + 'W-1: wrap ETH then deposit into WETH vault (no existing WETH)', + { tag: '@anvil' }, + async ({ hubPage, anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step('Fund wallet with ETH only (no WETH)', async () => { + await anvilRpc.fund(FUNDING_PRESETS.WETH_DEPOSIT_WRAP) + // Zero out any pre-existing WETH from the fork state so the UI + // shows "Wrap ETH to WETH" instead of "Approve Deposit". + await anvilRpc.fundWeth(0n) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for WETH vault', async () => { + await preDepositsPage.clickDepositForVault('WETH') + await depositModal.waitForOpen() + }) + + await test.step('Enter deposit amount', async () => { + await depositModal.enterAmount(DEPOSIT_AMOUNTS.WETH) + }) + + await test.step('Verify "Wrap ETH to WETH" button appears', async () => { + await depositModal.expectActionButtonReady(/wrap eth to weth/i) + }) + + await test.step('Simulate wrap completion on Anvil and refresh modal state', async () => { + // TODO: Restore real wrap tx confirmation once MetaMask STX routing is + // fully stable on local Anvil forks. + await anvilRpc.fundWeth(FALLBACK_WRAP_WETH_AMOUNT) + await hubPage.waitForTimeout(UI_SETTLE_DELAY) + await depositModal.close() + await preDepositsPage.clickDepositForVault('WETH') + await depositModal.waitForOpen() + await depositModal.enterAmount(DEPOSIT_AMOUNTS.WETH) + }) + + await test.step('Wait for button to change to "Approve Deposit"', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + await metamask.approveTransaction() + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) + + test( + 'W-2: deposit with sufficient WETH (skip wrap)', + { tag: '@anvil' }, + async ({ anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step('Fund wallet with WETH + gas ETH', async () => { + await anvilRpc.fund(FUNDING_PRESETS.WETH_DEPOSIT_DIRECT) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for WETH vault', async () => { + await preDepositsPage.clickDepositForVault('WETH') + await depositModal.waitForOpen() + }) + + await test.step('Enter deposit amount', async () => { + await depositModal.enterAmount(DEPOSIT_AMOUNTS.WETH) + }) + + await test.step('Verify "Approve Deposit" button (no wrap needed)', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + await metamask.approveTransaction() + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) + + test( + 'W-3: partial wrap then deposit (has some WETH, needs more)', + { tag: '@anvil' }, + async ({ hubPage, anvilRpc, metamask, preDepositsPage, depositModal }) => { + await test.step('Fund wallet with partial WETH + ETH', async () => { + await anvilRpc.fund(FUNDING_PRESETS.WETH_DEPOSIT_PARTIAL) + }) + + await test.step('Navigate to Pre-Deposits page', async () => { + await preDepositsPage.goto() + await preDepositsPage.waitForReady() + }) + + await test.step('Open deposit modal for WETH vault', async () => { + await preDepositsPage.clickDepositForVault('WETH') + await depositModal.waitForOpen() + }) + + await test.step('Enter amount exceeding current WETH balance', async () => { + await depositModal.enterAmount(DEPOSIT_AMOUNTS.WETH_PARTIAL) + }) + + await test.step('Verify "Wrap ETH to WETH" button (partial wrap needed)', async () => { + await depositModal.expectActionButtonReady(/wrap eth to weth/i) + }) + + await test.step('Simulate partial wrap completion on Anvil and refresh modal state', async () => { + // TODO: Restore real partial-wrap tx confirmation once MetaMask STX + // routing is fully stable on local Anvil forks. + await anvilRpc.fundWeth(FALLBACK_WRAP_WETH_AMOUNT) + await hubPage.waitForTimeout(UI_SETTLE_DELAY) + await depositModal.close() + await preDepositsPage.clickDepositForVault('WETH') + await depositModal.waitForOpen() + await depositModal.enterAmount(DEPOSIT_AMOUNTS.WETH_PARTIAL) + }) + + await test.step('Wait for button to change to "Approve Deposit"', async () => { + await depositModal.expectActionButtonReady(/approve deposit/i) + }) + + await test.step('Click "Approve Deposit" and approve token spend in MetaMask', async () => { + await depositModal.clickActionButton() + await metamask.approveTokenSpend() + }) + + await test.step('Approve deposit transaction in MetaMask', async () => { + await metamask.approveTransaction() + }) + + await test.step('Verify deposit success (modal closes)', async () => { + await depositModal.expectModalClosed() + }) + }, + ) +}) diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json index 72d03cd64..a8c649bc8 100644 --- a/e2e/tsconfig.json +++ b/e2e/tsconfig.json @@ -12,8 +12,6 @@ "noEmit": true, "skipLibCheck": true, "resolveJsonModule": true, - "allowUnusedLabels": false, - "allowUnreachableCode": false, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dc270ba02..7a9e2ab37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,13 +65,13 @@ importers: version: 5.90.7(react@19.1.2) connectkit: specifier: ^1.9.0 - version: 1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.7(react@19.1.2))(react-dom@19.2.0(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) + version: 1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.7(react@19.1.2))(react-dom@19.2.0(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) iron-session: specifier: ^8.0.4 version: 8.0.4 wagmi: specifier: ^2.12.8 - version: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + version: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) devDependencies: '@changesets/cli': specifier: ^2.26.2 @@ -2116,7 +2116,7 @@ importers: version: 0.23.1(rollup@4.53.2)(vite@6.3.5(@types/node@22.19.1)(jiti@2.6.1)(less@4.4.2)(lightningcss@1.30.2)(sass@1.94.0)(terser@5.44.1)(tsx@4.20.6)(yaml@2.8.1)) wagmi: specifier: ^3.3.2 - version: 3.3.2(wkpeo2jixccf754dzrbcslr4sa) + version: 3.3.2(hfxc5zc6ruiu6gsav63eqnjlsy) zod: specifier: 3.25.76 version: 3.25.76 @@ -2220,9 +2220,18 @@ importers: prettier: specifier: ^3.3.3 version: 3.6.2 + rimraf: + specifier: ^5.0.0 + version: 5.0.10 tsx: specifier: ^4.19.0 version: 4.20.6 + typescript: + specifier: ^5.7.0 + version: 5.9.3 + viem: + specifier: ^2.46.3 + version: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@4.3.6) packages/colors: devDependencies: @@ -2566,7 +2575,7 @@ importers: version: link:../icons connectkit: specifier: ^1.9.0 - version: 1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.12(react@19.1.2))(react-dom@19.1.2(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) + version: 1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.12(react@19.1.2))(react-dom@19.1.2(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) cva: specifier: ^1.0.0-beta.1 version: 1.0.0-beta.1(typescript@5.9.3) @@ -11867,6 +11876,7 @@ packages: '@walletconnect/ethereum-provider@2.21.1': resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/events@1.0.1': resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} @@ -11919,9 +11929,11 @@ packages: '@walletconnect/sign-client@2.21.0': resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/sign-client@2.21.1': resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/time@1.0.2': resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} @@ -11948,9 +11960,11 @@ packages: '@walletconnect/universal-provider@2.21.0': resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/universal-provider@2.21.1': resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' '@walletconnect/utils@2.19.2': resolution: {integrity: sha512-VU5CcUF4sZDg8a2/ov29OJzT3KfLuZqJUM0GemW30dlipI5fkpb0VPenZK7TcdLPXc1LN+Q+7eyTqHRoAu/BIA==} @@ -18933,6 +18947,14 @@ packages: typescript: optional: true + ox@0.14.7: + resolution: {integrity: sha512-zSQ/cfBdolj7U4++NAvH7sI+VG0T3pEohITCgcQj8KlawvTDY4vGVhDT64Atsm0d6adWfIYHDpu88iUBMMp+AQ==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + ox@0.6.7: resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} peerDependencies: @@ -21051,6 +21073,10 @@ packages: engines: {node: '>=14'} hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + ripemd160@2.0.3: resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} engines: {node: '>= 0.8'} @@ -22954,6 +22980,14 @@ packages: typescript: optional: true + viem@2.47.10: + resolution: {integrity: sha512-D+l6SDDZWB5bh8u9hgICzMX2/egMrgEQ+Pef/QkZgmOl6bOTyCQMSgWAH8jZTWJ/218J9QNv7s/9BH6Wu5oPDg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite-node@3.1.4: resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -25163,7 +25197,7 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) preact: 10.24.2 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zustand: 5.0.3(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.4.0(react@19.1.2)) transitivePeerDependencies: - '@types/react' @@ -25184,7 +25218,7 @@ snapshots: idb-keyval: 6.2.1 ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) preact: 10.24.2 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) zustand: 5.0.3(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.6.0(react@19.1.2)) transitivePeerDependencies: - '@types/react' @@ -26478,11 +26512,11 @@ snapshots: - supports-color optional: true - '@gemini-wallet/core@0.3.2(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': + '@gemini-wallet/core@0.3.2(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': dependencies: '@metamask/rpc-errors': 7.0.2 eventemitter3: 5.0.1 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - supports-color optional: true @@ -27992,7 +28026,7 @@ snapshots: - utf-8-validate - zod - '@lifi/sdk@3.15.1(@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@lifi/sdk@3.15.1(@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@bigmi/core': 0.6.5(@types/react@19.1.2)(bs58@6.0.0)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2)) '@bitcoinerlab/secp256k1': 1.2.0 @@ -28005,7 +28039,7 @@ snapshots: bech32: 2.0.0 bitcoinjs-lib: 7.0.1(typescript@5.9.3) bs58: 6.0.0 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@gql.tada/svelte-support' - '@gql.tada/vue-support' @@ -28020,7 +28054,7 @@ snapshots: '@lifi/types@17.55.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -28034,7 +28068,7 @@ snapshots: '@bigmi/react': 0.6.3(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bs58@6.0.0)(react-dom@19.1.2(react@19.1.2))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2)) '@emotion/react': 11.14.0(@types/react@19.1.2)(react@19.1.2) '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react@19.1.2) - '@lifi/sdk': 3.15.1(@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@lifi/sdk': 3.15.1(@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) '@mui/icons-material': 7.3.7(@mui/material@7.3.7(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.2(react@19.1.2))(react@19.1.2))(@types/react@19.1.2)(react@19.1.2) '@mui/material': 7.3.7(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.2(react@19.1.2))(react@19.1.2) '@mui/system': 7.3.7(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react@19.1.2))(@types/react@19.1.2)(react@19.1.2) @@ -28050,8 +28084,8 @@ snapshots: react-dom: 19.1.2(react@19.1.2) react-i18next: 16.5.2(i18next@25.7.4(typescript@5.9.3))(react-dom@19.1.2(react@19.1.2))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))(react@19.1.2)(typescript@5.9.3) use-sync-external-store: 1.6.0(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 3.3.2(wkpeo2jixccf754dzrbcslr4sa) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 3.3.2(hfxc5zc6ruiu6gsav63eqnjlsy) zustand: 5.0.10(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.6.0(react@19.1.2)) transitivePeerDependencies: - '@gql.tada/svelte-support' @@ -28099,7 +28133,7 @@ snapshots: react-router-dom: 6.30.3(react-dom@19.1.2(react@19.1.2))(react@19.1.2) react-transition-group: 4.4.5(react-dom@19.1.2(react@19.1.2))(react@19.1.2) viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - wagmi: 3.3.2(wkpeo2jixccf754dzrbcslr4sa) + wagmi: 3.3.2(hfxc5zc6ruiu6gsav63eqnjlsy) zustand: 5.0.10(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.4.0(react@19.1.2)) transitivePeerDependencies: - '@gql.tada/svelte-support' @@ -28365,21 +28399,6 @@ snapshots: openapi-fetch: 0.13.8 optional: true - '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.8)(utf-8-validate@6.0.3))': - dependencies: - bufferutil: 4.0.9 - cross-fetch: 4.1.0 - date-fns: 2.30.0 - debug: 4.4.3(supports-color@8.1.1) - eciesjs: 0.4.16 - eventemitter2: 6.4.9 - readable-stream: 3.6.2 - socket.io-client: 4.8.1(bufferutil@4.0.8)(utf-8-validate@6.0.3) - utf-8-validate: 5.0.10 - uuid: 8.3.2 - transitivePeerDependencies: - - supports-color - '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: bufferutil: 4.0.9 @@ -28412,23 +28431,6 @@ snapshots: - supports-color optional: true - '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@6.0.3))': - dependencies: - '@metamask/sdk-analytics': 0.0.5 - bufferutil: 4.0.9 - cross-fetch: 4.1.0 - date-fns: 2.30.0 - debug: 4.3.4 - eciesjs: 0.4.16 - eventemitter2: 6.4.9 - readable-stream: 3.6.2 - socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) - utf-8-validate: 5.0.10 - uuid: 8.3.2 - transitivePeerDependencies: - - supports-color - optional: true - '@metamask/sdk-install-modal-web@0.32.0': dependencies: '@paulmillr/qr': 0.2.1 @@ -28443,7 +28445,7 @@ snapshots: '@babel/runtime': 7.28.4 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 - '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metamask/sdk-install-modal-web': 0.32.0 '@paulmillr/qr': 0.2.1 bowser: 2.12.1 @@ -28527,7 +28529,7 @@ snapshots: '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 '@metamask/sdk-analytics': 0.0.5 - '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@6.0.3)) + '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@metamask/sdk-install-modal-web': 0.32.1 '@paulmillr/qr': 0.2.1 bowser: 2.12.1 @@ -32939,7 +32941,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -32950,7 +32952,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -32961,7 +32963,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -32972,18 +32974,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@reown/appkit-common@1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -32994,7 +32985,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -33006,7 +32997,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -33018,7 +33009,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4) transitivePeerDependencies: - bufferutil - typescript @@ -33030,7 +33021,7 @@ snapshots: dependencies: big.js: 6.2.2 dayjs: 1.11.13 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -33044,7 +33035,7 @@ snapshots: '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3) '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33079,42 +33070,7 @@ snapshots: '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - - '@reown/appkit-controllers@1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33149,7 +33105,7 @@ snapshots: '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33185,7 +33141,7 @@ snapshots: '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3) '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33372,43 +33328,6 @@ snapshots: - valtio - zod - '@reown/appkit-scaffold-ui@1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@4.3.6)': - dependencies: - '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-controllers': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-ui': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-utils': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@4.3.6) - '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - lit: 3.1.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - valtio - - zod - '@reown/appkit-scaffold-ui@1.7.8(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -33555,41 +33474,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-ui@1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-controllers': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - lit: 3.1.0 - qrcode: 1.5.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-ui@1.7.8(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -33671,7 +33555,7 @@ snapshots: '@walletconnect/logger': 2.1.2 '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33709,45 +33593,7 @@ snapshots: '@walletconnect/logger': 2.1.2 '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - - '@reown/appkit-utils@1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@4.3.6)': - dependencies: - '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-controllers': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-polyfills': 1.7.3 - '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/logger': 2.1.2 - '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33785,7 +33631,7 @@ snapshots: '@walletconnect/logger': 2.1.2 '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33824,7 +33670,7 @@ snapshots: '@walletconnect/logger': 2.1.2 '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33913,7 +33759,7 @@ snapshots: '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -33955,49 +33801,7 @@ snapshots: '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - - '@reown/appkit@1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-controllers': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-polyfills': 1.7.3 - '@reown/appkit-scaffold-ui': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@4.3.6) - '@reown/appkit-ui': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@reown/appkit-utils': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.1.2)(react@19.1.2))(zod@4.3.6) - '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - bs58: 6.0.0 - valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -34040,7 +33844,7 @@ snapshots: '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -34084,7 +33888,7 @@ snapshots: '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) bs58: 6.0.0 valtio: 1.13.2(@types/react@19.1.2)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -34224,16 +34028,6 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - events: 3.3.0 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) @@ -34248,7 +34042,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -34258,17 +34052,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -34278,7 +34062,7 @@ snapshots: '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.23.1 - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -37192,13 +36976,13 @@ snapshots: '@vue/shared@3.3.4': {} - '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.29.0)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(zod@3.25.76)': dependencies: '@coinbase/wallet-sdk': 4.3.0 '@metamask/sdk': 0.32.0(bufferutil@4.0.8)(utf-8-validate@6.0.3) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - '@wagmi/core': 2.17.1(@tanstack/query-core@5.29.0)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) + '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/ethereum-provider': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' viem: 2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) @@ -37232,13 +37016,13 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': + '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@coinbase/wallet-sdk': 4.3.0 '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) '@walletconnect/ethereum-provider': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' viem: 2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -37272,16 +37056,16 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)': + '@wagmi/connectors@5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@coinbase/wallet-sdk': 4.3.0 '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) - '@walletconnect/ethereum-provider': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -37312,9 +37096,23 @@ snapshots: - utf-8-validate - zod - '@wagmi/connectors@7.1.2(4a6hu6ddekh6hyalu2flybvp7q)': + '@wagmi/connectors@7.1.2(5jf2hsscarcgmoaufwd4cidao4)': dependencies: - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + optionalDependencies: + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@6.0.3)(zod@3.25.76) + '@gemini-wallet/core': 0.3.2(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + '@walletconnect/ethereum-provider': 2.21.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + porto: 0.2.35(@tanstack/react-query@5.90.12(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) + typescript: 5.9.3 + + '@wagmi/connectors@7.1.2(cx5afk5uelg3pjr7s3wuz6prei)': + dependencies: + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(utf-8-validate@5.0.10)(zod@3.25.76) @@ -37323,21 +37121,7 @@ snapshots: '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/ethereum-provider': 2.21.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) - porto: 0.2.35(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@3.3.2) - typescript: 5.9.3 - - '@wagmi/connectors@7.1.2(qh3tgp5jcthygi4ijosqnsyosy)': - dependencies: - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - optionalDependencies: - '@coinbase/wallet-sdk': 4.3.6(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(utf-8-validate@6.0.3)(zod@3.25.76) - '@gemini-wallet/core': 0.3.2(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) - '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - '@walletconnect/ethereum-provider': 2.21.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - porto: 0.2.35(@tanstack/react-query@5.90.12(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) + porto: 0.2.35(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@3.3.2) typescript: 5.9.3 '@wagmi/core@2.17.1(@tanstack/query-core@5.29.0)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': @@ -37370,11 +37154,11 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))': + '@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zustand: 5.0.0(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.4.0(react@19.1.2)) optionalDependencies: '@tanstack/query-core': 5.90.12 @@ -37385,7 +37169,7 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) @@ -37393,7 +37177,7 @@ snapshots: zustand: 5.0.0(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.4.0(react@19.1.2)) optionalDependencies: '@tanstack/query-core': 5.90.12 - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) typescript: 5.9.3 transitivePeerDependencies: - '@types/react' @@ -37401,15 +37185,15 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': + '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) zustand: 5.0.0(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.4.0(react@19.1.2)) optionalDependencies: '@tanstack/query-core': 5.90.12 - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) typescript: 5.9.3 transitivePeerDependencies: - '@types/react' @@ -37417,15 +37201,15 @@ snapshots: - react - use-sync-external-store - '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': + '@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) zustand: 5.0.0(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.6.0(react@19.1.2)) optionalDependencies: '@tanstack/query-core': 5.90.12 - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) typescript: 5.9.3 transitivePeerDependencies: - '@types/react' @@ -37693,50 +37477,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/logger': 2.1.2 - '@walletconnect/relay-api': 1.0.11 - '@walletconnect/relay-auth': 1.1.0 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/core@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@walletconnect/heartbeat': 1.2.2 @@ -37825,50 +37565,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/logger': 2.1.2 - '@walletconnect/relay-api': 1.0.11 - '@walletconnect/relay-auth': 1.1.0 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/window-getters': 1.0.1 - es-toolkit: 1.33.0 - events: 3.3.0 - uint8arrays: 3.1.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/core@2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/heartbeat': 1.2.2 @@ -38135,47 +37831,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/ethereum-provider@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@reown/appkit': 1.7.3(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/jsonrpc-http-connection': 1.0.8 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/sign-client': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/types': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/universal-provider': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/utils': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/ethereum-provider@2.21.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@reown/appkit': 1.7.8(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -38503,42 +38158,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/events': 1.0.1 - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/logger': 2.1.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/sign-client@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@walletconnect/core': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) @@ -38611,42 +38230,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/core': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/events': 1.0.1 - '@walletconnect/heartbeat': 1.2.2 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/logger': 2.1.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/sign-client@2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/core': 2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) @@ -39115,46 +38698,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/jsonrpc-http-connection': 1.0.8 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - es-toolkit: 1.33.0 - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/universal-provider@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 @@ -39235,46 +38778,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/universal-provider@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@walletconnect/events': 1.0.1 - '@walletconnect/jsonrpc-http-connection': 1.0.8 - '@walletconnect/jsonrpc-provider': 1.0.14 - '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - '@walletconnect/types': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/utils': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - es-toolkit: 1.33.0 - events: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/universal-provider@2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 @@ -39527,50 +39030,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@noble/ciphers': 1.2.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/relay-api': 1.0.11 - '@walletconnect/relay-auth': 1.1.0 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - bs58: 6.0.0 - detect-browser: 5.3.0 - query-string: 7.1.3 - uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/utils@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 @@ -39659,50 +39118,6 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)': - dependencies: - '@noble/ciphers': 1.2.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/relay-api': 1.0.11 - '@walletconnect/relay-auth': 1.1.0 - '@walletconnect/safe-json': 1.0.2 - '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.20.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))) - '@walletconnect/window-getters': 1.0.1 - '@walletconnect/window-metadata': 1.0.1 - bs58: 6.0.0 - detect-browser: 5.3.0 - query-string: 7.1.3 - uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - ioredis - - typescript - - uploadthing - - utf-8-validate - - zod - '@walletconnect/utils@2.21.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 @@ -40086,11 +39501,6 @@ snapshots: typescript: 5.9.3 zod: 3.25.76 - abitype@1.0.8(typescript@5.9.3)(zod@4.3.6): - optionalDependencies: - typescript: 5.9.3 - zod: 4.3.6 - abitype@1.1.0(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 @@ -41763,12 +41173,12 @@ snapshots: - '@babel/core' - react-is - connectkit@1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.12(react@19.1.2))(react-dom@19.1.2(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): + connectkit@1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.12(react@19.1.2))(react-dom@19.1.2(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): dependencies: '@tanstack/react-query': 5.90.12(react@19.1.2) buffer: 6.0.3 detect-browser: 5.3.0 - family: 0.1.4(react-dom@19.1.2(react@19.1.2))(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) + family: 0.1.4(react-dom@19.1.2(react@19.1.2))(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2) framer-motion: 6.5.1(react-dom@19.1.2(react@19.1.2))(react@19.1.2) qrcode: 1.5.4 react: 19.1.2 @@ -41777,8 +41187,8 @@ snapshots: react-use-measure: 2.1.7(react-dom@19.1.2(react@19.1.2))(react@19.1.2) resize-observer-polyfill: 1.5.1 styled-components: 5.3.11(@babel/core@7.28.5)(react-dom@19.1.2(react@19.1.2))(react-is@19.2.3)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - wagmi: 3.3.2(4ftyfq6w4talv4ejlelatozdga) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + wagmi: 3.3.2(fslbcedg2ixfu7ipp32bd6mwp4) transitivePeerDependencies: - '@babel/core' - react-is @@ -41803,12 +41213,12 @@ snapshots: - '@babel/core' - react-is - connectkit@1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.7(react@19.1.2))(react-dom@19.2.0(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)): + connectkit@1.9.1(@babel/core@7.28.5)(@tanstack/react-query@5.90.7(react@19.1.2))(react-dom@19.2.0(react@19.1.2))(react-is@19.2.3)(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): dependencies: '@tanstack/react-query': 5.90.7(react@19.1.2) buffer: 6.0.3 detect-browser: 5.3.0 - family: 0.1.4(react-dom@19.2.0(react@19.1.2))(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)) + family: 0.1.4(react-dom@19.2.0(react@19.1.2))(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) framer-motion: 6.5.1(react-dom@19.2.0(react@19.1.2))(react@19.1.2) qrcode: 1.5.4 react: 19.1.2 @@ -41817,8 +41227,8 @@ snapshots: react-use-measure: 2.1.7(react-dom@19.2.0(react@19.1.2))(react@19.1.2) resize-observer-polyfill: 1.5.1 styled-components: 5.3.11(@babel/core@7.28.5)(react-dom@19.2.0(react@19.1.2))(react-is@19.2.3)(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - wagmi: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - '@babel/core' - react-is @@ -43970,19 +43380,19 @@ snapshots: viem: 2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) - family@0.1.4(react-dom@19.1.2(react@19.1.2))(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): + family@0.1.4(react-dom@19.1.2(react@19.1.2))(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): optionalDependencies: react: 19.1.2 react-dom: 19.1.2(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) - wagmi: 3.3.2(4ftyfq6w4talv4ejlelatozdga) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + wagmi: 3.3.2(fslbcedg2ixfu7ipp32bd6mwp4) - family@0.1.4(react-dom@19.2.0(react@19.1.2))(react@19.1.2)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6)): + family@0.1.4(react-dom@19.2.0(react@19.1.2))(react@19.1.2)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): optionalDependencies: react: 19.1.2 react-dom: 19.2.0(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) - wagmi: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) fast-copy@3.0.2: {} @@ -45893,11 +45303,6 @@ snapshots: dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.3)): - dependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.3) - optional: true - isows@1.0.7(ws@8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)): dependencies: ws: 8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) @@ -49311,7 +48716,7 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - ox@0.11.3(typescript@5.9.3)(zod@3.22.4): + ox@0.11.3(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -49319,14 +48724,14 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.11.3(typescript@5.9.3)(zod@3.25.76): + ox@0.11.3(typescript@5.9.3)(zod@4.3.6): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -49334,14 +48739,14 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.11.3(typescript@5.9.3)(zod@4.3.6): + ox@0.14.7(typescript@5.9.3)(zod@3.22.4): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -49349,17 +48754,18 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) + abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.6.7(typescript@5.9.3)(zod@3.25.76): + ox@0.14.7(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.9.7 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 @@ -49370,10 +48776,11 @@ snapshots: transitivePeerDependencies: - zod - ox@0.6.7(typescript@5.9.3)(zod@4.3.6): + ox@0.14.7(typescript@5.9.3)(zod@4.3.6): dependencies: '@adraffy/ens-normalize': 1.11.1 - '@noble/curves': 1.9.7 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 @@ -49384,6 +48791,20 @@ snapshots: transitivePeerDependencies: - zod + ox@0.6.7(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + ox@0.6.9(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -49995,14 +49416,14 @@ snapshots: style-value-types: 5.0.0 tslib: 2.8.1 - porto@0.2.35(@tanstack/react-query@5.90.12(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): + porto@0.2.35(@tanstack/react-query@5.90.12(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(wagmi@3.3.2): dependencies: - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.6.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) hono: 4.10.8 idb-keyval: 6.2.2 mipd: 0.0.7(typescript@5.9.3) ox: 0.9.6(typescript@5.9.3)(zod@4.3.6) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) zod: 4.3.6 zustand: 5.0.10(@types/react@19.1.2)(react@19.1.2)(use-sync-external-store@1.6.0(react@19.1.2)) optionalDependencies: @@ -50010,16 +49431,16 @@ snapshots: react: 19.1.2 react-native: 0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@6.0.3) typescript: 5.9.3 - wagmi: 3.3.2(4ftyfq6w4talv4ejlelatozdga) + wagmi: 3.3.2(fslbcedg2ixfu7ipp32bd6mwp4) transitivePeerDependencies: - '@types/react' - immer - use-sync-external-store optional: true - porto@0.2.35(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@3.3.2): + porto@0.2.35(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(@wagmi/core@3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@3.3.2): dependencies: - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) hono: 4.10.8 idb-keyval: 6.2.2 mipd: 0.0.7(typescript@5.9.3) @@ -50032,7 +49453,7 @@ snapshots: react: 19.1.2 react-native: 0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10) typescript: 5.9.3 - wagmi: 3.3.2(wkpeo2jixccf754dzrbcslr4sa) + wagmi: 3.3.2(hfxc5zc6ruiu6gsav63eqnjlsy) transitivePeerDependencies: - '@types/react' - immer @@ -53420,6 +52841,10 @@ snapshots: dependencies: glob: 9.3.5 + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + ripemd160@2.0.3: dependencies: hash-base: 3.1.2 @@ -55860,23 +55285,6 @@ snapshots: - utf-8-validate - zod - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6): - dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.3)(zod@4.3.6) - isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.9.3)(zod@4.3.6) - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): dependencies: '@noble/curves': 1.8.1 @@ -55884,7 +55292,7 @@ snapshots: '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76) - isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.3)) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) ox: 0.6.7(typescript@5.9.3)(zod@3.25.76) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: @@ -55929,16 +55337,16 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4): + viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)) - ox: 0.11.3(typescript@5.9.3)(zod@3.22.4) - ws: 8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -55946,16 +55354,16 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): + viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@4.3.6): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)) - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) - ws: 8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3)) + ox: 0.11.3(typescript@5.9.3)(zod@4.3.6) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -55963,16 +55371,16 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + viem@2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) - isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.11.3(typescript@5.9.3)(zod@3.22.4) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + ox: 0.14.7(typescript@5.9.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -55980,15 +55388,32 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + viem@2.47.10(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3)) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.8)(utf-8-validate@6.0.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ox: 0.14.7(typescript@5.9.3)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -55997,15 +55422,15 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6): + viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.11.3(typescript@5.9.3)(zod@4.3.6) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -56014,7 +55439,7 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4): + viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.22.4): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 @@ -56022,7 +55447,7 @@ snapshots: '@scure/bip39': 1.6.0 abitype: 1.2.3(typescript@5.9.3)(zod@3.22.4) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3)) - ox: 0.11.3(typescript@5.9.3)(zod@3.22.4) + ox: 0.14.7(typescript@5.9.3)(zod@3.22.4) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 @@ -56032,7 +55457,7 @@ snapshots: - zod optional: true - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): + viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 @@ -56040,7 +55465,7 @@ snapshots: '@scure/bip39': 1.6.0 abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3)) - ox: 0.11.3(typescript@5.9.3)(zod@3.25.76) + ox: 0.14.7(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 @@ -56049,7 +55474,7 @@ snapshots: - utf-8-validate - zod - viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@4.3.6): + viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@4.3.6): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 @@ -56057,7 +55482,7 @@ snapshots: '@scure/bip39': 1.6.0 abitype: 1.2.3(typescript@5.9.3)(zod@4.3.6) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3)) - ox: 0.11.3(typescript@5.9.3)(zod@4.3.6) + ox: 0.14.7(typescript@5.9.3)(zod@4.3.6) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 @@ -56211,7 +55636,7 @@ snapshots: wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@tanstack/query-core@5.29.0)(@tanstack/react-query@5.29.0(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.29.0(react@19.1.2) - '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.29.0)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)))(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(zod@3.25.76) + '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.8)(react@19.1.2)(utf-8-validate@6.0.3)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.8)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@6.0.3)(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76))(zod@3.25.76) '@wagmi/core': 2.17.1(@tanstack/query-core@5.29.0)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.8)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) react: 19.1.2 use-sync-external-store: 1.4.0(react@19.1.2) @@ -56250,7 +55675,7 @@ snapshots: wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.90.7(react@19.1.2) - '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.39.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.2 use-sync-external-store: 1.4.0(react@19.1.2) @@ -56286,14 +55711,14 @@ snapshots: - utf-8-validate - zod - wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6): + wagmi@2.15.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.7(react@19.1.2))(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.90.7(react@19.1.2) - '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6))(zod@4.3.6) - '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6)) + '@wagmi/connectors': 5.8.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.83.0(@babel/core@7.28.5)(@types/react@19.1.2)(bufferutil@4.0.9)(react@19.1.2)(utf-8-validate@5.0.10)))(@types/react@19.1.2)(@wagmi/core@2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.1.2)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.17.1(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.2 use-sync-external-store: 1.4.0(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -56325,14 +55750,14 @@ snapshots: - utf-8-validate - zod - wagmi@3.3.2(4ftyfq6w4talv4ejlelatozdga): + wagmi@3.3.2(fslbcedg2ixfu7ipp32bd6mwp4): dependencies: '@tanstack/react-query': 5.90.12(react@19.1.2) - '@wagmi/connectors': 7.1.2(qh3tgp5jcthygi4ijosqnsyosy) - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) + '@wagmi/connectors': 7.1.2(5jf2hsscarcgmoaufwd4cidao4) + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76)) react: 19.1.2 use-sync-external-store: 1.4.0(react@19.1.2) - viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) + viem: 2.47.10(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -56349,11 +55774,11 @@ snapshots: - ox - porto - wagmi@3.3.2(wkpeo2jixccf754dzrbcslr4sa): + wagmi@3.3.2(hfxc5zc6ruiu6gsav63eqnjlsy): dependencies: '@tanstack/react-query': 5.90.7(react@19.1.2) - '@wagmi/connectors': 7.1.2(4a6hu6ddekh6hyalu2flybvp7q) - '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.11.3(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@wagmi/connectors': 7.1.2(cx5afk5uelg3pjr7s3wuz6prei) + '@wagmi/core': 3.2.2(@tanstack/query-core@5.90.12)(@types/react@19.1.2)(ox@0.14.7(typescript@5.9.3)(zod@3.25.76))(react@19.1.2)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.1.2))(viem@2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.1.2 use-sync-external-store: 1.4.0(react@19.1.2) viem: 2.44.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)