diff --git a/.changeset/multi-provider-routes.md b/.changeset/multi-provider-routes.md new file mode 100644 index 0000000..d1a7f02 --- /dev/null +++ b/.changeset/multi-provider-routes.md @@ -0,0 +1,10 @@ +--- +"@swapkit/ui": minor +--- + +Surface every provider in a multi-hop quote rather than just the first. + +- The collapsed quote card now face-piles the provider logos and renders the full path label (`1inch → Chainflip`, truncated to `A → … → Z` for 4+ providers) instead of only `providers[0]`. +- The priority badge (Recommended / Cheapest / Fastest) moves to a corner ribbon on the top-right of the card and dialog rows, freeing the inline row for the path label and amount on mobile too. +- The fee details accordion now leads with a vertical per-leg timeline (sell asset → provider → … → buy asset) for multi-hop routes; single-hop routes show the fees breakdown only, unchanged. +- The route-select dialog mirrors the collapsed card: stacked logos, path label, corner ribbon, and the title becomes "Select route". diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2be7a0e --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +SWAPKIT_DEV_AUTH_TOKEN="" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..517006d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# GitHub will automatically add review requests from these usernames for PRs + +- @towanTG @Drakeoon @ice-chillios diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml new file mode 100644 index 0000000..d2ea23f --- /dev/null +++ b/.github/workflows/pr-test.yml @@ -0,0 +1,30 @@ +name: PR Test + +on: + workflow_dispatch: + push: + branches: + - develop + pull_request: + branches: + - develop + +jobs: + build-lint-test: + if: github.event_name != 'pull_request' || contains(github.event.pull_request.title, ':tada:') == false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.head_ref }} + + - name: Setup Repo + uses: ./tools/github/setup-repo + + - run: bun build:ci + - run: bun lint + - run: bun type-check:ci + + # - name: Test + # run: bun test:ci diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7708920..9364e94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,11 +5,14 @@ on: push: branches: - develop + - beta - nightly jobs: build-lint-test: runs-on: ubuntu-latest + env: + TEST_API_KEY: ${{ secrets.TEST_API_KEY }} steps: - uses: actions/checkout@v4 @@ -58,14 +61,18 @@ jobs: - name: Upgrade npm for OIDC trusted publishing run: npm install -g npm@11 - - name: Copy npmrc config - run: cp .npmrc.prod .npmrc + - name: Configure npm registry + run: | + cp .npmrc.prod .npmrc + echo "registry=https://registry.npmjs.org/" > ~/.npmrc - name: Set job params shell: bash + id: deployment-params run: | git config --global user.email "swapkit@users.noreply.github.com" git config --global user.name "swapkit" + echo "publishName=${{ github.ref_name == 'develop' && 'Release' || github.ref_name }}" >> $GITHUB_OUTPUT - name: Exit pre changeset if: github.ref_name == 'nightly' @@ -76,17 +83,32 @@ jobs: if: github.ref_name == 'nightly' run: bun changeset version --snapshot nightly + - name: Change beta changeset + if: github.ref_name == 'beta' + continue-on-error: true + run: bun changeset pre enter beta + - name: Create Pull Request or Publish to npm id: changesets if: github.ref_name == 'develop' uses: changesets/action@v1.4.10 with: - title: ":tada: Publish Wallets Release" + title: ":tada: Publish ${{ steps.deployment-params.outputs.publishName }}" version: bun version-bump publish: bun publish-packages setupGitUser: false createGithubReleases: false + - name: Publish Beta to npm + if: github.ref_name == 'beta' + uses: changesets/action@v1.4.10 + with: + title: ":tada: Publish Beta" + version: bun version-bump + publish: bun publish-packages --no-git-tag + setupGitUser: false + createGithubReleases: false + - name: Publish Nightly to npm if: github.ref_name == 'nightly' uses: changesets/action@v1.4.10 diff --git a/.github/workflows/update-swapkit-deps.yml b/.github/workflows/update-swapkit-deps.yml new file mode 100644 index 0000000..d3e8a83 --- /dev/null +++ b/.github/workflows/update-swapkit-deps.yml @@ -0,0 +1,116 @@ +name: Update SwapKit Dependencies +env: + SWAPKIT_DEV_AUTH_TOKEN: ${{ secrets.SWAPKIT_DEV_AUTH_TOKEN }} + +on: + workflow_dispatch: + schedule: + # Every weekday at 10:00 UTC + - cron: "0 10 * * 1-5" + +permissions: + contents: write + pull-requests: write + +jobs: + update-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: develop + fetch-depth: 0 + + - name: Setup Repo + uses: ./tools/github/setup-repo + + - name: Update @swapkit/* packages + id: update + run: | + # Collect workspace package names so we can exclude them from the update + workspace_names=$(jq -r '.name // empty' packages/*/package.json | grep '^@swapkit/' || true) + + # Collect all @swapkit/* dependency names, excluding workspace packages themselves + all_deps=$(grep -roh '"@swapkit/[^"]*"' packages/*/package.json | tr -d '"' | sort -u) + if [ -n "$workspace_names" ]; then + packages=$(echo "$all_deps" | grep -vxFf <(echo "$workspace_names") | tr '\n' ' ') + else + packages=$(echo "$all_deps" | tr '\n' ' ') + fi + + if [ -z "$packages" ]; then + echo "No @swapkit/* packages found" + echo "changed=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "Updating: $packages" + + # bun update doesn't support globs, pass explicit package names + # shellcheck disable=SC2086 + bun update --latest $packages + + # Check if anything changed + if git diff --quiet -- packages/*/package.json bun.lock; then + echo "changed=false" >> "$GITHUB_OUTPUT" + echo "No @swapkit/* updates available" + exit 0 + fi + + echo "changed=true" >> "$GITHUB_OUTPUT" + + # Build a summary of what changed + { + echo "summary<> "$GITHUB_OUTPUT" + + - name: Create PR + if: steps.update.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + branch="chore/update-swapkit-deps-$(date +%Y%m%d)" + + git config user.email "swapkit@users.noreply.github.com" + git config user.name "swapkit" + + git checkout -b "$branch" + git add packages/*/package.json bun.lock + git commit -m "chore(deps): update @swapkit/* packages" + git push -u origin "$branch" + + # Close any stale update PRs + existing_prs=$(gh pr list --search "chore/update-swapkit-deps- in:title" --state open --json number --jq '.[].number' || true) + for pr in $existing_prs; do + gh pr close "$pr" --comment "Superseded by newer dependency update" + done + + gh pr create \ + --base develop \ + --head "$branch" \ + --title "chore(deps): update @swapkit/* packages" \ + --body "$(cat <<'PREOF' + ## SwapKit Dependency Update + + Automated bump of `@swapkit/*` packages to latest versions. + + ### Changes + + ${{ steps.update.outputs.summary }} + + --- + > CI will validate build, lint, and types on this PR. + PREOF + )" diff --git a/.gitignore b/.gitignore index f7b06c0..4e27708 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,20 @@ build/data.json .DS_Store .env .env.local +*.log +*.tmp.json +.aider* +.cursor/mcp.json +.mcp* +.claude +.claude-teams +AGENTS* +claude + +.idea/ +build/ +cache/ +coverage/ + +**/.terraform/* +*.tfstate diff --git a/.npmrc b/.npmrc index 927e64b..5f0fc3f 100644 --- a/.npmrc +++ b/.npmrc @@ -1,9 +1,3 @@ //registry.npmjs.org/:_authToken=${NPM_TOKEN} registry=https://registry.npmjs.org/ always-auth=true -//registry.npmjs.org/:_authToken=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 -//registry.npmjs.org/:_authToken=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 -//registry.npmjs.org/:_authToken=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 -//registry.npmjs.org/:_authToken=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 -//registry.npmjs.org/:_authToken=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 -//registry.npmjs.org/:_authToken=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 diff --git a/bun.lock b/bun.lock index a11169d..386163a 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "swapkit-wallets", @@ -21,14 +20,19 @@ "@swapkit/wallet-keystore": "^4.4.1", "@types/bun": "1.3.13", "@types/node": "25.6.0", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "caniuse-lite": "1.0.30001776", + "happy-dom": "^20.8.9", "ledger-bitcoin": "0.3.0", + "lefthook": "2.1.2", "typescript": "6.0.3", "zod": "4.4.3", }, }, "packages/sdk": { "name": "@swapkit/sdk", - "version": "4.6.30", + "version": "4.6.31", "dependencies": { "@stricahq/typhonjs": "~3.0.1", "@swapkit/core": "^4.4.33", @@ -42,6 +46,104 @@ "cosmjs-types": "0.10.1", }, }, + "packages/ui": { + "name": "@swapkit/ui", + "version": "0.19.1", + "dependencies": { + "@aptos-labs/ts-sdk": "1.34.0", + "@cosmjs/amino": "0.37.0", + "@cosmjs/crypto": "0.37.0", + "@cosmjs/proto-signing": "0.37.0", + "@cosmjs/stargate": "0.37.0", + "@hookform/resolvers": "5.2.2", + "@mysten/sui": "1.44.0", + "@near-js/accounts": "2.5.1", + "@near-js/crypto": "2.5.0", + "@near-js/providers": "2.5.1", + "@near-js/signers": "2.5.1", + "@near-js/transactions": "2.5.0", + "@near-js/utils": "2.5.1", + "@noble/curves": "2.2.0", + "@noble/hashes": "~2.2.0", + "@orbs-network/ton-access": "2.3.3", + "@polkadot/api": "15.10.2", + "@polkadot/keyring": "13.5.7", + "@polkadot/rpc-provider": "15.10.2", + "@polkadot/util": "13.5.7", + "@polkadot/util-crypto": "13.5.7", + "@radix-ui/react-accordion": "1.2.12", + "@radix-ui/react-alert-dialog": "1.1.15", + "@radix-ui/react-checkbox": "1.3.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-dropdown-menu": "2.1.16", + "@radix-ui/react-hover-card": "1.1.15", + "@radix-ui/react-label": "2.1.8", + "@radix-ui/react-menubar": "1.1.16", + "@radix-ui/react-select": "2.2.6", + "@radix-ui/react-separator": "1.1.8", + "@radix-ui/react-slot": "1.2.4", + "@radix-ui/react-switch": "1.2.6", + "@radix-ui/react-tabs": "1.1.13", + "@radix-ui/react-tooltip": "1.2.8", + "@radixdlt/babylon-gateway-api-sdk": "1.10.1", + "@radixdlt/radix-dapp-toolkit": "2.3.0", + "@scure/base": "2.2.0", + "@scure/bip32": "2.2.0", + "@scure/bip39": "~2.2.0", + "@sentry/react": "9.27.0", + "@solana/spl-memo": "0.2.5", + "@solana/spl-token": "0.4.14", + "@solana/web3.js": "1.98.4", + "@stellar/stellar-sdk": "15.1.0", + "@stricahq/bip32ed25519": "1.1.2", + "@stricahq/cbors": "1.0.4", + "@stricahq/typhonjs": "~3.0.1", + "@swapkit/core": "^4.4.33", + "@swapkit/helpers": "^4.14.0", + "@swapkit/plugins": "^4.6.47", + "@swapkit/toolboxes": "^4.17.1", + "@swapkit/wallet-keystore": "^4.4.1", + "@swapkit/wallets": "workspace:*", + "@ton/core": "0.63.1", + "@ton/crypto": "3.3.0", + "@ton/ton": "16.2.4", + "bignumber.js": "9.3.1", + "class-variance-authority": "0.7.1", + "clsx": "2.1.1", + "cosmjs-types": "0.10.1", + "crypto-browserify": "3.12.1", + "ethers": "6.16.0", + "highlight.js": "^11.11.1", + "lucide-react": "0.552.0", + "micro-key-producer": "0.8.6", + "micro-packed": "0.9.0", + "near-seed-phrase": "0.2.1", + "nuqs": "2.8.9", + "protobufjs": "8.0.3", + "react": "19.1.1", + "react-dom": "19.1.1", + "react-hook-form": "7.65.0", + "sonner": "2.0.7", + "starknet": "10.0.2", + "tailwind-merge": "2.6.0", + "tailwindcss": "3.4.18", + "tailwindcss-animate": "1.0.7", + "ts-pattern": "^5.9.0", + "xrpl": "4.6.0", + "zod": "4.4.3", + "zustand": "5.0.13", + }, + "devDependencies": { + "@sentry/vite-plugin": "3.5.0", + "@vitejs/plugin-react": "5.1.0", + "tailwindcss-scoped-preflight": "3.5.9", + "terser": "5.46.0", + "vite": "7.1.10", + "vite-plugin-node-polyfills": "0.25.0", + "vite-plugin-wasm": "3.5.0", + }, + }, "packages/wallet-extensions": { "name": "@swapkit/wallet-extensions", "version": "4.5.17", @@ -218,26 +320,33 @@ }, "playgrounds/vite-lite": { "name": "@internal/playground-vite-lite", - "version": "0.0.9", + "version": "0.0.22", "dependencies": { - "@swapkit/sdk": "workspace:*", - "@swapkit/ui": "0.20.0", - "@swapkit/wallet-extensions": "workspace:*", - "@swapkit/wallet-hardware": "workspace:*", - "@swapkit/wallet-mobile": "workspace:*", - "@swapkit/wallets": "workspace:*", - "hoist-non-react-statics": "3.3.2", + "@scure/base": "2.2.0", + "@sentry/react": "9.27.0", + "@swapkit/ui": "workspace:*", + "lodash-es": "4.17.23", "nuqs": "2.8.9", - "react": "19.2.5", - "react-dom": "19.2.5", + "react": "19.1.1", + "react-dom": "19.1.1", }, "devDependencies": { + "@eslint/js": "9.36.0", + "@types/node": "25.6.0", "@types/react": "19.2.14", "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "5.1.0", + "eslint": "9.36.0", + "eslint-plugin-react-hooks": "5.2.0", + "eslint-plugin-react-refresh": "0.4.22", + "globals": "16.4.0", + "ledger-bitcoin": "0.3.0", "typescript": "6.0.3", + "typescript-eslint": "8.45.0", "vite": "7.1.10", + "vite-plugin-cjs-interop": "2.4.3", "vite-plugin-node-polyfills": "0.25.0", + "vite-plugin-wasm": "3.5.0", }, }, "tools/builder": { @@ -257,6 +366,10 @@ }, }, "overrides": { + "@swapkit/helpers": "4.14.0", + "@swapkit/types": "0.8.0", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", "nuqs": "2.8.9", }, "packages": { @@ -404,6 +517,12 @@ "@cosmjs/utils": ["@cosmjs/utils@0.37.1", "", {}, "sha512-WPDPtHRxhG1xR/3H7xtNtWGgpYdnYj4tTC+nmavuOcPRjyowCS7jZXoi+LWJVKHJoj/s/G/3hH7WW/dqbBygwA=="], + "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@emurgo/cardano-serialization-lib-browser": ["@emurgo/cardano-serialization-lib-browser@13.2.1", "", {}, "sha512-7RfX1gI16Vj2DgCp/ZoXqyLAakWo6+X95ku/rYGbVzuS/1etrlSiJmdbmdm+eYmszMlGQjrtOJQeVLXoj4L/Ag=="], "@emurgo/cardano-serialization-lib-nodejs": ["@emurgo/cardano-serialization-lib-nodejs@13.2.0", "", {}, "sha512-Bz1zLGEqBQ0BVkqt1OgMxdBOE3BdUWUd7Ly9Ecr/aUwkA8AV1w1XzBMe4xblmJHnB1XXNlPH4SraXCvO+q0Mig=="], @@ -460,6 +579,24 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="], + + "@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="], + + "@eslint/js": ["@eslint/js@9.36.0", "", {}, "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="], + "@ethereumjs/common": ["@ethereumjs/common@10.1.1", "", { "dependencies": { "@ethereumjs/util": "^10.1.1", "eventemitter3": "^5.0.1" } }, "sha512-NefPzPlrJ9w+NWVe06P+sHZQU98E1AEU9vhiHJEVT2wEcNBC1YX6hON9+smrfbn86C4U1pb2zbvjhkF+n/LKBw=="], "@ethereumjs/rlp": ["@ethereumjs/rlp@10.1.1", "", { "bin": { "rlp": "bin/rlp.cjs" } }, "sha512-jbnWTEwcpoY+gE0r+wxfDG9zgiu54DcTcwnc9sX3DsqKR4l5K7x2V8mQL3Et6hURa4DuT9g7z6ukwpBLFchszg=="], @@ -522,6 +659,16 @@ "@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="], + "@humanfs/core": ["@humanfs/core@0.19.2", "", { "dependencies": { "@humanfs/types": "^0.15.0" } }, "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA=="], + + "@humanfs/node": ["@humanfs/node@0.16.8", "", { "dependencies": { "@humanfs/core": "^0.19.2", "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ=="], + + "@humanfs/types": ["@humanfs/types@0.15.0", "", {}, "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], "@internal/github": ["@internal/github@workspace:tools/github"], @@ -538,6 +685,8 @@ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], @@ -626,9 +775,11 @@ "@mysten/utils": ["@mysten/utils@0.2.0", "", { "dependencies": { "@scure/base": "^1.2.6" } }, "sha512-CM6kJcJHX365cK6aXfFRLBiuyXc5WSBHQ43t94jqlCAIRw8umgNcTb5EnEA9n31wPAQgLDGgbG/rCUISCTJ66w=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@near-js/accounts": ["@near-js/accounts@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/keystores": "2.5.1", "@near-js/providers": "2.5.1", "@near-js/signers": "2.5.1", "@near-js/tokens": "2.5.1", "@near-js/transactions": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0", "depd": "2.0.0", "is-my-json-valid": "^2.20.6", "lru_map": "0.4.1", "near-abi": "0.2.0" } }, "sha512-L4/Z9Ujwnz8/uvOExESP6h0t/plu4/0SFrL+UJBnfO5LObVwnJH2KG6MCLONy8rKh1FZHOlT9LPhtG/6nUrvOQ=="], - "@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + "@near-js/crypto": ["@near-js/crypto@2.5.0", "", { "dependencies": { "@near-js/types": "2.5.0", "@near-js/utils": "2.5.0", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-bsMCasnjRne9j0u5DuKeO0/xwS49GgRrVxzmW9WRZ7yWWh0U8IidTxNHTL1QCDFJNwwzt9HDnuj8XeVhlpixww=="], "@near-js/keystores": ["@near-js/keystores@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1" } }, "sha512-UlP3GXeDzRyUlL3qKZUkwSwbABDarhOqRRR0vcMBOOu+063GDULGio9GTWDvKDDi11nmfbhOzbiY5vXEW4jR8g=="], @@ -642,7 +793,7 @@ "@near-js/tokens": ["@near-js/tokens@2.5.1", "", {}, "sha512-doDtOaSA2FOsYzzwocg0L02z6ORNL7HFAuL455y2O38//F4C2jp+C9De9fWrItkrim2jKjoSR3UvO2AuVbwmWA=="], - "@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], + "@near-js/transactions": ["@near-js/transactions@2.5.0", "", { "dependencies": { "@near-js/crypto": "2.5.0", "@near-js/types": "2.5.0", "@near-js/utils": "2.5.0", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-gVhWS4T5VcLjyVaW8nxWxK7kcgbGgyJ0YVS+VmaFzQbSZKuYgNnQXxynTycFc34awTNbp3a4/MqAd8RgX9VIcg=="], "@near-js/types": ["@near-js/types@2.5.1", "", {}, "sha512-lUJJmbV6qcilIwswldeP7FIjkjTWvmtgI+yQHVmiBNRVjYvPMiQ/e9vs3SXE/cYtRluAdq0JHJwYoqhFb69mwA=="], @@ -672,6 +823,48 @@ "@orbs-network/ton-access": ["@orbs-network/ton-access@2.3.3", "", { "dependencies": { "isomorphic-fetch": "^3.0.0" } }, "sha512-b1miCPts7wBG9JKYgzXIRZQm/LMy5Uk1mNK8NzlcXHL3HRHJkkFbuYJGuj3IkWCiIicW3Ipp4sYnn3Fwo4oB0g=="], + "@oxc-parser/binding-android-arm-eabi": ["@oxc-parser/binding-android-arm-eabi@0.116.0", "", { "os": "android", "cpu": "arm" }, "sha512-AOET7YIOU3+ANO/3xQeRVGN5Xx6+JGXaIwlqkcHSfxJ/zzw2B6jb0YaLhX45SeRluKVTU8rka4N/tHtNoJjoCg=="], + + "@oxc-parser/binding-android-arm64": ["@oxc-parser/binding-android-arm64@0.116.0", "", { "os": "android", "cpu": "arm64" }, "sha512-yh0Zvth5cQ6XZkP3QF9MDrXf695zr5XxXq/wBQqpZb0uAgI9wpr98/Hx2RZITMfnNjkIq2VcyU44o3A0bdEmlQ=="], + + "@oxc-parser/binding-darwin-arm64": ["@oxc-parser/binding-darwin-arm64@0.116.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-plcTd/Jska55dToZz6XdRBPRVsj+asjD8QCpQFvt3Wj8pY+10D1pE53Mei3POAS/wSRSy7HiQ2twrm7H2A0CjA=="], + + "@oxc-parser/binding-darwin-x64": ["@oxc-parser/binding-darwin-x64@0.116.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ahqcF3e3x5Z2ZepzXpZ8ugREdmxvBL+g1nQ0SxO11pIZfck6UtbOtwtdAAxnQXBHHtidu7lPcrBq1SEx26t1PQ=="], + + "@oxc-parser/binding-freebsd-x64": ["@oxc-parser/binding-freebsd-x64@0.116.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-yo2/LaSXtlzKBurvNbwun/sN/RJwW3XhbMr069FwNVtft7GBnaLLdPIz/sf47icxw/BPViEX6wFvzeD12mtrAg=="], + + "@oxc-parser/binding-linux-arm-gnueabihf": ["@oxc-parser/binding-linux-arm-gnueabihf@0.116.0", "", { "os": "linux", "cpu": "arm" }, "sha512-EiZeliIPPdFsuaPx8PzDMVijD/4YaUxO46/eYPk5raRocJqjjxOG6GAacQ8UrG3fbrgYjaEChfYL1e8DyE445A=="], + + "@oxc-parser/binding-linux-arm-musleabihf": ["@oxc-parser/binding-linux-arm-musleabihf@0.116.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Nf7hnKRYRSIgglQcLAqE2St4b/Yr6dh+Z7in8mxol065Knevw71XZAiV1fmPSojq6uKPLV9eoH/wFrgr4TnZXw=="], + + "@oxc-parser/binding-linux-arm64-gnu": ["@oxc-parser/binding-linux-arm64-gnu@0.116.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-9SJI0S4Qggn3QHpT8Y1jtZceA0m4BlpvO3ne2Wxd33UdTHMmelAnrXryjWutHWQtjCzOwSnFBEoQAdNNyt1u3A=="], + + "@oxc-parser/binding-linux-arm64-musl": ["@oxc-parser/binding-linux-arm64-musl@0.116.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-wMZ6//GI+q1JwO7G2OR51+eA5P8Gr3BobU8RAzCGJptvyGMkWb7KQ1E8s8naVZRr6bSGWAL2p3mCzKOxmEPmrA=="], + + "@oxc-parser/binding-linux-ppc64-gnu": ["@oxc-parser/binding-linux-ppc64-gnu@0.116.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-5BO0KCzTG2HZTnp3r6SCAOeCs/GwFBQJ1WAOG/ROfDf1fVVEy6hrtLKTLCuUMaamH38v+1+RVEmzRkzBj+rMDQ=="], + + "@oxc-parser/binding-linux-riscv64-gnu": ["@oxc-parser/binding-linux-riscv64-gnu@0.116.0", "", { "os": "linux", "cpu": "none" }, "sha512-M24gYb/ocVMnLwnH2wY5sLt4sRBkAUHDmfiYtyUYdKTkfPOKtpopd5otsL/BPLnIhpMD8zby4uXVvw7BU0UIlw=="], + + "@oxc-parser/binding-linux-riscv64-musl": ["@oxc-parser/binding-linux-riscv64-musl@0.116.0", "", { "os": "linux", "cpu": "none" }, "sha512-LHLXTHCH0bdvGjlitwr1ngeh32GAgq9HYzQ5VAgt0k0UT84AS8AkXj9Spoa9l20fXkVgSvAKcCEkydi4Ol23Dw=="], + + "@oxc-parser/binding-linux-s390x-gnu": ["@oxc-parser/binding-linux-s390x-gnu@0.116.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-VE+XsztuE5jdHvLIDIQMuyDpz5NJGq1Vx/8EXYF0sS/gehlv9GhDpGVWU0SCZ/LjzIy4io/Z0W84UudqufvP3g=="], + + "@oxc-parser/binding-linux-x64-gnu": ["@oxc-parser/binding-linux-x64-gnu@0.116.0", "", { "os": "linux", "cpu": "x64" }, "sha512-rxUkauyjjCmgA7BoR63ogRGEtgubROnCm8AXE9ydg+p42jCGLLqG05mFcS2eC+FYyAU58ZFJNXXeqFW1iCyTGQ=="], + + "@oxc-parser/binding-linux-x64-musl": ["@oxc-parser/binding-linux-x64-musl@0.116.0", "", { "os": "linux", "cpu": "x64" }, "sha512-0zoZlk9MmXe6oTgSh5lT1D51SDC1bfwC96JmE1amMFAPdEbJk5MFRisfTN9TFBpBigQua65842tjaxqMiorAYw=="], + + "@oxc-parser/binding-openharmony-arm64": ["@oxc-parser/binding-openharmony-arm64@0.116.0", "", { "os": "none", "cpu": "arm64" }, "sha512-PGS7Xqik77U9WMyW626gAD5A2rSN629UvyYJKAl/tgpT+KqZI4+56pJfExhv8IW/PpSHjYHwjmakwobLikz8ww=="], + + "@oxc-parser/binding-wasm32-wasi": ["@oxc-parser/binding-wasm32-wasi@0.116.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-lGNf/9PU8XxB4Gt1Gr1AKwSrjxGYa6os0PlrT4bpoQsfE3gaZonQTKwJyKhiQdgy7pBCI+ed1LB1NNib1FYULw=="], + + "@oxc-parser/binding-win32-arm64-msvc": ["@oxc-parser/binding-win32-arm64-msvc@0.116.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-tcsOHE31duBSRQXZ7NfdtjmMKZwQYlS00PwAMJ4w5oXs3iPCvisUuIXP7Ko4FzeOBTRvkd64btxtQ6cRM0Kwlw=="], + + "@oxc-parser/binding-win32-ia32-msvc": ["@oxc-parser/binding-win32-ia32-msvc@0.116.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-higCz/x+dOQ264YEk22hnu4RDqvjhfehjFORpxoh42QyUxsP6eIembYesBUu5ilALWo0HvRD+m89az2BSTwqpQ=="], + + "@oxc-parser/binding-win32-x64-msvc": ["@oxc-parser/binding-win32-x64-msvc@0.116.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Lg2SRmVHpGG85knDVLbv44r1bYn0OpIV0vg9jVmoEIpDj3Q4kwXuQ6MWVtuslwHR8o2CSiqdBeEn1n1URrs6Eg=="], + + "@oxc-project/types": ["@oxc-project/types@0.116.0", "", {}, "sha512-uOT8S1tlPmDckNxMNtIudN/yXpLdnhlJMX2oLS7cxCd7L0sUF09A/EbSVMWT3Y/iT44IwXCJSJfgfSxXAqWf9Q=="], + "@passkeys/core": ["@passkeys/core@4.1.0", "", { "dependencies": { "@solana/web3.js": "^1.98.2", "sats-connect": "1.0.0", "zod": "^3.23.8" } }, "sha512-aXhiTcTc6zrmmwBL190A4nTUB8Fl7h9FDip38PnreDPyhaueKi0PVWMxhSYGV/HMlMo7O7VB1QQWofyDv2QBiA=="], "@passkeys/react": ["@passkeys/react@3.0.1", "", { "peerDependencies": { "@passkeys/core": "^4.0.0", "react": "^18.2.0 || ^19.0.0", "react-dom": "^18.2.0 || ^19.0.0", "sats-connect": "1.0.0" } }, "sha512-6kVf4cRbKCszGzXc37SVkc77ytgfguB/+NAXawp0Qn8Nm5dzUHlq2jIPgaVeYTaBpdsXu574lfVbLfLFjFOOGQ=="], @@ -938,12 +1131,34 @@ "@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@9.27.0", "", { "dependencies": { "@sentry-internal/replay": "9.27.0", "@sentry/core": "9.27.0" } }, "sha512-44rVSt3LCH6qePYRQrl4WUBwnkOk9dzinmnKmuwRksEdDOkVq5KBRhi/IDr7omwSpX8C+KrX5alfKhOx1cP0gQ=="], + "@sentry/babel-plugin-component-annotate": ["@sentry/babel-plugin-component-annotate@3.5.0", "", {}, "sha512-s2go8w03CDHbF9luFGtBHKJp4cSpsQzNVqgIa9Pfa4wnjipvrK6CxVT4icpLA3YO6kg5u622Yoa5GF3cJdippw=="], + "@sentry/browser": ["@sentry/browser@9.27.0", "", { "dependencies": { "@sentry-internal/browser-utils": "9.27.0", "@sentry-internal/feedback": "9.27.0", "@sentry-internal/replay": "9.27.0", "@sentry-internal/replay-canvas": "9.27.0", "@sentry/core": "9.27.0" } }, "sha512-geR3lhRJOmUQqi1WgovLSYcD/f66zYnctdnDEa7j1BW2XIB1nlTJn0mpYyAHghXKkUN/pBpp1Z+Jk0XlVwFYVg=="], + "@sentry/bundler-plugin-core": ["@sentry/bundler-plugin-core@3.5.0", "", { "dependencies": { "@babel/core": "^7.18.5", "@sentry/babel-plugin-component-annotate": "3.5.0", "@sentry/cli": "2.42.2", "dotenv": "^16.3.1", "find-up": "^5.0.0", "glob": "^9.3.2", "magic-string": "0.30.8", "unplugin": "1.0.1" } }, "sha512-zDzPrhJqAAy2VzV4g540qAZH4qxzisstK2+NIJPZUUKztWRWUV2cMHsyUtdctYgloGkLyGpZJBE3RE6dmP/xqQ=="], + + "@sentry/cli": ["@sentry/cli@2.42.2", "", { "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.7", "progress": "^2.0.3", "proxy-from-env": "^1.1.0", "which": "^2.0.2" }, "optionalDependencies": { "@sentry/cli-darwin": "2.42.2", "@sentry/cli-linux-arm": "2.42.2", "@sentry/cli-linux-arm64": "2.42.2", "@sentry/cli-linux-i686": "2.42.2", "@sentry/cli-linux-x64": "2.42.2", "@sentry/cli-win32-i686": "2.42.2", "@sentry/cli-win32-x64": "2.42.2" }, "bin": { "sentry-cli": "bin/sentry-cli" } }, "sha512-spb7S/RUumCGyiSTg8DlrCX4bivCNmU/A1hcfkwuciTFGu8l5CDc2I6jJWWZw8/0enDGxuj5XujgXvU5tr4bxg=="], + + "@sentry/cli-darwin": ["@sentry/cli-darwin@2.42.2", "", { "os": "darwin" }, "sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg=="], + + "@sentry/cli-linux-arm": ["@sentry/cli-linux-arm@2.42.2", "", { "os": [ "linux", "freebsd", ], "cpu": "arm" }, "sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg=="], + + "@sentry/cli-linux-arm64": ["@sentry/cli-linux-arm64@2.42.2", "", { "os": [ "linux", "freebsd", ], "cpu": "arm64" }, "sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw=="], + + "@sentry/cli-linux-i686": ["@sentry/cli-linux-i686@2.42.2", "", { "os": [ "linux", "freebsd", ], "cpu": "ia32" }, "sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ=="], + + "@sentry/cli-linux-x64": ["@sentry/cli-linux-x64@2.42.2", "", { "os": [ "linux", "freebsd", ], "cpu": "x64" }, "sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw=="], + + "@sentry/cli-win32-i686": ["@sentry/cli-win32-i686@2.42.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw=="], + + "@sentry/cli-win32-x64": ["@sentry/cli-win32-x64@2.42.2", "", { "os": "win32", "cpu": "x64" }, "sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw=="], + "@sentry/core": ["@sentry/core@9.27.0", "", {}, "sha512-Zb2SSAdWXQjTem+sVWrrAq9L6YYfxyoTwtapaE6C6qZBR5C8Uak0wcYww8StaCFH7dDA/PSW+VxOwjNXocrQHQ=="], "@sentry/react": ["@sentry/react@9.27.0", "", { "dependencies": { "@sentry/browser": "9.27.0", "@sentry/core": "9.27.0", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { "react": "^16.14.0 || 17.x || 18.x || 19.x" } }, "sha512-UT7iaGEwTqe06O4mgHfKGTRBHg+U0JSI/id+QxrOji6ksosOsSnSC3Vdq+gPs9pzCCFE+6+DkH6foYNNLIN0lw=="], + "@sentry/vite-plugin": ["@sentry/vite-plugin@3.5.0", "", { "dependencies": { "@sentry/bundler-plugin-core": "3.5.0", "unplugin": "1.0.1" } }, "sha512-jUnpTdpicG8wefamw7eNo2uO+Q3KCbOAiF76xH4gfNHSW6TN2hBfOtmLu7J+ive4c0Al3+NEHz19bIPR0lkwWg=="], + "@sinclair/typebox": ["@sinclair/typebox@0.33.22", "", {}, "sha512-auUj4k+f4pyrIVf4GW5UKquSZFHJWri06QgARy9C0t9ZTjJLIuNIrr1yl9bWcJWJ1Gz1vOvYN1D+QPaIlNMVkQ=="], "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], @@ -1104,7 +1319,7 @@ "@swapkit/types": ["@swapkit/types@0.8.0", "", {}, "sha512-FagrQGiWfOyIMHHrmbJsb/Ue/FGCYDPz0aEHRGEnEbV9KdT41dDNC+WNdAWbS97KLT9pRRa6EeDpOpB2gYf/ug=="], - "@swapkit/ui": ["@swapkit/ui@0.20.0", "", { "dependencies": { "@aptos-labs/ts-sdk": "1.34.0", "@cosmjs/amino": "0.39.0", "@cosmjs/crypto": "0.39.0", "@cosmjs/proto-signing": "0.39.0", "@cosmjs/stargate": "0.39.0", "@hookform/resolvers": "5.2.2", "@mysten/sui": "1.44.0", "@near-js/accounts": "2.5.1", "@near-js/crypto": "2.5.1", "@near-js/providers": "2.5.1", "@near-js/signers": "2.5.1", "@near-js/transactions": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "2.2.0", "@noble/hashes": "2.2.0", "@orbs-network/ton-access": "2.3.3", "@polkadot/api": "15.10.2", "@polkadot/keyring": "13.5.7", "@polkadot/rpc-provider": "15.10.2", "@polkadot/util": "13.5.7", "@polkadot/util-crypto": "13.5.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.8", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.8", "@radix-ui/react-slot": "1.2.4", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-tooltip": "1.2.8", "@radixdlt/babylon-gateway-api-sdk": "1.10.1", "@radixdlt/radix-dapp-toolkit": "2.3.0", "@scure/base": "2.2.0", "@scure/bip32": "2.2.0", "@scure/bip39": "2.2.0", "@sentry/react": "9.27.0", "@solana/spl-memo": "0.2.5", "@solana/spl-token": "0.4.14", "@solana/web3.js": "1.98.4", "@stellar/stellar-sdk": "15.1.0", "@stricahq/bip32ed25519": "1.1.2", "@stricahq/cbors": "1.0.4", "@stricahq/typhonjs": "3.1.0", "@swapkit/core": "^4.4.33", "@swapkit/helpers": "^4.14.0", "@swapkit/plugins": "^4.6.47", "@swapkit/toolboxes": "^4.17.1", "@swapkit/wallet-keystore": "^4.4.1", "@swapkit/wallets": "^4.8.23", "@ton/core": "0.63.1", "@ton/crypto": "3.3.0", "@ton/ton": "16.2.4", "bignumber.js": "9.3.1", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cosmjs-types": "0.11.0", "crypto-browserify": "3.12.1", "ethers": "6.16.0", "highlight.js": "^11.11.1", "lucide-react": "0.552.0", "micro-key-producer": "0.8.6", "micro-packed": "0.9.0", "near-seed-phrase": "0.2.1", "nuqs": "2.8.9", "protobufjs": "8.0.3", "react": "19.1.1", "react-dom": "19.1.1", "react-hook-form": "7.65.0", "sonner": "2.0.7", "starknet": "10.0.2", "tailwind-merge": "2.6.0", "tailwindcss": "3.4.18", "tailwindcss-animate": "1.0.7", "ts-pattern": "5.9.0", "xrpl": "4.6.0", "zod": "4.4.3", "zustand": "5.0.13" } }, "sha512-uO+pACSXikB7M3J1LOk6S3mmLx/L2+5+FIqrtMt71YLdsNIwCcbekDrsPTewtqFa2K7oCkr4xDu9+3gi2zEFiQ=="], + "@swapkit/ui": ["@swapkit/ui@workspace:packages/ui"], "@swapkit/utxo-signer": ["@swapkit/utxo-signer@2.2.0", "", { "peerDependencies": { "@noble/curves": "2.2.0", "@noble/hashes": "2.2.0", "@scure/base": "2.2.0", "micro-packed": "0.9.0" } }, "sha512-yDdqcUzhmI3wzXpw/7fFnJdNoXrYEFDrhB5bJjUXx34xoE0CaOVtjj/kveAAa60dUoTyITS/OtWL32+Gi4Z0wg=="], @@ -1172,6 +1387,8 @@ "@trezor/websocket-client": ["@trezor/websocket-client@1.3.0", "", { "dependencies": { "@trezor/utils": "9.5.0", "ws": "^8.18.0" }, "peerDependencies": { "tslib": "^2.6.2" } }, "sha512-9KQSaVc3NtmM6rFFj1e+9bM0C5mVKVidbnxlfzuBJu7G2YMRdIdLPcAXhvmRZjs40uzDuBeApK+p547kODz2ug=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], @@ -1214,7 +1431,29 @@ "@types/websocket": ["@types/websocket@1.0.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-svjGZvPB7EzuYS94cI7a+qhwgGU1y89wUgjT6E2wVUfmAGIvRfT7obBvRtnhXCSsoMdlG4gBFGE7MfkIXZLoww=="], - "@types/ws": ["@types/ws@7.4.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww=="], + "@types/whatwg-mimetype": ["@types/whatwg-mimetype@3.0.2", "", {}, "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA=="], + + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.45.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/type-utils": "8.45.0", "@typescript-eslint/utils": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.45.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.45.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.45.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.45.0", "@typescript-eslint/types": "^8.45.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.45.0", "", { "dependencies": { "@typescript-eslint/types": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0" } }, "sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA=="], + + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.45.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.45.0", "", { "dependencies": { "@typescript-eslint/types": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0", "@typescript-eslint/utils": "8.45.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@8.45.0", "", {}, "sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.45.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.45.0", "@typescript-eslint/tsconfig-utils": "8.45.0", "@typescript-eslint/types": "8.45.0", "@typescript-eslint/visitor-keys": "8.45.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.45.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.45.0", "", { "dependencies": { "@typescript-eslint/types": "8.45.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.0", "", { "dependencies": { "@babel/core": "^7.28.4", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.43", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew=="], @@ -1274,13 +1513,17 @@ "abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="], + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + "aes-js": ["aes-js@4.0.0-beta.5", "", {}, "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q=="], - "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], - "ajv": ["ajv@8.11.2", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg=="], + "ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], @@ -1314,7 +1557,9 @@ "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], - "axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], + "axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "base-x": ["base-x@4.0.1", "", {}, "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw=="], @@ -1366,6 +1611,8 @@ "borsh": ["borsh@1.0.0", "", {}, "sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ=="], + "brace-expansion": ["brace-expansion@1.1.15", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg=="], + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "brorand": ["brorand@1.1.0", "", {}, "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="], @@ -1394,6 +1641,10 @@ "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "buffer-image-size": ["buffer-image-size@0.6.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ=="], + "buffer-xor": ["buffer-xor@1.0.3", "", {}, "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ=="], "bufferutil": ["bufferutil@4.1.0", "", { "dependencies": { "node-gyp-build": "^4.3.0" } }, "sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw=="], @@ -1414,11 +1665,13 @@ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + "camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001788", "", {}, "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001776", "", {}, "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw=="], "cardinal": ["cardinal@2.1.1", "", { "dependencies": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" }, "bin": { "cdl": "./bin/cdl.js" } }, "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw=="], @@ -1426,7 +1679,7 @@ "cbor": ["cbor@10.0.12", "", { "dependencies": { "nofilter": "^3.0.2" } }, "sha512-exQDevYd7ZQLP4moMQcZkKCVZsXLAtUSflObr3xTh4xzFIv/xBCdvCd6L259kQOUP2kcTC0jvC6PpZIf/WmRXA=="], - "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], @@ -1436,7 +1689,7 @@ "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - "cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "^1.0.0" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], @@ -1450,7 +1703,9 @@ "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], - "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], "console-browserify": ["console-browserify@1.2.0", "", {}, "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="], @@ -1492,7 +1747,7 @@ "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], - "dataloader": ["dataloader@1.4.0", "", {}, "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="], + "dataloader": ["dataloader@2.2.3", "", {}, "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA=="], "dateformat": ["dateformat@4.6.3", "", {}, "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="], @@ -1502,6 +1757,8 @@ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], @@ -1562,6 +1819,8 @@ "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], @@ -1586,11 +1845,33 @@ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@9.36.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.36.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ=="], + + "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="], + + "eslint-plugin-react-refresh": ["eslint-plugin-react-refresh@0.4.22", "", { "peerDependencies": { "eslint": ">=8.40" } }, "sha512-atkAG6QaJMGoTLc4MDAP+rqZcfwQuTIh2IqHWFLy2TEjxr0MOK+5BSG4RzL2564AAPpZkDRsZXAUz68kjnU6Ug=="], + + "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + "esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="], + "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], - "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], + + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], "ethers": ["ethers@6.16.0", "", { "dependencies": { "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", "ws": "8.17.1" } }, "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A=="], @@ -1620,6 +1901,8 @@ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="], @@ -1638,11 +1921,17 @@ "fetch-ponyfill": ["fetch-ponyfill@7.1.0", "", { "dependencies": { "node-fetch": "~2.6.1" } }, "sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="], "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], @@ -1654,6 +1943,8 @@ "fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -1676,8 +1967,12 @@ "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + "glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", "minipass": "^4.2.4", "path-scurry": "^1.6.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + "globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="], + "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], @@ -1690,10 +1985,16 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], + "graphql": ["graphql@16.13.2", "", {}, "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig=="], "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], + "happy-dom": ["happy-dom@20.10.1", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "buffer-image-size": "^0.6.4", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-awPoqPjx8CgjapJllyDlgzgVHjBExcitKK5ZJkxwhQJyQpHFkyS2bEcqCm7IeW20cQvuCI0cz2Ifq79CJKqtiw=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], @@ -1726,6 +2027,8 @@ "https-browserify": ["https-browserify@1.0.0", "", {}, "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg=="], + "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], + "human-id": ["human-id@4.1.3", "", { "bin": { "human-id": "dist/cli.js" } }, "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q=="], "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], @@ -1740,6 +2043,10 @@ "immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="], + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "int64-buffer": ["int64-buffer@1.1.0", "", {}, "sha512-94smTCQOvigN4d/2R/YDjz8YVG0Sufvv2aAh8P5m42gwhCsDAJqnbNOrxJsrADuAFAA69Q/ptGzxvNcNuIJcvw=="], @@ -1824,7 +2131,9 @@ "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], - "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], @@ -1852,6 +2161,30 @@ "ledger-bitcoin": ["ledger-bitcoin@0.3.0", "", { "dependencies": { "@bitcoinerlab/descriptors": "^1.1.1", "@bitcoinerlab/secp256k1": "^1.2.0", "@ledgerhq/hw-transport": "^6.31.13", "bip32-path": "^0.4.2", "bitcoinjs-lib": "^6.1.7" } }, "sha512-gaTCdvnqFMvK6i6112MCcsNC+DDhUx1EKPDgqYoLswgwWLyb+EoZjXI0VxxkW9m7VszQdpOv210xNdohmQ6knw=="], + "lefthook": ["lefthook@2.1.2", "", { "optionalDependencies": { "lefthook-darwin-arm64": "2.1.2", "lefthook-darwin-x64": "2.1.2", "lefthook-freebsd-arm64": "2.1.2", "lefthook-freebsd-x64": "2.1.2", "lefthook-linux-arm64": "2.1.2", "lefthook-linux-x64": "2.1.2", "lefthook-openbsd-arm64": "2.1.2", "lefthook-openbsd-x64": "2.1.2", "lefthook-windows-arm64": "2.1.2", "lefthook-windows-x64": "2.1.2" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-HdAMl4g47kbWSkrUkCx3Kucq54omFS6piMJtXwXNtmCAfB40UaybTJuYtFW4hNzZ5SvaEimtxTp7P/MNIkEfsA=="], + + "lefthook-darwin-arm64": ["lefthook-darwin-arm64@2.1.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AgHu93YuJtj1l9bcKlCbo4Tg8N8xFl9iD6BjXCGaGMu46LSjFiXbJFlkUdpgrL8fIbwoCjJi5FNp3POpqs4Wdw=="], + + "lefthook-darwin-x64": ["lefthook-darwin-x64@2.1.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-exooc9Ectz13OLJJOXM9AzaFQbqzf9QCF8JuVvGfbr4RYABYK+BwwtydjlPQrA76/n/h4tsS11MH5bBULnLkYA=="], + + "lefthook-freebsd-arm64": ["lefthook-freebsd-arm64@2.1.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-E1QMlJPEU21n9eewv6ePfh+JmoTSg5R1jaYcKCky10kfbMdohNucI3xV91F2LcerE+p3UejKDqr/1wWO2RMGeQ=="], + + "lefthook-freebsd-x64": ["lefthook-freebsd-x64@2.1.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-/5zp+x8055Thj46x9S7hgnneZxvWhHQvPWkkgISCab1Lh6eLrbxvhE1qTb1lU3DqTnNmH9NeXdq1xPHc9uGluA=="], + + "lefthook-linux-arm64": ["lefthook-linux-arm64@2.1.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK5FvDTkwKO7tOznY8iEZzuTsM1jXMZAG5BMRs7olN1k1K6m2unR6oKABP0hCd0wDErK6DZKDJDJfB564Rzqtw=="], + + "lefthook-linux-x64": ["lefthook-linux-x64@2.1.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4eOtz4PNh8GbJ+nA8YVDfW/eMirQWdZqMP/V/MVtoVBGobf6oXvvuDOySvAPOgNYEFN0Boegytmuji/851Vstg=="], + + "lefthook-openbsd-arm64": ["lefthook-openbsd-arm64@2.1.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-lJXRJ6iJIBKwomuNBA3CUNSclj2/rKuxGAQoUra214B92VB6jL9zaY5YEs6h/ie9jQrzSnllEeg7xyDIsuVCrQ=="], + + "lefthook-openbsd-x64": ["lefthook-openbsd-x64@2.1.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-GyOje4W0DIqkmR7/Of5D+mZ0vWqMvtGAVedtJR6d1239xNeMzCS8Q+/a3O1xigceZa5xhlqq0BWlssB/QYPQnA=="], + + "lefthook-windows-arm64": ["lefthook-windows-arm64@2.1.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-MZKMqTULEpX/8N3fKXAR0A9RjsGKkEEY0japLqrHOIpxsJXry1DRz0FvQo2kkY4WW3rtFegV9m6eesOymuDrUg=="], + + "lefthook-windows-x64": ["lefthook-windows-x64@2.1.2", "", { "os": "win32", "cpu": "x64" }, "sha512-NZUgObuaSxc0EXAwC/CzkMf7TuQc++GGIk6TLPdaUpoSsNSJSZEwBVz5DtFB1cG+eMkfO/wOKplls+yjimTTtQ=="], + + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], @@ -1862,15 +2195,19 @@ "lit-html": ["lit-html@3.3.2", "", { "dependencies": { "@types/trusted-types": "^2.0.2" } }, "sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw=="], - "locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], + "lodash-es": ["lodash-es@4.17.23", "", {}, "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="], + "lodash.clonedeep": ["lodash.clonedeep@4.5.0", "", {}, "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="], + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], - "long": ["long@4.0.0", "", {}, "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="], + "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], @@ -1912,8 +2249,12 @@ "minimalistic-crypto-utils": ["minimalistic-crypto-utils@1.0.1", "", {}, "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="], + "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], + "mock-socket": ["mock-socket@9.3.1", "", {}, "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw=="], "motion": ["motion@10.16.2", "", { "dependencies": { "@motionone/animation": "^10.15.1", "@motionone/dom": "^10.16.2", "@motionone/svelte": "^10.16.2", "@motionone/types": "^10.15.1", "@motionone/utils": "^10.15.1", "@motionone/vue": "^10.16.2" } }, "sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ=="], @@ -1932,6 +2273,8 @@ "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + "near-abi": ["near-abi@0.2.0", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-kCwSf/3fraPU2zENK18sh+kKG4uKbEUEQdyWQkmW8ZofmLarObIz2+zAYjA1teDZLeMvEQew3UysnPDXgjneaA=="], "near-api-js": ["near-api-js@3.0.4", "", { "dependencies": { "@near-js/accounts": "1.0.4", "@near-js/crypto": "1.2.1", "@near-js/keystores": "0.0.9", "@near-js/keystores-browser": "0.0.9", "@near-js/keystores-node": "0.0.9", "@near-js/providers": "0.1.1", "@near-js/signers": "0.1.1", "@near-js/transactions": "1.1.2", "@near-js/types": "0.0.4", "@near-js/utils": "0.1.0", "@near-js/wallet-account": "1.1.1", "@noble/curves": "1.2.0", "ajv": "8.11.2", "ajv-formats": "2.1.1", "bn.js": "5.2.1", "borsh": "1.0.0", "depd": "2.0.0", "http-errors": "1.7.2", "near-abi": "0.1.1", "node-fetch": "2.6.7" } }, "sha512-qKWjnugoB7kSFhzZ5GXyH/eABspCQYWBmWnM4hpV5ctnQBt89LqgEu9yD1z4sa89MvUu8BuCxwb1m00BE8iofg=="], @@ -1950,7 +2293,7 @@ "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], - "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], @@ -1988,19 +2331,23 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "os-browserify": ["os-browserify@0.3.0", "", {}, "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A=="], "outdent": ["outdent@0.5.0", "", {}, "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q=="], - "ox": ["ox@0.14.17", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@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", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-jOzNb2Wlfzsr8z/GoCtd1bf6OSRuWuysvbhnHGD+7fV1WRbcBR6B0RYoe3xWnUedF7zp4l5APmS7CzAhUok/lA=="], + "ox": ["ox@0.4.4", "", { "dependencies": { "@adraffy/ens-normalize": "^1.10.1", "@noble/curves": "^1.6.0", "@noble/hashes": "^1.5.0", "@scure/bip32": "^1.5.0", "@scure/bip39": "^1.4.0", "abitype": "^1.0.6", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-oJPEeCDs9iNiPs6J0rTx+Y0KGeCGyCAA3zo94yZhm8G5WpOxrwUtn2Ie/Y8IyARSqqY/j9JTKA3Fc1xs1DvFnw=="], + + "oxc-parser": ["oxc-parser@0.116.0", "", { "dependencies": { "@oxc-project/types": "^0.116.0" }, "optionalDependencies": { "@oxc-parser/binding-android-arm-eabi": "0.116.0", "@oxc-parser/binding-android-arm64": "0.116.0", "@oxc-parser/binding-darwin-arm64": "0.116.0", "@oxc-parser/binding-darwin-x64": "0.116.0", "@oxc-parser/binding-freebsd-x64": "0.116.0", "@oxc-parser/binding-linux-arm-gnueabihf": "0.116.0", "@oxc-parser/binding-linux-arm-musleabihf": "0.116.0", "@oxc-parser/binding-linux-arm64-gnu": "0.116.0", "@oxc-parser/binding-linux-arm64-musl": "0.116.0", "@oxc-parser/binding-linux-ppc64-gnu": "0.116.0", "@oxc-parser/binding-linux-riscv64-gnu": "0.116.0", "@oxc-parser/binding-linux-riscv64-musl": "0.116.0", "@oxc-parser/binding-linux-s390x-gnu": "0.116.0", "@oxc-parser/binding-linux-x64-gnu": "0.116.0", "@oxc-parser/binding-linux-x64-musl": "0.116.0", "@oxc-parser/binding-openharmony-arm64": "0.116.0", "@oxc-parser/binding-wasm32-wasi": "0.116.0", "@oxc-parser/binding-win32-arm64-msvc": "0.116.0", "@oxc-parser/binding-win32-ia32-msvc": "0.116.0", "@oxc-parser/binding-win32-x64-msvc": "0.116.0" } }, "sha512-ugEo6wwqaqCGcpi7GsLCwSkoD7gIXzvtdaTxE+mbrXFYazU5Q9YdpZdAj9z2b79i/xlv+uW2aAvyzGAlpUzhKQ=="], "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], "p-filter": ["p-filter@2.1.0", "", { "dependencies": { "p-map": "^2.0.0" } }, "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw=="], - "p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], - "p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], "p-map": ["p-map@2.1.0", "", {}, "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="], @@ -2010,6 +2357,8 @@ "pako": ["pako@2.1.0", "", {}, "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="], + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parse-asn1": ["parse-asn1@5.1.9", "", { "dependencies": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", "evp_bytestokey": "^1.0.3", "pbkdf2": "^3.1.5", "safe-buffer": "^5.2.1" } }, "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg=="], "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], @@ -2020,6 +2369,8 @@ "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], "pbkdf2": ["pbkdf2@3.1.5", "", { "dependencies": { "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "ripemd160": "^2.0.3", "safe-buffer": "^5.2.1", "sha.js": "^2.4.12", "to-buffer": "^1.2.1" } }, "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ=="], @@ -2064,6 +2415,8 @@ "preact": ["preact@10.29.1", "", {}, "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + "prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], @@ -2072,13 +2425,15 @@ "process-warning": ["process-warning@5.0.0", "", {}, "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA=="], + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + "propagate": ["propagate@2.0.1", "", {}, "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag=="], "protobufjs": ["protobufjs@8.0.3", "", { "dependencies": { "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-LBYnMWkKLB8fE/ljROPDbCl7mgLSlI+oBe1fAAr5MTqFg4TIi0tYrVVurJvQggOjnUYMQtEZBjrej59ojMNTHQ=="], "proxy-compare": ["proxy-compare@2.5.1", "", {}, "sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA=="], - "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], "public-encrypt": ["public-encrypt@4.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q=="], @@ -2108,9 +2463,9 @@ "randomfill": ["randomfill@1.0.4", "", { "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" } }, "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw=="], - "react": ["react@19.2.5", "", {}, "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA=="], + "react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="], - "react-dom": ["react-dom@19.2.5", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.5" } }, "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag=="], + "react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="], "react-hook-form": ["react-hook-form@7.65.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-xtOzDz063WcXvGWaHgLNrNzlsdFgtUWcb32E6WFaGTd7kPZG3EeDusjdZfUsPwKCKVXy1ZlntifaHZ4l8pAsmw=="], @@ -2190,7 +2545,7 @@ "scale-ts": ["scale-ts@1.6.1", "", {}, "sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g=="], - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], "secp256k1": ["secp256k1@5.0.1", "", { "dependencies": { "elliptic": "^6.5.7", "node-addon-api": "^5.0.0", "node-gyp-build": "^4.2.0" } }, "sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA=="], @@ -2238,8 +2593,12 @@ "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "spawndamnit": ["spawndamnit@3.0.1", "", { "dependencies": { "cross-spawn": "^7.0.5", "signal-exit": "^4.0.1" } }, "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg=="], "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], @@ -2272,6 +2631,8 @@ "superstruct": ["superstruct@2.0.2", "", {}, "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A=="], + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], "symbol-observable": ["symbol-observable@2.0.3", "", {}, "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA=="], @@ -2282,8 +2643,12 @@ "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], + "tailwindcss-scoped-preflight": ["tailwindcss-scoped-preflight@3.5.9", "", { "peerDependencies": { "postcss": "^8", "tailwindcss": "^3" } }, "sha512-Q1lJssrJ2K96bCj8tocF/HCMy1NwMpFE30is3F4qFAAGfS9XYj6pz8JqfATSEnFhr7D6VAGLMn9apr/yqbSgTQ=="], + "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], + "terser": ["terser@5.46.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="], + "text-encoding-utf-8": ["text-encoding-utf-8@1.0.2", "", {}, "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg=="], "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], @@ -2310,13 +2675,15 @@ "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], + "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], "ts-mixer": ["ts-mixer@6.0.4", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="], "ts-pattern": ["ts-pattern@5.9.0", "", {}, "sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg=="], - "tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tslog": ["tslog@4.10.2", "", {}, "sha512-XuELoRpMR+sq8fuWwX7P0bcj+PRNiicOKDEb3fGNURhxWVyykCi9BNq7c4uVz7h7P0sj8qgBsr5SWS6yBClq3g=="], @@ -2326,6 +2693,8 @@ "type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], "typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="], @@ -2334,6 +2703,8 @@ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + "typescript-eslint": ["typescript-eslint@8.45.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.45.0", "@typescript-eslint/parser": "8.45.0", "@typescript-eslint/typescript-estree": "8.45.0", "@typescript-eslint/utils": "8.45.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg=="], + "ua-is-frozen": ["ua-is-frozen@0.1.2", "", {}, "sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw=="], "ua-parser-js": ["ua-parser-js@2.0.9", "", { "dependencies": { "detect-europe-js": "^0.1.2", "is-standalone-pwa": "^0.1.1", "ua-is-frozen": "^0.1.2" }, "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-OsqGhxyo/wGdLSXMSJxuMGN6H4gDnKz6Fb3IBm4bxZFMnyy0sdf6MN96Ie8tC6z/btdO+Bsy8guxlvLdwT076w=="], @@ -2350,6 +2721,8 @@ "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + "unplugin": ["unplugin@1.0.1", "", { "dependencies": { "acorn": "^8.8.1", "chokidar": "^3.5.3", "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.5.0" } }, "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA=="], + "unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], @@ -2378,7 +2751,7 @@ "uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="], - "valibot": ["valibot@0.42.1", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw=="], + "valibot": ["valibot@0.36.0", "", {}, "sha512-CjF1XN4sUce8sBK9TixrDqFM7RwNkuXdJu174/AwmQUB62QbCQADg5lLe8ldBalFgtj1uKj+pKwDJiNo4Mn+eQ=="], "valtio": ["valtio@1.11.2", "", { "dependencies": { "proxy-compare": "2.5.1", "use-sync-external-store": "1.2.0" }, "peerDependencies": { "@types/react": ">=16.8", "react": ">=16.8" }, "optionalPeers": ["@types/react", "react"] }, "sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw=="], @@ -2388,18 +2761,28 @@ "vite": ["vite@7.1.10", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA=="], + "vite-plugin-cjs-interop": ["vite-plugin-cjs-interop@2.4.3", "", { "dependencies": { "estree-walker": "^3.0.3", "magic-string": "^0.30.21", "minimatch": "^10.2.4", "oxc-parser": "^0.116.0" }, "peerDependencies": { "vite": "4 || 5 || 6 || 7" } }, "sha512-WH7DUJcuXU3r5DruH8yIyFPxPshgvOUEN4s2ZPohuzEGfQMkp/CmI5NilP7H+q31ut0y57x6dB8D3DAesCI+aQ=="], + "vite-plugin-node-polyfills": ["vite-plugin-node-polyfills@0.25.0", "", { "dependencies": { "@rollup/plugin-inject": "^5.0.5", "node-stdlib-browser": "^1.3.1" }, "peerDependencies": { "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-rHZ324W3LhfGPxWwQb2N048TThB6nVvnipsqBUJEzh3R9xeK9KI3si+GMQxCuAcpPJBVf0LpDtJ+beYzB3/chg=="], + "vite-plugin-wasm": ["vite-plugin-wasm@3.5.0", "", { "peerDependencies": { "vite": "^2 || ^3 || ^4 || ^5 || ^6 || ^7" } }, "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ=="], + "vm-browserify": ["vm-browserify@1.1.2", "", {}, "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="], "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + "webpack-sources": ["webpack-sources@3.5.0", "", {}, "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ=="], + + "webpack-virtual-modules": ["webpack-virtual-modules@0.5.0", "", {}, "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="], + "websocket": ["websocket@1.0.35", "", { "dependencies": { "bufferutil": "^4.0.1", "debug": "^2.2.0", "es5-ext": "^0.10.63", "typedarray-to-buffer": "^3.1.5", "utf-8-validate": "^5.0.2", "yaeti": "^0.0.6" } }, "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q=="], "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], @@ -2410,11 +2793,13 @@ "wif": ["wif@2.0.6", "", { "dependencies": { "bs58check": "<3.0.0" } }, "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ=="], - "wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], + "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], "xrpl": ["xrpl@4.6.0", "", { "dependencies": { "@scure/bip32": "^1.3.1", "@scure/bip39": "^1.2.1", "@xrplf/isomorphic": "^1.0.1", "@xrplf/secret-numbers": "^2.0.0", "bignumber.js": "^9.0.0", "eventemitter3": "^5.0.1", "fast-json-stable-stringify": "^2.1.0", "ripple-address-codec": "^5.0.0", "ripple-binary-codec": "^2.7.0", "ripple-keypairs": "^2.0.0" } }, "sha512-0nXZfqDHRJ6bsDv1WtA9MdCYalMtXuxVa9mtLdqT3xypRKf2LwT5DbuGL/kHcVfuqk3B+ly+SFARlrnX+LHtRQ=="], @@ -2432,15 +2817,15 @@ "xumm-xapp-sdk": ["xumm-xapp-sdk@1.7.2", "", { "dependencies": { "debug": "^4.1.1", "events": "^3.3.0" } }, "sha512-kiJAbA+F4gRNRux1zZ+PYJNko9fI4Y8EFf/4EMX4tPcdQEQyXfIMPj7l6tgwSNRy2sISbw2jUYDMayL+ZFlmOg=="], - "y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "yaeti": ["yaeti@0.0.6", "", {}, "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug=="], "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - "yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], @@ -2466,6 +2851,10 @@ "@bitcoinerlab/secp256k1/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], + "@changesets/get-github-info/dataloader": ["dataloader@1.4.0", "", {}, "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw=="], + + "@changesets/get-github-info/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "@coinbase/wallet-sdk/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], "@coinbase/wallet-sdk/clsx": ["clsx@1.2.1", "", {}, "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="], @@ -2482,6 +2871,12 @@ "@cosmjs/tendermint-rpc/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + + "@eslint/eslintrc/strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + "@ethereumjs/tx/@noble/curves": ["@noble/curves@2.0.1", "", { "dependencies": { "@noble/hashes": "2.0.1" } }, "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw=="], "@ethereumjs/tx/@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], @@ -2490,16 +2885,22 @@ "@ethereumjs/util/@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], + "@keplr-wallet/types/long": ["long@4.0.0", "", {}, "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="], + "@keplr-wallet/types/starknet": ["starknet@9.2.2", "", { "dependencies": { "@noble/curves": "~1.7.0", "@noble/hashes": "~1.6.0", "@scure/base": "~1.2.1", "@scure/starknet": "1.1.0", "@starknet-io/get-starknet-wallet-standard": "^5.0.0", "@starknet-io/starknet-types-010": "npm:@starknet-io/types-js@0.10.0", "@starknet-io/starknet-types-09": "npm:@starknet-io/types-js@~0.9.1", "abi-wan-kanabi": "2.2.4", "lossless-json": "^4.2.0", "pako": "^2.0.4", "ts-mixer": "^6.0.3" } }, "sha512-wYgszbsEWowlc8/PSJGs38kQ54fMYrP5UwN/HpiOUwI1wRFJm7gbTOyrs3fA2UhnScawtBU5besuYkb/nxWm/A=="], "@ledgerhq/client-ids/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], "@ledgerhq/domain-service/@ledgerhq/errors": ["@ledgerhq/errors@6.33.0", "", {}, "sha512-9iMdjB0Hfxfd8HGMVM0TDPfxBXhJ4MtGKyFlm8aveSHSXjcTjGtCkcnk4OUZ6ZHopBb69BFR+HC2N/ob9xuNgA=="], + "@ledgerhq/domain-service/axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], + "@ledgerhq/domain-service/react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="], "@ledgerhq/domain-service/react-dom": ["react-dom@19.0.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ=="], + "@ledgerhq/evm-tools/axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], + "@ledgerhq/hw-app-btc/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@ledgerhq/hw-app-btc/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -2510,6 +2911,8 @@ "@ledgerhq/hw-app-eth/@ledgerhq/errors": ["@ledgerhq/errors@6.33.0", "", {}, "sha512-9iMdjB0Hfxfd8HGMVM0TDPfxBXhJ4MtGKyFlm8aveSHSXjcTjGtCkcnk4OUZ6ZHopBb69BFR+HC2N/ob9xuNgA=="], + "@ledgerhq/hw-app-eth/axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], + "@ledgerhq/hw-transport-mocker/@ledgerhq/hw-transport": ["@ledgerhq/hw-transport@6.35.0", "", { "dependencies": { "@ledgerhq/devices": "8.14.0", "@ledgerhq/errors": "^6.33.0", "@ledgerhq/logs": "^6.17.0", "events": "^3.3.0" } }, "sha512-BFk4Zr5gfzT40RT6nj0NQTNB25bxWD3QWhdrOA6Mi/CChFTdGomjOuAhWHla2kH50ft8M5UsiiUeHoR+56J69g=="], "@ledgerhq/psbtv2/bitcoinjs-lib": ["bitcoinjs-lib@5.2.0", "", { "dependencies": { "bech32": "^1.1.2", "bip174": "^2.0.1", "bip32": "^2.0.4", "bip66": "^1.1.0", "bitcoin-ops": "^1.4.0", "bs58check": "^2.0.0", "create-hash": "^1.1.0", "create-hmac": "^1.1.3", "merkle-lib": "^2.0.10", "pushdata-bitcoin": "^1.0.1", "randombytes": "^2.0.1", "tiny-secp256k1": "^1.1.1", "typeforce": "^1.11.3", "varuint-bitcoin": "^1.0.4", "wif": "^2.0.1" } }, "sha512-5DcLxGUDejgNBYcieMIUfjORtUeNWl828VWLHJGVKZCb4zIS1oOySTUr0LGmcqJBQgTBz3bGbRQla4FgrdQEIQ=="], @@ -2524,26 +2927,14 @@ "@manypkg/find-root/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], + "@manypkg/find-root/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "@manypkg/find-root/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], "@manypkg/get-packages/@changesets/types": ["@changesets/types@4.1.0", "", {}, "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw=="], "@manypkg/get-packages/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], - "@motionone/animation/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/dom/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/easing/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/generators/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/svelte/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/utils/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@motionone/vue/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@mysten/bcs/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], "@mysten/sui/@noble/curves": ["@noble/curves@1.9.4", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-2bKONnuM53lINoDrSmK8qP8W271ms7pygDhZt4SiLOoLwBtoHqeCFi6RG42V8zd3mLHuJFhU/Bmaqo4nX0/kBw=="], @@ -2556,16 +2947,24 @@ "@mysten/sui/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], - "@mysten/sui/valibot": ["valibot@0.36.0", "", {}, "sha512-CjF1XN4sUce8sBK9TixrDqFM7RwNkuXdJu174/AwmQUB62QbCQADg5lLe8ldBalFgtj1uKj+pKwDJiNo4Mn+eQ=="], - "@mysten/utils/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@near-js/accounts/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@near-js/accounts/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], + "@near-js/accounts/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@near-js/crypto/@near-js/types": ["@near-js/types@2.5.0", "", {}, "sha512-U0HgAnRwN/XKJ1O4Htac+G5bvkMalBJ8i/kwAPJpoOI1MUtP9dhbCG4GBErADCpczukhrAWlDBHHdfhPnhgyzQ=="], + + "@near-js/crypto/@near-js/utils": ["@near-js/utils@2.5.0", "", { "dependencies": { "@near-js/types": "2.5.0", "@scure/base": "^1.2.4", "depd": "2.0.0", "mustache": "4.0.0" } }, "sha512-hifdeZVzV9TFcgLNekRVVnB6q7zxdCQPmC9cybT1SjfeiIP/5jPabOZXGWNJPSloRcrTMluCTtaWinIw1HXanQ=="], + "@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], "@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + "@near-js/keystores/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + "@near-js/keystores-browser/@near-js/crypto": ["@near-js/crypto@1.2.1", "", { "dependencies": { "@near-js/types": "0.0.4", "@near-js/utils": "0.1.0", "@noble/curves": "1.2.0", "bn.js": "5.2.1", "borsh": "1.0.0", "randombytes": "2.1.0" } }, "sha512-iJOHaGKvdudYfR8nEtRhGlgcTEHeVmxMoT0JVXmuP3peG96v/sSnA03CE6MZBeCC8txKAQOffagxE7oU6hJp9g=="], "@near-js/keystores-browser/@near-js/keystores": ["@near-js/keystores@0.0.9", "", { "dependencies": { "@near-js/crypto": "1.2.1", "@near-js/types": "0.0.4" } }, "sha512-j8ySgVEcm2Gg6zxkSdadNtPlIqhJZdPGfWWM3tPtEoowNS9snhwZn5NRFPrgmX0+MzpF7E091CRcY90MvRVhsg=="], @@ -2574,10 +2973,20 @@ "@near-js/keystores-node/@near-js/keystores": ["@near-js/keystores@0.0.9", "", { "dependencies": { "@near-js/crypto": "1.2.1", "@near-js/types": "0.0.4" } }, "sha512-j8ySgVEcm2Gg6zxkSdadNtPlIqhJZdPGfWWM3tPtEoowNS9snhwZn5NRFPrgmX0+MzpF7E091CRcY90MvRVhsg=="], - "@near-js/providers/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "@near-js/providers/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@near-js/providers/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], + + "@near-js/signers/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@near-js/signers/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], "@near-js/signers/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@near-js/transactions/@near-js/types": ["@near-js/types@2.5.0", "", {}, "sha512-U0HgAnRwN/XKJ1O4Htac+G5bvkMalBJ8i/kwAPJpoOI1MUtP9dhbCG4GBErADCpczukhrAWlDBHHdfhPnhgyzQ=="], + + "@near-js/transactions/@near-js/utils": ["@near-js/utils@2.5.0", "", { "dependencies": { "@near-js/types": "2.5.0", "@scure/base": "^1.2.4", "depd": "2.0.0", "mustache": "4.0.0" } }, "sha512-hifdeZVzV9TFcgLNekRVVnB6q7zxdCQPmC9cybT1SjfeiIP/5jPabOZXGWNJPSloRcrTMluCTtaWinIw1HXanQ=="], + "@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@near-js/utils/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], @@ -2598,6 +3007,10 @@ "@near-js/wallet-account/bn.js": ["bn.js@5.2.1", "", {}, "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="], + "@near-wallet-selector/core/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@near-wallet-selector/core/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], + "@near-wallet-selector/core/borsh": ["borsh@2.0.0", "", {}, "sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg=="], "@near-wallet-selector/core/rxjs": ["rxjs@7.8.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg=="], @@ -2614,124 +3027,62 @@ "@polkadot/api/@polkadot/util-crypto": ["@polkadot/util-crypto@13.5.9", "", { "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@polkadot/networks": "13.5.9", "@polkadot/util": "13.5.9", "@polkadot/wasm-crypto": "^7.5.3", "@polkadot/wasm-util": "^7.5.3", "@polkadot/x-bigint": "13.5.9", "@polkadot/x-randomvalues": "13.5.9", "@scure/base": "^1.1.7", "tslib": "^2.8.0" } }, "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg=="], - "@polkadot/api/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/api-augment/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/api-augment/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/api-base/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/api-base/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/api-derive/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], "@polkadot/api-derive/@polkadot/util-crypto": ["@polkadot/util-crypto@13.5.9", "", { "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@polkadot/networks": "13.5.9", "@polkadot/util": "13.5.9", "@polkadot/wasm-crypto": "^7.5.3", "@polkadot/wasm-util": "^7.5.3", "@polkadot/x-bigint": "13.5.9", "@polkadot/x-randomvalues": "13.5.9", "@scure/base": "^1.1.7", "tslib": "^2.8.0" } }, "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg=="], - "@polkadot/api-derive/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/keyring/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/networks/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/rpc-augment/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/rpc-augment/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/rpc-core/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/rpc-core/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/rpc-provider/@polkadot/keyring": ["@polkadot/keyring@13.5.9", "", { "dependencies": { "@polkadot/util": "13.5.9", "@polkadot/util-crypto": "13.5.9", "tslib": "^2.8.0" } }, "sha512-bMCpHDN7U8ytxawjBZ89/he5s3AmEZuOdkM/ABcorh/flXNPfyghjFK27Gy4OKoFxX52yJ2sTHR4NxM87GuFXQ=="], "@polkadot/rpc-provider/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], "@polkadot/rpc-provider/@polkadot/util-crypto": ["@polkadot/util-crypto@13.5.9", "", { "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@polkadot/networks": "13.5.9", "@polkadot/util": "13.5.9", "@polkadot/wasm-crypto": "^7.5.3", "@polkadot/wasm-util": "^7.5.3", "@polkadot/x-bigint": "13.5.9", "@polkadot/x-randomvalues": "13.5.9", "@scure/base": "^1.1.7", "tslib": "^2.8.0" } }, "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg=="], - "@polkadot/rpc-provider/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types/@polkadot/keyring": ["@polkadot/keyring@13.5.9", "", { "dependencies": { "@polkadot/util": "13.5.9", "@polkadot/util-crypto": "13.5.9", "tslib": "^2.8.0" } }, "sha512-bMCpHDN7U8ytxawjBZ89/he5s3AmEZuOdkM/ABcorh/flXNPfyghjFK27Gy4OKoFxX52yJ2sTHR4NxM87GuFXQ=="], "@polkadot/types/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], "@polkadot/types/@polkadot/util-crypto": ["@polkadot/util-crypto@13.5.9", "", { "dependencies": { "@noble/curves": "^1.3.0", "@noble/hashes": "^1.3.3", "@polkadot/networks": "13.5.9", "@polkadot/util": "13.5.9", "@polkadot/wasm-crypto": "^7.5.3", "@polkadot/wasm-util": "^7.5.3", "@polkadot/x-bigint": "13.5.9", "@polkadot/x-randomvalues": "13.5.9", "@scure/base": "^1.1.7", "tslib": "^2.8.0" } }, "sha512-foUesMhxkTk8CZ0/XEcfvHk6I0O+aICqqVJllhOpyp/ZVnrTBKBf59T6RpsXx2pCtBlMsLRvg/6Mw7RND1HqDg=="], - "@polkadot/types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types-augment/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/types-augment/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types-codec/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], "@polkadot/types-codec/@polkadot/x-bigint": ["@polkadot/x-bigint@13.5.9", "", { "dependencies": { "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" } }, "sha512-JVW6vw3e8fkcRyN9eoc6JIl63MRxNQCP/tuLdHWZts1tcAYao0hpWUzteqJY93AgvmQ91KPsC1Kf3iuuZCi74g=="], - "@polkadot/types-codec/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types-create/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/types-create/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types-known/@polkadot/networks": ["@polkadot/networks@13.5.9", "", { "dependencies": { "@polkadot/util": "13.5.9", "@substrate/ss58-registry": "^1.51.0", "tslib": "^2.8.0" } }, "sha512-nmKUKJjiLgcih0MkdlJNMnhEYdwEml2rv/h59ll2+rAvpsVWMTLCb6Cq6q7UC44+8kiWK2UUJMkFU+3PFFxndA=="], "@polkadot/types-known/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/types-known/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/types-support/@polkadot/util": ["@polkadot/util@13.5.9", "", { "dependencies": { "@polkadot/x-bigint": "13.5.9", "@polkadot/x-global": "13.5.9", "@polkadot/x-textdecoder": "13.5.9", "@polkadot/x-textencoder": "13.5.9", "@types/bn.js": "^5.1.6", "bn.js": "^5.2.1", "tslib": "^2.8.0" } }, "sha512-pIK3XYXo7DKeFRkEBNYhf3GbCHg6dKQisSvdzZwuyzA6m7YxQq4DFw4IE464ve4Z7WsJFt3a6C9uII36hl9EWw=="], - "@polkadot/types-support/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/util/@polkadot/x-global": ["@polkadot/x-global@13.5.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw=="], - "@polkadot/util/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/util-crypto/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@polkadot/util-crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], "@polkadot/util-crypto/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], - "@polkadot/util-crypto/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-bridge/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-crypto/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-crypto-asmjs/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-crypto-init/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-crypto-wasm/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/wasm-util/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/x-bigint/@polkadot/x-global": ["@polkadot/x-global@13.5.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw=="], - "@polkadot/x-bigint/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/x-fetch/node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], - "@polkadot/x-fetch/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/x-global/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/x-randomvalues/@polkadot/x-global": ["@polkadot/x-global@13.5.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw=="], - "@polkadot/x-randomvalues/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/x-textdecoder/@polkadot/x-global": ["@polkadot/x-global@13.5.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw=="], - "@polkadot/x-textdecoder/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@polkadot/x-textencoder/@polkadot/x-global": ["@polkadot/x-global@13.5.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw=="], - "@polkadot/x-textencoder/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/x-ws/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "@polkadot/x-ws/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - "@radix-ui/react-alert-dialog/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], @@ -2752,12 +3103,26 @@ "@radixdlt/radix-dapp-toolkit/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], + "@radixdlt/radix-dapp-toolkit/valibot": ["valibot@0.42.1", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw=="], + "@reduxjs/toolkit/immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="], + "@rollup/plugin-inject/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + "@scure/starknet/@noble/curves": ["@noble/curves@1.7.0", "", { "dependencies": { "@noble/hashes": "1.6.0" } }, "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw=="], "@scure/starknet/@noble/hashes": ["@noble/hashes@1.6.1", "", {}, "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w=="], + "@sentry/bundler-plugin-core/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + + "@sentry/bundler-plugin-core/magic-string": ["magic-string@0.30.8", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ=="], + + "@sentry/cli/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "@sentry/cli/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "@solana/accounts/@solana/codecs-strings": ["@solana/codecs-strings@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": ">=5.3.3" } }, "sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug=="], "@solana/addresses/@solana/codecs-strings": ["@solana/codecs-strings@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": ">=5.3.3" } }, "sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug=="], @@ -2778,6 +3143,10 @@ "@solana/codecs-strings/@solana/errors": ["@solana/errors@2.0.0-rc.1", "", { "dependencies": { "chalk": "^5.3.0", "commander": "^12.1.0" }, "peerDependencies": { "typescript": ">=5" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ=="], + "@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "@solana/errors/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "@solana/keys/@solana/codecs-strings": ["@solana/codecs-strings@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": ">=5.3.3" } }, "sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug=="], "@solana/kit/@solana/codecs": ["@solana/codecs@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-data-structures": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/codecs-strings": "2.3.0", "@solana/options": "2.3.0" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g=="], @@ -2790,8 +3159,6 @@ "@solana/rpc-api/@solana/codecs-strings": ["@solana/codecs-strings@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": ">=5.3.3" } }, "sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug=="], - "@solana/rpc-subscriptions-channel-websocket/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - "@solana/rpc-transport-http/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "@solana/rpc-types/@solana/codecs-strings": ["@solana/codecs-strings@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "fastestsmallesttextencoderdecoder": "^1.0.22", "typescript": ">=5.3.3" } }, "sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug=="], @@ -2814,6 +3181,8 @@ "@solana/web3.js/bs58": ["bs58@4.0.1", "", { "dependencies": { "base-x": "^3.0.2" } }, "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw=="], + "@solana/web3.js/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "@stacks/common/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="], "@stacks/network/cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], @@ -2822,11 +3191,9 @@ "@stacks/transactions/@noble/secp256k1": ["@noble/secp256k1@1.7.1", "", {}, "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw=="], - "@starknet-io/get-starknet-wallet-standard/ox": ["ox@0.4.4", "", { "dependencies": { "@adraffy/ens-normalize": "^1.10.1", "@noble/curves": "^1.6.0", "@noble/hashes": "^1.5.0", "@scure/bip32": "^1.5.0", "@scure/bip39": "^1.4.0", "abitype": "^1.0.6", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-oJPEeCDs9iNiPs6J0rTx+Y0KGeCGyCAA3zo94yZhm8G5WpOxrwUtn2Ie/Y8IyARSqqY/j9JTKA3Fc1xs1DvFnw=="], - "@stellar/stellar-base/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], - "@stellar/stellar-sdk/axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + "@stellar/stellar-sdk/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], "@stricahq/typhonjs/@stricahq/cbors": ["@stricahq/cbors@1.0.2", "", { "dependencies": { "bignumber.js": "^9.0.2", "buffer": "^6.0.3" } }, "sha512-6ePsEiq7EGHA5IiPn9poA7sF5iXPqt30kKw3pjR/BhP7S+XHZNu/OPumESWnVl4AM+IEYC2x9eL+4qRPsTPVww=="], @@ -2834,27 +3201,17 @@ "@swapkit/core/cosmjs-types": ["cosmjs-types@0.11.0", "", {}, "sha512-kDSkgHpRTrg1413jCNehT3P21+EBxZWFMBr9JEzVfmPiNdtuwAoLAkCYo7c7i/pTakAwyHsXbxOg8kkD+AN33w=="], - "@swapkit/toolboxes/@cosmjs/crypto": ["@cosmjs/crypto@0.39.0", "", { "dependencies": { "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/utils": "^0.39.0", "@noble/ciphers": "^2.1.1", "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/bip39": "^2.0.1" } }, "sha512-ATRhSXN8w3fvUkj9xzLHwvzylDvvn4f3cC1CQwhQc2OxyzpEEFACS3wHS6iwdJJS99acV8dq+oVOYflUqI0brQ=="], - - "@swapkit/toolboxes/@stricahq/typhonjs": ["@stricahq/typhonjs@3.1.0", "", { "dependencies": { "@stricahq/cbors": "1.0.2", "bech32": "^2.0.0", "bignumber.js": "^9.0.1", "blakejs": "^1.2.1", "bs58": "^5.0.0", "buffer": "^6.0.3", "lodash": "^4.17.21" } }, "sha512-Eaw0qqNIz+6sA9zD/9pFCdQ+gNbCv8PKFMhXu4Vq6KSR1XsH40jNPFkrqgKaq8q+gbO569U1+tu41dHk40JNbw=="], + "@swapkit/plugins/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], - "@swapkit/toolboxes/cosmjs-types": ["cosmjs-types@0.11.0", "", {}, "sha512-kDSkgHpRTrg1413jCNehT3P21+EBxZWFMBr9JEzVfmPiNdtuwAoLAkCYo7c7i/pTakAwyHsXbxOg8kkD+AN33w=="], - - "@swapkit/ui/@cosmjs/amino": ["@cosmjs/amino@0.39.0", "", { "dependencies": { "@cosmjs/crypto": "^0.39.0", "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/utils": "^0.39.0" } }, "sha512-56WqsZ4xbdJE4KWJTPbw7hUzePflRxRLuxoBlUsa8qIiFumpzZRW0Ycb7IloEF8wAmdgsdfrG1hSJSBlqdFE7A=="], - - "@swapkit/ui/@cosmjs/crypto": ["@cosmjs/crypto@0.39.0", "", { "dependencies": { "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/utils": "^0.39.0", "@noble/ciphers": "^2.1.1", "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/bip39": "^2.0.1" } }, "sha512-ATRhSXN8w3fvUkj9xzLHwvzylDvvn4f3cC1CQwhQc2OxyzpEEFACS3wHS6iwdJJS99acV8dq+oVOYflUqI0brQ=="], - - "@swapkit/ui/@cosmjs/proto-signing": ["@cosmjs/proto-signing@0.39.0", "", { "dependencies": { "@cosmjs/amino": "^0.39.0", "@cosmjs/crypto": "^0.39.0", "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/utils": "^0.39.0", "cosmjs-types": "^0.11.0" } }, "sha512-jthQ2PA092fvrbFaZRRKuHV7awOsayjDLIBACaGIblFj9yJCcrvhFp+8YV87ia990DjKmWJc3sstHvQZ3yK/EQ=="], - - "@swapkit/ui/@cosmjs/stargate": ["@cosmjs/stargate@0.39.0", "", { "dependencies": { "@cosmjs/amino": "^0.39.0", "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/proto-signing": "^0.39.0", "@cosmjs/stream": "^0.39.0", "@cosmjs/tendermint-rpc": "^0.39.0", "@cosmjs/utils": "^0.39.0", "cosmjs-types": "^0.11.0" } }, "sha512-dQtucU9czF2NUUbEKs19PMfv+EusDFKWHMVK6Hinytmpq9sdk5JUIln+g/8k+UjKcV4HPv6S0AywbhE+tl84kQ=="], + "@swapkit/toolboxes/@cosmjs/crypto": ["@cosmjs/crypto@0.39.0", "", { "dependencies": { "@cosmjs/encoding": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/utils": "^0.39.0", "@noble/ciphers": "^2.1.1", "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/bip39": "^2.0.1" } }, "sha512-ATRhSXN8w3fvUkj9xzLHwvzylDvvn4f3cC1CQwhQc2OxyzpEEFACS3wHS6iwdJJS99acV8dq+oVOYflUqI0brQ=="], - "@swapkit/ui/@stricahq/typhonjs": ["@stricahq/typhonjs@3.1.0", "", { "dependencies": { "@stricahq/cbors": "1.0.2", "bech32": "^2.0.0", "bignumber.js": "^9.0.1", "blakejs": "^1.2.1", "bs58": "^5.0.0", "buffer": "^6.0.3", "lodash": "^4.17.21" } }, "sha512-Eaw0qqNIz+6sA9zD/9pFCdQ+gNbCv8PKFMhXu4Vq6KSR1XsH40jNPFkrqgKaq8q+gbO569U1+tu41dHk40JNbw=="], + "@swapkit/toolboxes/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], - "@swapkit/ui/cosmjs-types": ["cosmjs-types@0.11.0", "", {}, "sha512-kDSkgHpRTrg1413jCNehT3P21+EBxZWFMBr9JEzVfmPiNdtuwAoLAkCYo7c7i/pTakAwyHsXbxOg8kkD+AN33w=="], + "@swapkit/toolboxes/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], - "@swapkit/ui/react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="], + "@swapkit/toolboxes/@stricahq/typhonjs": ["@stricahq/typhonjs@3.1.0", "", { "dependencies": { "@stricahq/cbors": "1.0.2", "bech32": "^2.0.0", "bignumber.js": "^9.0.1", "blakejs": "^1.2.1", "bs58": "^5.0.0", "buffer": "^6.0.3", "lodash": "^4.17.21" } }, "sha512-Eaw0qqNIz+6sA9zD/9pFCdQ+gNbCv8PKFMhXu4Vq6KSR1XsH40jNPFkrqgKaq8q+gbO569U1+tu41dHk40JNbw=="], - "@swapkit/ui/react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="], + "@swapkit/toolboxes/cosmjs-types": ["cosmjs-types@0.11.0", "", {}, "sha512-kDSkgHpRTrg1413jCNehT3P21+EBxZWFMBr9JEzVfmPiNdtuwAoLAkCYo7c7i/pTakAwyHsXbxOg8kkD+AN33w=="], "@swapkit/wallet-extensions/@cosmjs/amino": ["@cosmjs/amino@0.37.1", "", { "dependencies": { "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1" } }, "sha512-z3QSfw2S2kGbi5XBahOdAIu2Nnb7XiLgTOphZQoOJXJcTQemAG/wYHLJD9TcQ48SX+eDTJ4i7XRyJaIdg0ClcA=="], @@ -2862,19 +3219,23 @@ "@swapkit/wallet-extensions/@cosmjs/stargate": ["@cosmjs/stargate@0.37.1", "", { "dependencies": { "@cosmjs/amino": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/proto-signing": "^0.37.1", "@cosmjs/stream": "^0.37.1", "@cosmjs/tendermint-rpc": "^0.37.1", "@cosmjs/utils": "^0.37.1", "cosmjs-types": "^0.10.1" } }, "sha512-nQgaJB7A81cRYtmDrcIySq8hbd+QLXJTGFEs6R1xMdxascaABX0x86nS44ALk+EZojQQRnwupOsw1dKLlQmIFg=="], + "@swapkit/wallet-extensions/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@swapkit/wallet-extensions/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], + "@swapkit/wallet-hardware/@cosmjs/amino": ["@cosmjs/amino@0.37.1", "", { "dependencies": { "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1" } }, "sha512-z3QSfw2S2kGbi5XBahOdAIu2Nnb7XiLgTOphZQoOJXJcTQemAG/wYHLJD9TcQ48SX+eDTJ4i7XRyJaIdg0ClcA=="], "@swapkit/wallet-hardware/@cosmjs/proto-signing": ["@cosmjs/proto-signing@0.37.1", "", { "dependencies": { "@cosmjs/amino": "^0.37.1", "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "cosmjs-types": "^0.10.1" } }, "sha512-cCUfejHOfjx6L/noF9QnXIy4dKoTKl56NFIqz2cizx+kZKszdL0yOtQlu0dD9nR+uMafRHU7aok6v5HH4RZIDw=="], - "@swapkit/wallets/@cosmjs/amino": ["@cosmjs/amino@0.37.1", "", { "dependencies": { "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1" } }, "sha512-z3QSfw2S2kGbi5XBahOdAIu2Nnb7XiLgTOphZQoOJXJcTQemAG/wYHLJD9TcQ48SX+eDTJ4i7XRyJaIdg0ClcA=="], + "@swapkit/wallet-hardware/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], - "@swapkit/wallets/@cosmjs/proto-signing": ["@cosmjs/proto-signing@0.37.1", "", { "dependencies": { "@cosmjs/amino": "^0.37.1", "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "cosmjs-types": "^0.10.1" } }, "sha512-cCUfejHOfjx6L/noF9QnXIy4dKoTKl56NFIqz2cizx+kZKszdL0yOtQlu0dD9nR+uMafRHU7aok6v5HH4RZIDw=="], + "@swapkit/wallet-hardware/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], - "@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@swapkit/wallets/@cosmjs/amino": ["@cosmjs/amino@0.37.1", "", { "dependencies": { "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1" } }, "sha512-z3QSfw2S2kGbi5XBahOdAIu2Nnb7XiLgTOphZQoOJXJcTQemAG/wYHLJD9TcQ48SX+eDTJ4i7XRyJaIdg0ClcA=="], - "@ton/ton/axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + "@swapkit/wallets/@cosmjs/proto-signing": ["@cosmjs/proto-signing@0.37.1", "", { "dependencies": { "@cosmjs/amino": "^0.37.1", "@cosmjs/crypto": "^0.37.1", "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "cosmjs-types": "^0.10.1" } }, "sha512-cCUfejHOfjx6L/noF9QnXIy4dKoTKl56NFIqz2cizx+kZKszdL0yOtQlu0dD9nR+uMafRHU7aok6v5HH4RZIDw=="], - "@ton/ton/dataloader": ["dataloader@2.2.3", "", {}, "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA=="], + "@swapkit/wallets/@near-js/transactions": ["@near-js/transactions@2.5.1", "", { "dependencies": { "@near-js/crypto": "2.5.1", "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/hashes": "1.7.1", "borsh": "1.0.0" } }, "sha512-0svK5K6VqOciSIn9mxreyS0uQf8T1UZc71JBA6yrstpHJhltz/dvNUMY0FV+xHx3H/KAdvCMjX0VLEpyi08yWQ=="], "@ton/ton/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -2914,8 +3275,6 @@ "@trezor/utxo-lib/wif": ["wif@5.0.0", "", { "dependencies": { "bs58check": "^4.0.0" } }, "sha512-iFzrC/9ne740qFbNjTZ2FciSRJlHIXoxqk/Y5EnE08QOXu1WjJyCCswwDTYbohAOEnlCtLaAAQBhyaLRFh2hMA=="], - "@trezor/websocket-client/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - "@types/bn.js/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], "@types/cacheable-request/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], @@ -2930,6 +3289,10 @@ "@types/ws/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + "@walletconnect/environment/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], "@walletconnect/events/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -2966,14 +3329,14 @@ "@xrplf/isomorphic/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + "@xrplf/isomorphic/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], + "abi-wan-kanabi/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], - "abi-wan-kanabi/yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + "ajv-formats/ajv": ["ajv@8.11.2", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "asn1.js/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], "bip32/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -2992,6 +3355,8 @@ "browserify-zlib/pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], + "browserslist/caniuse-lite": ["caniuse-lite@1.0.30001788", "", {}, "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ=="], + "bs58check/bs58": ["bs58@4.0.1", "", { "dependencies": { "base-x": "^3.0.2" } }, "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw=="], "bun-types/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], @@ -3004,6 +3369,8 @@ "create-ecdh/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], + "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "diffie-hellman/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], "elliptic/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], @@ -3014,17 +3381,25 @@ "ethers/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], + "ethers/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], + + "ethers/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], - "fetch-ponyfill/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "glob/minimatch": ["minimatch@8.0.7", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg=="], "http-errors/depd": ["depd@1.1.2", "", {}, "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="], "http-errors/inherits": ["inherits@2.0.3", "", {}, "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="], + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "isomorphic-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "jayson/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], - "jayson/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "jayson/@types/ws": ["@types/ws@7.4.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww=="], "jayson/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], @@ -3060,19 +3435,19 @@ "near-api-js/@noble/curves": ["@noble/curves@1.2.0", "", { "dependencies": { "@noble/hashes": "1.3.2" } }, "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw=="], + "near-api-js/ajv": ["ajv@8.11.2", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg=="], + "near-api-js/bn.js": ["bn.js@5.2.1", "", {}, "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="], "near-api-js/near-abi": ["near-abi@0.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-RVDI8O+KVxRpC3KycJ1bpfVj9Zv+xvq9PlW1yIFl46GhrnLw83/72HqHGjGDjQ8DtltkcpSjY9X3YIGZ+1QyzQ=="], - "near-api-js/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], - "near-seed-phrase/bs58": ["bs58@4.0.1", "", { "dependencies": { "base-x": "^3.0.2" } }, "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw=="], "node-stdlib-browser/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="], - "ox/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="], + "ox/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -3082,19 +3457,15 @@ "ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], - "pino/pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], + "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "pkg-dir/find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + "path-scurry/minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - "protobufjs/long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], + "pino/pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], "public-encrypt/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="], - "react-remove-scroll/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "react-remove-scroll-bar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "react-style-singleton/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], "read-cache/pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], @@ -3108,13 +3479,11 @@ "ripple-keypairs/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], - "rpc-websockets/@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], - "rpc-websockets/uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], - "rpc-websockets/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "rxjs/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], - "smoldot/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "socks-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], "starknet/@noble/curves": ["@noble/curves@1.7.0", "", { "dependencies": { "@noble/hashes": "1.6.0" } }, "sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw=="], @@ -3134,12 +3503,6 @@ "usb/node-addon-api": ["node-addon-api@8.7.0", "", {}, "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA=="], - "use-callback-ref/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "use-sidecar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "use-sync-external-store/react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="], - "viem/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="], "viem/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -3148,7 +3511,9 @@ "viem/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], - "viem/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "viem/ox": ["ox@0.14.17", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@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", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-jOzNb2Wlfzsr8z/GoCtd1bf6OSRuWuysvbhnHGD+7fV1WRbcBR6B0RYoe3xWnUedF7zp4l5APmS7CzAhUok/lA=="], + + "vite-plugin-cjs-interop/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "websocket/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -3158,6 +3523,10 @@ "xrpl/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "xumm-sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "@aptos-labs/aptos-client/axios/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "@aptos-labs/ts-sdk/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], "@aptos-labs/ts-sdk/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], @@ -3178,14 +3547,20 @@ "@keplr-wallet/types/starknet/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@ledgerhq/domain-service/axios/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "@ledgerhq/domain-service/react-dom/scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="], + "@ledgerhq/evm-tools/axios/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "@ledgerhq/hw-app-btc/bitcoinjs-lib/bech32": ["bech32@1.1.4", "", {}, "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="], "@ledgerhq/hw-app-btc/bitcoinjs-lib/bip32": ["bip32@2.0.6", "", { "dependencies": { "@types/node": "10.12.18", "bs58check": "^2.1.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "tiny-secp256k1": "^1.1.3", "typeforce": "^1.11.5", "wif": "^2.0.6" } }, "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA=="], "@ledgerhq/hw-app-btc/bs58/base-x": ["base-x@3.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA=="], + "@ledgerhq/hw-app-eth/axios/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], + "@ledgerhq/hw-transport-mocker/@ledgerhq/hw-transport/@ledgerhq/devices": ["@ledgerhq/devices@8.14.0", "", { "dependencies": { "@ledgerhq/errors": "^6.33.0", "@ledgerhq/logs": "^6.17.0", "rxjs": "7.8.2", "semver": "7.7.3" } }, "sha512-eMGOaagkMJrqGtqemYNraPg38FA0I/UUEPrbrC+vOZu1qeoG+Sek3gjuJih6rMK4efUfcI4Zs19w/Hv/58fwkQ=="], "@ledgerhq/hw-transport-mocker/@ledgerhq/hw-transport/@ledgerhq/errors": ["@ledgerhq/errors@6.33.0", "", {}, "sha512-9iMdjB0Hfxfd8HGMVM0TDPfxBXhJ4MtGKyFlm8aveSHSXjcTjGtCkcnk4OUZ6ZHopBb69BFR+HC2N/ob9xuNgA=="], @@ -3194,8 +3569,16 @@ "@ledgerhq/psbtv2/bitcoinjs-lib/bip32": ["bip32@2.0.6", "", { "dependencies": { "@types/node": "10.12.18", "bs58check": "^2.1.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "tiny-secp256k1": "^1.1.3", "typeforce": "^1.11.5", "wif": "^2.0.6" } }, "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA=="], + "@manypkg/find-root/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "@mysten/sui/@scure/bip32/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], + "@near-js/accounts/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@near-js/accounts/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@near-js/crypto/@near-js/utils/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@near-js/keystores-browser/@near-js/crypto/@near-js/types": ["@near-js/types@0.0.4", "", { "dependencies": { "bn.js": "5.2.1" } }, "sha512-8TTMbLMnmyG06R5YKWuS/qFG1tOA3/9lX4NgBqQPsvaWmDsa+D+QwOkrEHDegped0ZHQwcjAXjKML1S1TyGYKg=="], @@ -3218,8 +3601,26 @@ "@near-js/keystores-node/@near-js/keystores/@near-js/types": ["@near-js/types@0.0.4", "", { "dependencies": { "bn.js": "5.2.1" } }, "sha512-8TTMbLMnmyG06R5YKWuS/qFG1tOA3/9lX4NgBqQPsvaWmDsa+D+QwOkrEHDegped0ZHQwcjAXjKML1S1TyGYKg=="], + "@near-js/keystores/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@near-js/keystores/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@near-js/providers/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@near-js/providers/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@near-js/providers/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@near-js/signers/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@near-js/signers/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@near-js/transactions/@near-js/utils/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@near-js/wallet-account/@near-js/accounts/@near-js/providers": ["@near-js/providers@0.1.1", "", { "dependencies": { "@near-js/transactions": "1.1.2", "@near-js/types": "0.0.4", "@near-js/utils": "0.1.0", "bn.js": "5.2.1", "borsh": "1.0.0", "http-errors": "1.7.2" }, "optionalDependencies": { "node-fetch": "2.6.7" } }, "sha512-0M/Vz2Ac34ShKVoe2ftVJ5Qg4eSbEqNXDbCDOdVj/2qbLWZa7Wpe+me5ei4TMY2ZhGdawhgJUPrYwdJzOCyf8w=="], + "@near-js/wallet-account/@near-js/accounts/ajv": ["ajv@8.11.2", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg=="], + "@near-js/wallet-account/@near-js/accounts/near-abi": ["near-abi@0.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.11" } }, "sha512-RVDI8O+KVxRpC3KycJ1bpfVj9Zv+xvq9PlW1yIFl46GhrnLw83/72HqHGjGDjQ8DtltkcpSjY9X3YIGZ+1QyzQ=="], "@near-js/wallet-account/@near-js/crypto/@noble/curves": ["@noble/curves@1.2.0", "", { "dependencies": { "@noble/hashes": "1.3.2" } }, "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw=="], @@ -3230,6 +3631,18 @@ "@near-js/wallet-account/@near-js/utils/bs58": ["bs58@4.0.0", "", { "dependencies": { "base-x": "^2.0.1" } }, "sha512-/jcGuUuSebyxwLLfKrbKnCJttxRf9PM51EnHTwmFKBxl4z1SGkoAhrfd6uZKE0dcjQTfm6XzTP8DPr1tzE4KIw=="], + "@near-wallet-selector/core/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@near-wallet-selector/core/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@near-wallet-selector/core/@near-js/crypto/borsh": ["borsh@1.0.0", "", {}, "sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ=="], + + "@near-wallet-selector/core/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@near-wallet-selector/core/@near-js/transactions/borsh": ["borsh@1.0.0", "", {}, "sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ=="], + + "@near-wallet-selector/core/rxjs/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], + "@polkadot/api-augment/@polkadot/util/@polkadot/x-bigint": ["@polkadot/x-bigint@13.5.9", "", { "dependencies": { "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" } }, "sha512-JVW6vw3e8fkcRyN9eoc6JIl63MRxNQCP/tuLdHWZts1tcAYao0hpWUzteqJY93AgvmQ91KPsC1Kf3iuuZCi74g=="], "@polkadot/api-augment/@polkadot/util/@polkadot/x-textdecoder": ["@polkadot/x-textdecoder@13.5.9", "", { "dependencies": { "@polkadot/x-global": "13.5.9", "tslib": "^2.8.0" } }, "sha512-W2HhVNUbC/tuFdzNMbnXAWsIHSg9SC9QWDNmFD3nXdSzlXNgL8NmuiwN2fkYvCQBtp/XSoy0gDLx0C+Fo19cfw=="], @@ -3358,8 +3771,12 @@ "@scure/starknet/@noble/curves/@noble/hashes": ["@noble/hashes@1.6.0", "", {}, "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ=="], + "@solana/codecs-data-structures/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "@solana/codecs-data-structures/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + "@solana/codecs-strings/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "@solana/codecs-strings/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], "@solana/codecs/@solana/codecs-core/@solana/errors": ["@solana/errors@2.0.0-rc.1", "", { "dependencies": { "chalk": "^5.3.0", "commander": "^12.1.0" }, "peerDependencies": { "typescript": ">=5" }, "bin": { "errors": "bin/cli.mjs" } }, "sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ=="], @@ -3372,6 +3789,8 @@ "@solana/kit/@solana/codecs/@solana/options": ["@solana/options@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-data-structures": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/codecs-strings": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw=="], + "@solana/options/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "@solana/options/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], "@solana/sysvars/@solana/codecs/@solana/codecs-data-structures": ["@solana/codecs-data-structures@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/codecs-numbers": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw=="], @@ -3384,24 +3803,16 @@ "@stacks/common/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], - "@starknet-io/get-starknet-wallet-standard/ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="], - - "@starknet-io/get-starknet-wallet-standard/ox/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], - - "@starknet-io/get-starknet-wallet-standard/ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - - "@starknet-io/get-starknet-wallet-standard/ox/@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="], - - "@starknet-io/get-starknet-wallet-standard/ox/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], - - "@starknet-io/get-starknet-wallet-standard/ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + "@stacks/network/cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "@stellar/stellar-base/@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "@stellar/stellar-sdk/axios/proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], - "@swapkit/core/@stricahq/typhonjs/@stricahq/cbors": ["@stricahq/cbors@1.0.2", "", { "dependencies": { "bignumber.js": "^9.0.2", "buffer": "^6.0.3" } }, "sha512-6ePsEiq7EGHA5IiPn9poA7sF5iXPqt30kKw3pjR/BhP7S+XHZNu/OPumESWnVl4AM+IEYC2x9eL+4qRPsTPVww=="], + "@swapkit/plugins/@near-js/transactions/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], + + "@swapkit/plugins/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@swapkit/toolboxes/@cosmjs/crypto/@cosmjs/encoding": ["@cosmjs/encoding@0.39.0", "", { "dependencies": { "@scure/base": "^2.0.0", "base64-js": "^1.3.0", "readonly-date-esm": "^2.0.0" } }, "sha512-+poEaeM8YjGNVtrHLQNWqkhEeDxapjrdpnPCT+JCRh8YNbeHEdftzZLCH5VCBSOtvo7PF0gK1B7sbQbBl6q5pQ=="], "@swapkit/toolboxes/@cosmjs/crypto/@cosmjs/math": ["@cosmjs/math@0.39.0", "", {}, "sha512-FSLy/oDF+BtOP/J60RsjL5W4MCKiCfBjSoeV5xj6qg2g8N884Ue853iuWanjqGkQJwkXCp+JbeK8Mv9j6AaYHw=="], @@ -3410,59 +3821,43 @@ "@swapkit/toolboxes/@cosmjs/crypto/@noble/ciphers": ["@noble/ciphers@2.2.0", "", {}, "sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA=="], - "@swapkit/toolboxes/@stricahq/typhonjs/@stricahq/cbors": ["@stricahq/cbors@1.0.2", "", { "dependencies": { "bignumber.js": "^9.0.2", "buffer": "^6.0.3" } }, "sha512-6ePsEiq7EGHA5IiPn9poA7sF5iXPqt30kKw3pjR/BhP7S+XHZNu/OPumESWnVl4AM+IEYC2x9eL+4qRPsTPVww=="], - - "@swapkit/ui/@cosmjs/amino/@cosmjs/encoding": ["@cosmjs/encoding@0.39.0", "", { "dependencies": { "@scure/base": "^2.0.0", "base64-js": "^1.3.0", "readonly-date-esm": "^2.0.0" } }, "sha512-+poEaeM8YjGNVtrHLQNWqkhEeDxapjrdpnPCT+JCRh8YNbeHEdftzZLCH5VCBSOtvo7PF0gK1B7sbQbBl6q5pQ=="], - - "@swapkit/ui/@cosmjs/amino/@cosmjs/math": ["@cosmjs/math@0.39.0", "", {}, "sha512-FSLy/oDF+BtOP/J60RsjL5W4MCKiCfBjSoeV5xj6qg2g8N884Ue853iuWanjqGkQJwkXCp+JbeK8Mv9j6AaYHw=="], + "@swapkit/toolboxes/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], - "@swapkit/ui/@cosmjs/amino/@cosmjs/utils": ["@cosmjs/utils@0.39.0", "", {}, "sha512-h7fy7Tbcl9v8ABntp8+kqw2VmUus2HbnRJFyzTkM7byRktLtECHYNMsztwyl1rdHkzc8Nc2xs6K/56d7a+75aw=="], + "@swapkit/toolboxes/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "@swapkit/ui/@cosmjs/crypto/@cosmjs/encoding": ["@cosmjs/encoding@0.39.0", "", { "dependencies": { "@scure/base": "^2.0.0", "base64-js": "^1.3.0", "readonly-date-esm": "^2.0.0" } }, "sha512-+poEaeM8YjGNVtrHLQNWqkhEeDxapjrdpnPCT+JCRh8YNbeHEdftzZLCH5VCBSOtvo7PF0gK1B7sbQbBl6q5pQ=="], + "@swapkit/toolboxes/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], - "@swapkit/ui/@cosmjs/crypto/@cosmjs/math": ["@cosmjs/math@0.39.0", "", {}, "sha512-FSLy/oDF+BtOP/J60RsjL5W4MCKiCfBjSoeV5xj6qg2g8N884Ue853iuWanjqGkQJwkXCp+JbeK8Mv9j6AaYHw=="], - - "@swapkit/ui/@cosmjs/crypto/@cosmjs/utils": ["@cosmjs/utils@0.39.0", "", {}, "sha512-h7fy7Tbcl9v8ABntp8+kqw2VmUus2HbnRJFyzTkM7byRktLtECHYNMsztwyl1rdHkzc8Nc2xs6K/56d7a+75aw=="], - - "@swapkit/ui/@cosmjs/crypto/@noble/ciphers": ["@noble/ciphers@2.2.0", "", {}, "sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA=="], - - "@swapkit/ui/@cosmjs/proto-signing/@cosmjs/encoding": ["@cosmjs/encoding@0.39.0", "", { "dependencies": { "@scure/base": "^2.0.0", "base64-js": "^1.3.0", "readonly-date-esm": "^2.0.0" } }, "sha512-+poEaeM8YjGNVtrHLQNWqkhEeDxapjrdpnPCT+JCRh8YNbeHEdftzZLCH5VCBSOtvo7PF0gK1B7sbQbBl6q5pQ=="], - - "@swapkit/ui/@cosmjs/proto-signing/@cosmjs/math": ["@cosmjs/math@0.39.0", "", {}, "sha512-FSLy/oDF+BtOP/J60RsjL5W4MCKiCfBjSoeV5xj6qg2g8N884Ue853iuWanjqGkQJwkXCp+JbeK8Mv9j6AaYHw=="], + "@swapkit/toolboxes/@stricahq/typhonjs/@stricahq/cbors": ["@stricahq/cbors@1.0.2", "", { "dependencies": { "bignumber.js": "^9.0.2", "buffer": "^6.0.3" } }, "sha512-6ePsEiq7EGHA5IiPn9poA7sF5iXPqt30kKw3pjR/BhP7S+XHZNu/OPumESWnVl4AM+IEYC2x9eL+4qRPsTPVww=="], - "@swapkit/ui/@cosmjs/proto-signing/@cosmjs/utils": ["@cosmjs/utils@0.39.0", "", {}, "sha512-h7fy7Tbcl9v8ABntp8+kqw2VmUus2HbnRJFyzTkM7byRktLtECHYNMsztwyl1rdHkzc8Nc2xs6K/56d7a+75aw=="], + "@swapkit/wallet-extensions/@cosmjs/amino/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/encoding": ["@cosmjs/encoding@0.39.0", "", { "dependencies": { "@scure/base": "^2.0.0", "base64-js": "^1.3.0", "readonly-date-esm": "^2.0.0" } }, "sha512-+poEaeM8YjGNVtrHLQNWqkhEeDxapjrdpnPCT+JCRh8YNbeHEdftzZLCH5VCBSOtvo7PF0gK1B7sbQbBl6q5pQ=="], + "@swapkit/wallet-extensions/@cosmjs/proto-signing/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/math": ["@cosmjs/math@0.39.0", "", {}, "sha512-FSLy/oDF+BtOP/J60RsjL5W4MCKiCfBjSoeV5xj6qg2g8N884Ue853iuWanjqGkQJwkXCp+JbeK8Mv9j6AaYHw=="], + "@swapkit/wallet-extensions/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/stream": ["@cosmjs/stream@0.39.0", "", { "dependencies": { "xstream": "^11.14.0" } }, "sha512-h56it+ku5F6nlO94VyVAyz3pQqYsGRJ8v+5Y5erXYlQ0Qmr+rLrlSMCiViFEMK9INRSilAypdI5hKPCzotiqRg=="], + "@swapkit/wallet-extensions/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/tendermint-rpc": ["@cosmjs/tendermint-rpc@0.39.0", "", { "dependencies": { "@cosmjs/crypto": "^0.39.0", "@cosmjs/encoding": "^0.39.0", "@cosmjs/json-rpc": "^0.39.0", "@cosmjs/math": "^0.39.0", "@cosmjs/socket": "^0.39.0", "@cosmjs/stream": "^0.39.0", "@cosmjs/utils": "^0.39.0", "readonly-date-esm": "^2.0.0", "xstream": "^11.14.0" } }, "sha512-KowP/6P6Tx+OnGoimYnxuSBIfhB+vWqWER2pZpEIOHId8ZfcjQ9JS2F+Ah+WmZ9D+bKgn4pJ5ImAS13TeShIEw=="], + "@swapkit/wallet-extensions/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/utils": ["@cosmjs/utils@0.39.0", "", {}, "sha512-h7fy7Tbcl9v8ABntp8+kqw2VmUus2HbnRJFyzTkM7byRktLtECHYNMsztwyl1rdHkzc8Nc2xs6K/56d7a+75aw=="], + "@swapkit/wallet-hardware/@cosmjs/amino/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - "@swapkit/ui/@stricahq/typhonjs/@stricahq/cbors": ["@stricahq/cbors@1.0.2", "", { "dependencies": { "bignumber.js": "^9.0.2", "buffer": "^6.0.3" } }, "sha512-6ePsEiq7EGHA5IiPn9poA7sF5iXPqt30kKw3pjR/BhP7S+XHZNu/OPumESWnVl4AM+IEYC2x9eL+4qRPsTPVww=="], + "@swapkit/wallet-hardware/@cosmjs/proto-signing/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - "@swapkit/ui/react-dom/scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], + "@swapkit/wallet-hardware/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], - "@swapkit/wallet-extensions/@cosmjs/amino/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], + "@swapkit/wallet-hardware/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "@swapkit/wallet-extensions/@cosmjs/proto-signing/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - - "@swapkit/wallet-hardware/@cosmjs/amino/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - - "@swapkit/wallet-hardware/@cosmjs/proto-signing/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], + "@swapkit/wallet-hardware/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@swapkit/wallets/@cosmjs/amino/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], "@swapkit/wallets/@cosmjs/proto-signing/@cosmjs/crypto": ["@cosmjs/crypto@0.37.1", "", { "dependencies": { "@cosmjs/encoding": "^0.37.1", "@cosmjs/math": "^0.37.1", "@cosmjs/utils": "^0.37.1", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "hash-wasm": "^4.12.0" } }, "sha512-CdLOKQVJM422UegKpi4T/xkdNwvLZwJwSC7NyYi7tAyty0NzP67u+vNqar7Ok22ECkKLj6N9uRcIl4g62oZThA=="], - "@ton/ton/axios/proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], + "@swapkit/wallets/@near-js/transactions/@near-js/crypto": ["@near-js/crypto@2.5.1", "", { "dependencies": { "@near-js/types": "2.5.1", "@near-js/utils": "2.5.1", "@noble/curves": "1.8.1", "@noble/hashes": "^1.7.1", "borsh": "1.0.0", "secp256k1": "5.0.1" } }, "sha512-Kb+bbnUrfvuzzed9hpLRpcIlCMOaQlw/7BxlZPCq8DggVaK1m0nKR1DHQs2cV0Q0WSKSk2UrFJho1dxeKL5alg=="], - "@trezor/blockchain-link-utils/@stellar/stellar-sdk/@stellar/stellar-base": ["@stellar/stellar-base@14.1.0", "", { "dependencies": { "@noble/curves": "^1.9.6", "@stellar/js-xdr": "^3.1.2", "base32.js": "^0.1.0", "bignumber.js": "^9.3.1", "buffer": "^6.0.3", "sha.js": "^2.4.12" } }, "sha512-A8kFli6QGy22SRF45IjgPAJfUNGjnI+R7g4DF5NZYVsD1kGf7B4ITyc4OPclLV9tqNI4/lXxafGEw0JEUbHixw=="], + "@swapkit/wallets/@near-js/transactions/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], - "@trezor/blockchain-link-utils/@stellar/stellar-sdk/axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + "@trezor/blockchain-link-utils/@stellar/stellar-sdk/@stellar/stellar-base": ["@stellar/stellar-base@14.1.0", "", { "dependencies": { "@noble/curves": "^1.9.6", "@stellar/js-xdr": "^3.1.2", "base32.js": "^0.1.0", "bignumber.js": "^9.3.1", "buffer": "^6.0.3", "sha.js": "^2.4.12" } }, "sha512-A8kFli6QGy22SRF45IjgPAJfUNGjnI+R7g4DF5NZYVsD1kGf7B4ITyc4OPclLV9tqNI4/lXxafGEw0JEUbHixw=="], "@trezor/blockchain-link-utils/@trezor/protobuf/long": ["long@5.2.5", "", {}, "sha512-e0r9YBBgNCq1D1o5Dp8FMH0N5hsFtXDBiVa0qoJPHpakvZkmDKPRoGffZJII/XsHvj9An9blm+cRJ01yQqU+Dw=="], @@ -3476,8 +3871,6 @@ "@trezor/blockchain-link/@stellar/stellar-sdk/@stellar/stellar-base": ["@stellar/stellar-base@14.1.0", "", { "dependencies": { "@noble/curves": "^1.9.6", "@stellar/js-xdr": "^3.1.2", "base32.js": "^0.1.0", "bignumber.js": "^9.3.1", "buffer": "^6.0.3", "sha.js": "^2.4.12" } }, "sha512-A8kFli6QGy22SRF45IjgPAJfUNGjnI+R7g4DF5NZYVsD1kGf7B4ITyc4OPclLV9tqNI4/lXxafGEw0JEUbHixw=="], - "@trezor/blockchain-link/@stellar/stellar-sdk/axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], - "@trezor/blockchain-link/xrpl/@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="], "@trezor/blockchain-link/xrpl/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], @@ -3514,12 +3907,16 @@ "@types/ws/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.1.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA=="], + "@walletconnect/modal-ui/lit/@lit/reactive-element": ["@lit/reactive-element@1.6.3", "", { "dependencies": { "@lit-labs/ssr-dom-shim": "^1.0.0" } }, "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ=="], "@walletconnect/modal-ui/lit/lit-element": ["lit-element@3.3.3", "", { "dependencies": { "@lit-labs/ssr-dom-shim": "^1.1.0", "@lit/reactive-element": "^1.3.0", "lit-html": "^2.8.0" } }, "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA=="], "@walletconnect/modal-ui/lit/lit-html": ["lit-html@2.8.0", "", { "dependencies": { "@types/trusted-types": "^2.0.2" } }, "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q=="], + "@walletconnect/modal-ui/qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], + "@walletconnect/utils/ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="], "@walletconnect/utils/ox/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="], @@ -3534,11 +3931,7 @@ "abi-wan-kanabi/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - "abi-wan-kanabi/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], - - "abi-wan-kanabi/yargs/y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - - "abi-wan-kanabi/yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "browserify-sign/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], @@ -3552,6 +3945,10 @@ "ethers/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + "glob/minimatch/brace-expansion": ["brace-expansion@2.1.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA=="], + + "jayson/@types/ws/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], + "micro-key-producer/micro-packed/@scure/base": ["@scure/base@2.0.0", "", {}, "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w=="], "near-api-js/@near-js/signers/@noble/hashes": ["@noble/hashes@1.3.3", "", {}, "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA=="], @@ -3562,15 +3959,21 @@ "near-api-js/@noble/curves/@noble/hashes": ["@noble/hashes@1.3.2", "", {}, "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="], - "near-seed-phrase/bs58/base-x": ["base-x@3.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA=="], + "near-api-js/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "ox/@scure/bip32/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], + "near-seed-phrase/bs58/base-x": ["base-x@3.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA=="], "ox/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], "ox/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], - "pkg-dir/find-up/locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + "qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], + + "qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "qrcode/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], + + "qrcode/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], "read-yaml-file/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], @@ -3578,8 +3981,6 @@ "ripple-keypairs/@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "rpc-websockets/@types/ws/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], - "starknet/@noble/curves/@noble/hashes": ["@noble/hashes@1.6.0", "", {}, "sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ=="], "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], @@ -3590,6 +3991,12 @@ "viem/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "viem/ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="], + + "viem/ox/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + + "vite-plugin-cjs-interop/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + "websocket/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "xrpl/@scure/bip32/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], @@ -3610,6 +4017,10 @@ "@ledgerhq/psbtv2/bitcoinjs-lib/bip32/@types/node": ["@types/node@10.12.18", "", {}, "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ=="], + "@manypkg/find-root/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "@near-js/accounts/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@near-js/keystores-browser/@near-js/crypto/@near-js/utils/bs58": ["bs58@4.0.0", "", { "dependencies": { "base-x": "^2.0.1" } }, "sha512-/jcGuUuSebyxwLLfKrbKnCJttxRf9PM51EnHTwmFKBxl4z1SGkoAhrfd6uZKE0dcjQTfm6XzTP8DPr1tzE4KIw=="], "@near-js/keystores-browser/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.3.2", "", {}, "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="], @@ -3622,23 +4033,33 @@ "@near-js/keystores-node/@near-js/keystores/@near-js/types/bn.js": ["bn.js@5.2.1", "", {}, "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ=="], - "@near-js/wallet-account/@near-js/accounts/@near-js/providers/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "@near-js/keystores/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@near-js/providers/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@near-js/signers/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@near-js/wallet-account/@near-js/accounts/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "@near-js/wallet-account/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.3.2", "", {}, "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="], "@near-js/wallet-account/@near-js/utils/bs58/base-x": ["base-x@2.0.6", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g=="], + "@near-wallet-selector/core/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + + "@solana/codecs/@solana/codecs-core/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "@solana/codecs/@solana/codecs-core/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], - "@solana/codecs/@solana/codecs-numbers/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + "@solana/codecs/@solana/codecs-numbers/@solana/errors/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "@starknet-io/get-starknet-wallet-standard/ox/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@solana/codecs/@solana/codecs-numbers/@solana/errors/commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], - "@starknet-io/get-starknet-wallet-standard/ox/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@swapkit/plugins/@near-js/transactions/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/tendermint-rpc/@cosmjs/json-rpc": ["@cosmjs/json-rpc@0.39.0", "", { "dependencies": { "@cosmjs/stream": "^0.39.0", "xstream": "^11.14.0" } }, "sha512-slyo76IYkTuSxrzxvF1s1ScFPIGnW7PbNSx8lr++NzdyPluqe053+cSqsxLUioXb5qI9Nxny2fWxOK8isSn+cg=="], + "@swapkit/plugins/@near-js/transactions/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/tendermint-rpc/@cosmjs/socket": ["@cosmjs/socket@0.39.0", "", { "dependencies": { "@cosmjs/stream": "^0.39.0", "isomorphic-ws": "^4.0.1", "ws": "^7", "xstream": "^11.14.0" } }, "sha512-mvA+/ycMn7dnjjdooSPq516poFpSARRXhFhKjCXxGUmBZA+74vLDLbtD6VGzHd08A2JSZBSiAhVOZpjYqgV78A=="], + "@swapkit/toolboxes/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@swapkit/wallet-extensions/@cosmjs/amino/@cosmjs/crypto/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], @@ -3652,6 +4073,8 @@ "@swapkit/wallet-extensions/@cosmjs/proto-signing/@cosmjs/crypto/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "@swapkit/wallet-extensions/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@swapkit/wallet-hardware/@cosmjs/amino/@cosmjs/crypto/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@swapkit/wallet-hardware/@cosmjs/amino/@cosmjs/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -3664,6 +4087,8 @@ "@swapkit/wallet-hardware/@cosmjs/proto-signing/@cosmjs/crypto/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "@swapkit/wallet-hardware/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@swapkit/wallets/@cosmjs/amino/@cosmjs/crypto/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@swapkit/wallets/@cosmjs/amino/@cosmjs/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -3676,12 +4101,14 @@ "@swapkit/wallets/@cosmjs/proto-signing/@cosmjs/crypto/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "@swapkit/wallets/@near-js/transactions/@near-js/crypto/@noble/curves": ["@noble/curves@1.8.1", "", { "dependencies": { "@noble/hashes": "1.7.1" } }, "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ=="], + + "@swapkit/wallets/@near-js/transactions/@near-js/crypto/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + "@trezor/blockchain-link-utils/@stellar/stellar-sdk/@stellar/stellar-base/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@trezor/blockchain-link-utils/@stellar/stellar-sdk/@stellar/stellar-base/@stellar/js-xdr": ["@stellar/js-xdr@3.1.2", "", {}, "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ=="], - "@trezor/blockchain-link-utils/@stellar/stellar-sdk/axios/proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], - "@trezor/blockchain-link-utils/@trezor/protobuf/protobufjs/@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], "@trezor/blockchain-link-utils/@trezor/protobuf/protobufjs/long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], @@ -3700,8 +4127,6 @@ "@trezor/blockchain-link/@stellar/stellar-sdk/@stellar/stellar-base/@stellar/js-xdr": ["@stellar/js-xdr@3.1.2", "", {}, "sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ=="], - "@trezor/blockchain-link/@stellar/stellar-sdk/axios/proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="], - "@trezor/blockchain-link/xrpl/@scure/bip32/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], "@trezor/blockchain-link/xrpl/@scure/bip32/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], @@ -3718,13 +4143,23 @@ "@trezor/protobuf/protobufjs/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "@walletconnect/modal-ui/qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], + + "@walletconnect/modal-ui/qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + + "@walletconnect/modal-ui/qrcode/yargs/y18n": ["y18n@4.0.3", "", {}, "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="], + + "@walletconnect/modal-ui/qrcode/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], + "@walletconnect/utils/ox/@scure/bip32/@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="], - "abi-wan-kanabi/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "jayson/@types/ws/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], "near-api-js/@near-js/utils/bs58/base-x": ["base-x@2.0.6", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g=="], - "pkg-dir/find-up/locate-path/p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "qrcode/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "qrcode/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], "ripemd160/hash-base/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], @@ -3732,13 +4167,15 @@ "ripemd160/hash-base/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "rpc-websockets/@types/ws/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "vite-plugin-cjs-interop/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@manypkg/find-root/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], "@near-js/keystores-browser/@near-js/crypto/@near-js/utils/bs58/base-x": ["base-x@2.0.6", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g=="], "@near-js/keystores-node/@near-js/crypto/@near-js/utils/bs58/base-x": ["base-x@2.0.6", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-UAmjxz9KbK+YIi66xej+pZVo/vxUOh49ubEvZW5egCbxhur05pBb+hwuireQwKO4nDpsNm64/jEei17LEpsr5g=="], - "@swapkit/ui/@cosmjs/stargate/@cosmjs/tendermint-rpc/@cosmjs/socket/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "@swapkit/plugins/@near-js/transactions/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], "@swapkit/wallet-extensions/@cosmjs/amino/@cosmjs/crypto/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], @@ -3752,6 +4189,8 @@ "@swapkit/wallets/@cosmjs/proto-signing/@cosmjs/crypto/@scure/bip39/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], + "@swapkit/wallets/@near-js/transactions/@near-js/crypto/@noble/curves/@noble/hashes": ["@noble/hashes@1.7.1", "", {}, "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ=="], + "@trezor/blockchain-link-utils/@stellar/stellar-sdk/@stellar/stellar-base/@noble/curves/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], "@trezor/blockchain-link-utils/@trezor/protobuf/protobufjs/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], @@ -3760,6 +4199,16 @@ "@trezor/device-authenticity/@trezor/protobuf/protobufjs/@types/node/undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], - "pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + "@walletconnect/modal-ui/qrcode/yargs/cliui/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "@walletconnect/modal-ui/qrcode/yargs/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + + "qrcode/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "@walletconnect/modal-ui/qrcode/yargs/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + + "qrcode/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "@walletconnect/modal-ui/qrcode/yargs/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], } } diff --git a/devops/CLAUDE.md b/devops/CLAUDE.md new file mode 100644 index 0000000..207bd22 --- /dev/null +++ b/devops/CLAUDE.md @@ -0,0 +1,45 @@ +# DevOps - SwapKit UI + +Infrastructure, CI/CD, and deployment configuration for the SwapKit UI. + +## Quick Reference + +- **GCP Projects**: `sk-ui-dev`, `sk-ui-stage`, `sk-ui-prod` +- **Terraform State**: `gs://sk-frontend-terraform-be` +- **DNS**: Cloudflare (zone: `swapkit.dev`, creds in repo root `.env`) +- **Build System**: Google Cloud Build (region: `us-central1`) +- **Package Manager**: Bun (not npm) +- **GitHub**: `swapkit/wallets` via Cloud Build connection `swapkit` + +## Documentation + +- **[CDN Infrastructure](terraform/cdn/CDN.md)** — CDN + Studio routing, Terraform, DNS, SSL certs, operational runbooks +- **[Cloud Build Pipelines](cloudbuild/CLOUDBUILD.md)** — Build triggers, deploy pipelines, trigger config files + +## Environment Matrix + +| Environment | GCP Project | Branch | CDN Domain | Studio Domain | +|---|---|---|---|---| +| Dev | `sk-ui-dev` | `develop` | `cdn-dev.swapkit.dev` | `widget-dev.swapkit.dev/studio` | +| Staging | `sk-ui-stage` | `staging` | `cdn-stage.swapkit.dev` | `widget-stage.swapkit.dev/studio` | +| Production | `sk-ui-prod` | `main` | `cdn.swapkit.dev` | `widget.swapkit.dev/studio` | + +Studio routing is enabled per-environment via `enable_studio` in the CDN terraform. All environments are active. + +## Key Conventions + +- Each GCP project is **fully isolated** — own service accounts, triggers, and resources. **No cross-project IAM.** +- GitHub connections vary by project: `swapkit` (swapkit-devops), `swapkit-org` (sk-ui-dev), `sk` (sk-ui-stage/prod). All link to repo `swapkit-wallets` +- DNS pattern: `-direct.swapkit.dev` (A record, not proxied) + `.swapkit.dev` (CNAME, Cloudflare proxied) +- Google-managed SSL certs only cover the `-direct` domains; Cloudflare handles SSL on proxied domains +- Terraform auto-applies on push to the environment's branch when files in the relevant path change +- Build service account: `cloudbuild@.iam.gserviceaccount.com` + +## Infrastructure Locations + +| Component | Path | Manages | +|---|---|---| +| CDN + Studio LB | `devops/terraform/cdn//` | GCS bucket, Cloud CDN, URL map, SSL, forwarding rules | +| Widget Cloud Run | `playgrounds/vite-lite/terraform//` | Cloud Run services, serverless NEGs, backend service | +| CI/CD Pipelines | `devops/cloudbuild/` | Build and deploy YAML + trigger configs | +| Build/Deploy Triggers (TF) | `devops/bootstrap/` | Cloud Build trigger + Artifact Registry definitions | diff --git a/devops/bootstrap/build_trigger/.terraform.lock.hcl b/devops/bootstrap/build_trigger/.terraform.lock.hcl new file mode 100644 index 0000000..bd3ef5e --- /dev/null +++ b/devops/bootstrap/build_trigger/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "6.48.0" + hashes = [ + "h1:kXgER6get6WqsFx1lslfRnssgcg+g248eNUiXn55tdg=", + "zh:3640317ada2141ab5b54b5c5c2b1d0f60af861fb9788f05808b5d5d7ac8d1819", + "zh:4ec6082c343d7ea097bf725c7f550978789860f43b442a7709e1a4ca209d10a7", + "zh:66dcb85612f82c464a682e03a20e9dfd479e743d63a7e9cf754dcf81fa6e442b", + "zh:88ce6cb6f2f5f3a356c27ca5923594d272ea25801ed81026e102a2dc24d347d3", + "zh:b62e3715bf35fe0322b2a56c5072ecfdea2dd25f1c794f432acd1dd0105112b5", + "zh:bc2a9397c6d9b71ccf74cea442e74d8bb5603d491aa4a7cd88d5c44693674e16", + "zh:c6710acbdbaeca8307467186b0cc5184c8223fd0efa8c52e7f81310f34c68c69", + "zh:ca077af69ab66444bf027b7663e1386f2d14699b50562d1674c84522316bf52a", + "zh:e1b74bcdacb20d73da0470f6874dc7ac38b58bfa738ec5e337fcc7c5a4f32663", + "zh:e9b2dcd583025b69b7e80c9ad0d9ee4ed91e731f2073db5b6516978cf7617017", + "zh:f0d4ef4a8ca749b9102b152aafc093fa7def2afbda771b6b26cbc873f4e6dfc8", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/devops/bootstrap/build_trigger/backend.tf b/devops/bootstrap/build_trigger/backend.tf new file mode 100644 index 0000000..6c6d514 --- /dev/null +++ b/devops/bootstrap/build_trigger/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "sk-frontend-terraform-be" + prefix = "terraform/state/widget/sk-ui-dev/build-trigger/" + } +} diff --git a/devops/bootstrap/build_trigger/build_trigger.tf b/devops/bootstrap/build_trigger/build_trigger.tf new file mode 100644 index 0000000..ddb0e85 --- /dev/null +++ b/devops/bootstrap/build_trigger/build_trigger.tf @@ -0,0 +1,29 @@ +resource "google_cloudbuild_trigger" "widget" { + project = var.project_id + name = var.trigger_name + location = "us-central1" + + repository_event_config { + repository = "projects/${var.project_id}/locations/us-central1/connections/swapkit/repositories/swapkit-wallets" + push { + branch = "^${var.branch_name}$" + } + } + + git_file_source { + path = "devops/cloudbuild/buildchangedapps.yaml" + repository = "projects/${var.project_id}/locations/us-central1/connections/swapkit/repositories/swapkit-wallets" + revision = var.branch_ref + repo_type = "GITHUB" + } + + service_account = "projects/${var.project_id}/serviceAccounts/cloudbuild@${var.project_id}.iam.gserviceaccount.com" +} + +resource "google_artifact_registry_repository" "docker_repo" { + location = var.region_artifact + project = var.project_id + repository_id = var.repository_name + description = "Docker repository for widget" + format = "DOCKER" +} \ No newline at end of file diff --git a/devops/bootstrap/build_trigger/variables.tf b/devops/bootstrap/build_trigger/variables.tf new file mode 100644 index 0000000..5e174b6 --- /dev/null +++ b/devops/bootstrap/build_trigger/variables.tf @@ -0,0 +1,41 @@ +variable "project_id" { + description = "The Google Cloud project ID for build." + type = string + default = "swapkit-devops" +} + +variable "region" { + description = "The Google Cloud region." + type = string + default = "us-central1" +} + +variable "region_artifact" { + description = "The Google Cloud region for Artifact Registry." + type = string + default = "us" +} + +variable "trigger_name" { + description = "Cloud Build trigger name." + type = string + default = "build-widget" +} + +variable "branch_name" { + description = "Branch name pattern." + type = string + default = "(develop|main)" +} + +variable "branch_ref" { + description = "Branch reference." + type = string + default = "refs/heads/^(develop|main)$" +} + +variable "repository_name" { + description = "Artifact Registry repository ID." + type = string + default = "widget" +} \ No newline at end of file diff --git a/devops/bootstrap/deploy_trigger/sk-ui-dev/.terraform.lock.hcl b/devops/bootstrap/deploy_trigger/sk-ui-dev/.terraform.lock.hcl new file mode 100644 index 0000000..bd3ef5e --- /dev/null +++ b/devops/bootstrap/deploy_trigger/sk-ui-dev/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "6.48.0" + hashes = [ + "h1:kXgER6get6WqsFx1lslfRnssgcg+g248eNUiXn55tdg=", + "zh:3640317ada2141ab5b54b5c5c2b1d0f60af861fb9788f05808b5d5d7ac8d1819", + "zh:4ec6082c343d7ea097bf725c7f550978789860f43b442a7709e1a4ca209d10a7", + "zh:66dcb85612f82c464a682e03a20e9dfd479e743d63a7e9cf754dcf81fa6e442b", + "zh:88ce6cb6f2f5f3a356c27ca5923594d272ea25801ed81026e102a2dc24d347d3", + "zh:b62e3715bf35fe0322b2a56c5072ecfdea2dd25f1c794f432acd1dd0105112b5", + "zh:bc2a9397c6d9b71ccf74cea442e74d8bb5603d491aa4a7cd88d5c44693674e16", + "zh:c6710acbdbaeca8307467186b0cc5184c8223fd0efa8c52e7f81310f34c68c69", + "zh:ca077af69ab66444bf027b7663e1386f2d14699b50562d1674c84522316bf52a", + "zh:e1b74bcdacb20d73da0470f6874dc7ac38b58bfa738ec5e337fcc7c5a4f32663", + "zh:e9b2dcd583025b69b7e80c9ad0d9ee4ed91e731f2073db5b6516978cf7617017", + "zh:f0d4ef4a8ca749b9102b152aafc093fa7def2afbda771b6b26cbc873f4e6dfc8", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/devops/bootstrap/deploy_trigger/sk-ui-dev/backend.tf b/devops/bootstrap/deploy_trigger/sk-ui-dev/backend.tf new file mode 100644 index 0000000..dc3e67a --- /dev/null +++ b/devops/bootstrap/deploy_trigger/sk-ui-dev/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "sk-frontend-terraform-be" + prefix = "terraform/state/widget/sk-ui-dev/deploy-trigger/" + } +} diff --git a/devops/bootstrap/deploy_trigger/sk-ui-dev/deploy_trigger.tf b/devops/bootstrap/deploy_trigger/sk-ui-dev/deploy_trigger.tf new file mode 100644 index 0000000..4a9b26d --- /dev/null +++ b/devops/bootstrap/deploy_trigger/sk-ui-dev/deploy_trigger.tf @@ -0,0 +1,35 @@ +resource "google_cloudbuild_trigger" "deploy-service-on-image" { + project = var.project_id + name = "deploy-widget" + location = "us-central1" + + pubsub_config { + topic = "projects/swapkit-devops/topics/gcr" + } + + source_to_build { + ref = var.branch_ref + repository = "projects/${var.project_id}/locations/us-central1/connections/swapkit-org/repositories/swapkit-wallets" + repo_type = "GITHUB" + } + + git_file_source { + path = "devops/cloudbuild/deploy.yaml" + repository = "projects/${var.project_id}/locations/us-central1/connections/swapkit-org/repositories/swapkit-wallets" + revision = var.branch_ref + repo_type = "GITHUB" + } + + service_account = "projects/${var.project_id}/serviceAccounts/cloudbuild@${var.project_id}.iam.gserviceaccount.com" + + filter = "_ACTION.matches(\"INSERT\") && _TAG.matches(\"us-docker.pkg.dev/swapkit-devops/widget.*:(dev|dev-deploy|feat|feature)$\") && !_TAG.matches(\".*cache.*\")" + + substitutions = { + _ACTION = "$(body.message.data.action)" + _DIGEST = "$(body.message.data.digest)" + _IMAGE_TAG = "$${_TAG##*/}" + _SERVICE_NAME = "$${_SERVICE_PREFIX##*/}" + _SERVICE_PREFIX = "$${_TAG%:*}" + _TAG = "$(body.message.data.tag)" + } +} \ No newline at end of file diff --git a/devops/bootstrap/deploy_trigger/sk-ui-dev/variables.tf b/devops/bootstrap/deploy_trigger/sk-ui-dev/variables.tf new file mode 100644 index 0000000..ecdeecb --- /dev/null +++ b/devops/bootstrap/deploy_trigger/sk-ui-dev/variables.tf @@ -0,0 +1,29 @@ +variable "project_id" { + description = "The Google Cloud project ID for deployment." + type = string + default = "sk-ui-dev" +} + +variable "region" { + description = "The Google Cloud region." + type = string + default = "us-central1" +} + +variable "trigger_name" { + description = "Cloud Build trigger name." + type = string + default = "deploy-widget" +} + +variable "branch_name" { + description = "Branch name pattern." + type = string + default = "feat/DOP-112" +} + +variable "branch_ref" { + description = "Branch reference." + type = string + default = "refs/heads/feat/DOP-112" +} \ No newline at end of file diff --git a/devops/cloudbuild/CLOUDBUILD.md b/devops/cloudbuild/CLOUDBUILD.md new file mode 100644 index 0000000..7569389 --- /dev/null +++ b/devops/cloudbuild/CLOUDBUILD.md @@ -0,0 +1,109 @@ +# Cloud Build Pipelines + +All CI/CD for the SwapKit UI runs on Google Cloud Build. Each environment has its own triggers in its own GCP project. + +## Pipelines + +### 1. Widget Image Build (`buildchangedapps.yaml`) + +Detects changed files, builds the widget Docker image via Kaniko, pushes to Artifact Registry. + +- **Watches**: `services/**`, triggered on `develop`, `main` (and active feature branches) +- **Output**: `us-docker.pkg.dev//widget/widget:` + +### 2. Widget Cloud Run Deploy (`deploy.yaml`) + +Terraform-based deployment of the widget to Cloud Run. Triggered by Pub/Sub on new image push to Artifact Registry. + +- **Terraform**: `playgrounds/vite-lite/terraform//` +- **Deploys to**: Cloud Run (multi-region: us-central1, europe-west1) + +### 3. Widget CDN Asset Deploy (`widget-cdn-deploy.yaml`) + +Builds the widget JS bundle and uploads to the CDN GCS bucket. + +- **Watches**: `packages/ui/**` +- **Steps**: `bun install` → `bun run build` → `bun build:widget` → `gsutil rsync` to bucket +- **Uploads**: + - `/widget/latest/` — mutable, `Cache-Control: public, max-age=0, must-revalidate` + - `/widget/v{version}/` — immutable, `Cache-Control: public, immutable, max-age=31536000` (skips if version already exists) +- **Resulting URLs** (prod example): + - `https://cdn.swapkit.dev/widget/latest/swapkit-widget.js` — always latest + - `https://cdn.swapkit.dev/widget/v1.2.3/swapkit-widget.js` — pinned version + +### 4. CDN Infrastructure (`terraform/cdn/cloudbuild.yaml`) + +Terraform auto-apply for CDN infrastructure (GCS bucket, Cloud CDN, load balancer, SSL). + +- **Watches**: `devops/terraform/cdn//**` +- **Steps**: `terraform init` → `apply -refresh-only` → `apply -auto-approve` + +## Trigger Matrix + +### CDN Asset Deploy Triggers + +| Trigger | Project | Branch | Bucket | +|---|---|---|---| +| `widget-cdn-deploy-dev` | `sk-ui-dev` | `develop` | `swapkit-widget-cdn-dev` | +| `widget-cdn-deploy-stage` | `sk-ui-stage` | `staging` | `swapkit-widget-cdn-stage` | +| `widget-cdn-deploy-prod` | `sk-ui-prod` | `main` | `swapkit-widget-cdn-prod` | + +### CDN Infrastructure Triggers + +| Trigger | Project | Branch | Watches | +|---|---|---|---| +| `widget-cdn-infrastructure-dev` | `sk-ui-dev` | `develop` | `devops/terraform/cdn/sk-ui-dev/**` | +| `widget-cdn-infrastructure-stage` | `sk-ui-stage` | `staging` | `devops/terraform/cdn/sk-ui-stage/**` | +| `widget-cdn-infrastructure-prod` | `sk-ui-prod` | `main` | `devops/terraform/cdn/sk-ui-prod/**` | + +## Trigger Config Files + +All trigger configs are YAML files that can be imported/updated via: +```bash +gcloud builds triggers import --source= \ + --project= --region=us-central1 +``` + +| File | Purpose | +|---|---| +| `cloudbuild/trigger-widget-cdn-deploy-dev.yaml` | Widget asset deploy (dev) | +| `cloudbuild/trigger-widget-cdn-deploy-stage.yaml` | Widget asset deploy (stage) | +| `cloudbuild/trigger-widget-cdn-deploy-prod.yaml` | Widget asset deploy (prod) | +| `terraform/cdn/trigger-config-dev.yaml` | CDN infra auto-apply (dev) | +| `terraform/cdn/trigger-config-stage.yaml` | CDN infra auto-apply (stage) | +| `terraform/cdn/trigger-config-prod.yaml` | CDN infra auto-apply (prod) | + +## GitHub Connections + +Each project has its own Cloud Build connection. All link to repo `swapkit-wallets` (`swapkit/wallets` on GitHub). + +| Project | Connection | Repository | +|---|---|---| +| `swapkit-devops` | `swapkit` | `swapkit-wallets` | +| `sk-ui-dev` | `swapkit-org` | `swapkit-wallets` | +| `sk-ui-stage` | `sk` | `swapkit-wallets` | +| `sk-ui-prod` | `sk` | `swapkit-wallets` | + +## Service Accounts + +Each project uses `cloudbuild@.iam.gserviceaccount.com`. Required IAM roles: + +| Role | Purpose | +|---|---| +| `roles/storage.admin` | GCS bucket creation, IAM, and CDN asset uploads | +| `roles/compute.loadBalancerAdmin` | Forwarding rules, URL maps, proxies, backend buckets | +| `roles/compute.networkAdmin` | Global static IP addresses | +| `roles/certificatemanager.owner` | Google-managed SSL certificates | +| `roles/run.admin` | Cloud Run service deployment (widget image build pipeline) | +| `roles/artifactregistry.writer` | Push container images | + +## Manual Trigger Run + +```bash +# Run widget CDN deploy manually (e.g., for dev) +gcloud builds submit \ + --config=devops/cloudbuild/widget-cdn-deploy.yaml \ + --project=sk-ui-dev --region=us-central1 \ + --service-account="projects/sk-ui-dev/serviceAccounts/cloudbuild@sk-ui-dev.iam.gserviceaccount.com" \ + --substitutions=_BUCKET_NAME=swapkit-widget-cdn-dev . +``` diff --git a/devops/cloudbuild/buildchangedapps.yaml b/devops/cloudbuild/buildchangedapps.yaml new file mode 100644 index 0000000..98acc1c --- /dev/null +++ b/devops/cloudbuild/buildchangedapps.yaml @@ -0,0 +1,158 @@ +timeout: 1800s +options: + logging: CLOUD_LOGGING_ONLY + +steps: + # Step 0: Fetch full Git history for proper change detection + - name: 'gcr.io/cloud-builders/git' + id: 'fetch-full-history' + entrypoint: 'bash' + args: + - '-c' + - | + # Configure GitHub authentication using the token + git config --global url."https://$$GITHUB_TOKEN@github.com/".insteadOf "https://github.com/" + + # Fetch complete repository history for accurate diffing + git fetch --unshallow --tags + + # For PR builds, fetch the target branch for comparison + if [ -n "$_PR_NUMBER" ] && [ -n "$BRANCH_NAME" ]; then + git fetch origin $BRANCH_NAME + fi + + # Debug output to verify repository state + echo "Repository prepared:" + git log --oneline -n 5 + secretEnv: ['GITHUB_TOKEN'] + + # Step 1: Detect changed files in the Vite project + - name: 'gcr.io/cloud-builders/git' + id: 'get-changed-files' + entrypoint: 'bash' + args: + - '-c' + - | + # Print build environment for debugging + echo "Build environment:" + echo "PR_NUMBER: ${_PR_NUMBER:-NOT_SET}" + echo "BRANCH_NAME: ${BRANCH_NAME:-NOT_SET}" + echo "COMMIT_SHA: ${COMMIT_SHA:-NOT_SET}" + echo "HEAD SHA: $(git rev-parse HEAD)" + + # Skip change detection for non-core branches + if [ "$BRANCH_NAME" = "feat/DOP-112" ] || [ "$BRANCH_NAME" = "develop" ] || [ "$BRANCH_NAME" = "main" ] || [ "$BRANCH_NAME" = "staging" ]; then + : # This is an allowed branch, continue with processing + else + echo "Non-core branch detected ($BRANCH_NAME) - creating empty changed_files.txt" + touch /workspace/changed_files.txt + exit 0 + fi + + # Determine changed files with fallback mechanisms + if [ -n "$_PR_NUMBER" ]; then + echo "PR build detected - comparing with target branch $BRANCH_NAME" + git fetch origin $BRANCH_NAME --depth=1 + git diff --name-only origin/$BRANCH_NAME HEAD > /workspace/changed_files.txt || { + echo "Diff failed, fallback to listing all files" + git ls-files > /workspace/changed_files.txt + } + else + echo "Non-PR build detected - comparing HEAD^ with HEAD" + if [ $(git rev-list --count HEAD) -gt 1 ]; then + git diff --name-only HEAD^ HEAD > /workspace/changed_files.txt || { + echo "Diff failed, using commit range" + git diff --name-only $COMMIT_SHA~1 $COMMIT_SHA > /workspace/changed_files.txt || { + echo "Final fallback - listing all files" + git ls-files > /workspace/changed_files.txt + } + } + else + echo "Shallow clone with no history - listing all files" + git ls-files > /workspace/changed_files.txt + fi + fi + + # Output the changed files for debugging + echo "Changed files detected:" + cat /workspace/changed_files.txt + echo "Total changed files: $(wc -l < /workspace/changed_files.txt)" + + # Step 2: Set target environment based on branch + - id: set-env-vars + name: 'gcr.io/cloud-builders/gcloud' + script: | + #!/usr/bin/env bash + # Determine target environment based on branch name + TARGET_ENV=dev + if [ "${BRANCH_NAME}" == "main" ] + then + TARGET_ENV=prod + fi + if [ "${BRANCH_NAME}" == "staging" ] + then + TARGET_ENV=staging + fi + + echo "Building for environment: ${TARGET_ENV}" + echo "export TARGET_ENV=${TARGET_ENV}" >> /workspace/vars.env + echo "Current environment variables:" + cat /workspace/vars.env + env: + - 'BRANCH_NAME=${BRANCH_NAME}' + + # Step 3: Build the Vite application with Kaniko + - name: 'gcr.io/cloud-builders/docker' + id: 'generate-build-step' + waitFor: ['set-env-vars'] + entrypoint: 'bash' + args: + - '-c' + - | + # Generate Kaniko build configuration for the Vite app + source /workspace/vars.env + + echo "Generating Kaniko build configuration for Vite application:" + echo "steps:" > /workspace/kaniko_steps.yaml + echo " - name: 'gcr.io/kaniko-project/executor:latest'" >> /workspace/kaniko_steps.yaml + echo " id: 'build-vite-app'" >> /workspace/kaniko_steps.yaml + echo " args:" >> /workspace/kaniko_steps.yaml + echo " - --destination=us-docker.pkg.dev/$PROJECT_ID/widget/widget:$SHORT_SHA" >> /workspace/kaniko_steps.yaml + echo " - --destination=us-docker.pkg.dev/$PROJECT_ID/widget/widget:$${TARGET_ENV}" >> /workspace/kaniko_steps.yaml + echo " - --cache=true" >> /workspace/kaniko_steps.yaml + echo " - --cache-ttl=6h" >> /workspace/kaniko_steps.yaml + echo " - --context=/workspace/" >> /workspace/kaniko_steps.yaml + echo " - --dockerfile=/workspace/playgrounds/vite-lite/Dockerfile" >> /workspace/kaniko_steps.yaml + + echo "options:" >> /workspace/kaniko_steps.yaml + echo " logging: CLOUD_LOGGING_ONLY" >> /workspace/kaniko_steps.yaml + + echo "Generated kaniko_steps.yaml:" + cat /workspace/kaniko_steps.yaml + + # Step 4: Execute the Kaniko build + - name: 'gcr.io/cloud-builders/gcloud' + id: 'run-kaniko-build' + waitFor: ['generate-build-step'] + entrypoint: 'bash' + args: + - '-c' + - | + # Execute the Kaniko build for the Vite application + echo "Starting Kaniko build for Vite application..." + exec gcloud builds submit \ + --region=us-central1 \ + --config=/workspace/kaniko_steps.yaml \ + --machine-type=e2-highcpu-32 \ + --async \ + --format='value(id)' \ + --service-account="projects/${PROJECT_ID}/serviceAccounts/cloudbuild@${PROJECT_ID}.iam.gserviceaccount.com" \ + . + +tags: + - "widget-build" + +availableSecrets: + secretManager: + - versionName: projects/$PROJECT_ID/secrets/cloudbuild-github-access-token/versions/latest + env: 'GITHUB_TOKEN' \ No newline at end of file diff --git a/devops/cloudbuild/deploy.yaml b/devops/cloudbuild/deploy.yaml new file mode 100644 index 0000000..7456172 --- /dev/null +++ b/devops/cloudbuild/deploy.yaml @@ -0,0 +1,213 @@ +steps: + # Step 0: Display build information + - name: 'gcr.io/cloud-builders/gcloud' + id: display-build-info + entrypoint: /bin/sh + args: + - '-c' + - | + echo "==========================================" + echo "Widget Deployment Information" + echo "==========================================" + echo "Project ID: ${PROJECT_ID}" + echo "Image Digest: ${_DIGEST}" + echo "Image Tag: ${_TAG}" + echo "Build ID: ${BUILD_ID}" + echo "Commit SHA: ${SHORT_SHA}" + echo "==========================================" + + # Step 1: Initialize Terraform with backend configuration + - name: 'hashicorp/terraform:${_TF_VERSION}' + id: terraform-init + entrypoint: /bin/sh + args: + - '-c' + - | + cd playgrounds/vite-lite/terraform/${PROJECT_ID} + + echo "Initializing Terraform..." + echo "Backend bucket: sk-frontend-terraform-be" + echo "Backend prefix: terraform/state/${_SERVICE_NAME}/${PROJECT_ID}" + + terraform init -reconfigure + env: + - TF_VAR_project_id=${PROJECT_ID} + - TF_VAR_service_name=${_SERVICE_NAME} + - TF_VAR_image_url=${_DIGEST} + + # Step 2: Validate Terraform Configuration + - name: 'hashicorp/terraform:${_TF_VERSION}' + id: terraform-validate + entrypoint: /bin/sh + args: + - '-c' + - | + cd playgrounds/vite-lite/terraform/${PROJECT_ID} + + echo "=== Terraform Configuration Validation ===" + echo "Project ID: ${PROJECT_ID}" + echo "Service Name: ${_SERVICE_NAME}" + echo "Image URL: ${_DIGEST}" + echo "" + + terraform validate + + echo "" + echo "✓ Terraform configuration is valid" + env: + - TF_VAR_project_id=${PROJECT_ID} + - TF_VAR_service_name=${_SERVICE_NAME} + - TF_VAR_image_url=${_DIGEST} + + # Step 3: Generate Terraform Plan + - name: 'hashicorp/terraform:${_TF_VERSION}' + id: terraform-plan + entrypoint: /bin/sh + args: + - '-c' + - | + cd playgrounds/vite-lite/terraform/${PROJECT_ID} + + echo "=== Generating Terraform Plan ===" + + terraform plan -out=plan.tfplan -input=false \ + -var="project_id=${PROJECT_ID}" \ + -var="service_name=${_SERVICE_NAME}" \ + -var="image_url=${_DIGEST}" + + echo "" + echo "✓ Terraform plan generated successfully" + env: + - TF_VAR_project_id=${PROJECT_ID} + - TF_VAR_service_name=${_SERVICE_NAME} + - TF_VAR_image_url=${_DIGEST} + + # Step 4: Apply Terraform Plan with error handling for existing resources + - name: 'hashicorp/terraform:${_TF_VERSION}' + id: terraform-apply + entrypoint: /bin/sh + args: + - '-c' + - | + cd playgrounds/vite-lite/terraform/${PROJECT_ID} + + # Get service name and regions from Terraform variables + SERVICE_NAME="${_SERVICE_NAME}" + + # Extract regions from variables.tf + get_regions() { + terraform console </dev/null | tr -d '[]"' | tr ',' ' ' + var.additional_regions + EOF + } + + REGION_LIST=$$(get_regions) + + # Fallback if terraform console doesn't work + if [ -z "$$REGION_LIST" ]; then + echo "Fallback: Reading regions from default values..." + REGION_LIST="us-central1 europe-west1" + fi + + echo "=== Configuration ===" + echo "Service Name: $$SERVICE_NAME" + echo "Project ID: ${PROJECT_ID}" + echo "Regions: $$REGION_LIST" + echo "" + + # Function to import existing Cloud Run service if it exists + import_existing_service() { + local region=$$1 + local full_service_name="$$SERVICE_NAME-$$region" + + echo "Checking for existing service: $$full_service_name in $$region" + + if gcloud run services describe $$full_service_name \ + --region=$$region \ + --project=${PROJECT_ID} \ + --quiet >/dev/null 2>&1; then + + echo "✓ Found existing Cloud Run service: $$full_service_name" + echo " Importing into Terraform state..." + + terraform import \ + "google_cloud_run_v2_service.default[\"$$region\"]" \ + "projects/${PROJECT_ID}/locations/$$region/services/$$full_service_name" \ + 2>/dev/null || echo " (Already imported or failed to import)" + else + echo "✗ Service $$full_service_name does not exist in $$region (will be created)" + fi + } + + # Function to import existing IAM binding if it exists + import_existing_iam() { + local region=$$1 + local full_service_name="$$SERVICE_NAME-$$region" + + if gcloud run services describe $$full_service_name \ + --region=$$region \ + --project=${PROJECT_ID} \ + --quiet >/dev/null 2>&1; then + + echo "✓ Importing IAM binding for: $$full_service_name" + + terraform import \ + "google_cloud_run_v2_service_iam_binding.public_access[\"$$region\"]" \ + "projects/${PROJECT_ID}/locations/$$region/services/$$full_service_name" \ + 2>/dev/null || echo " (Already imported or failed to import)" + fi + } + + echo "=== Applying Terraform ===" + + # Try to apply + if terraform apply -auto-approve -input=false plan.tfplan; then + echo "" + echo "✓ Terraform apply completed successfully" + else + echo "" + echo "⚠ Initial apply failed, attempting to import existing resources..." + echo "" + + # Import existing resources for each region + for region in $$REGION_LIST; do + echo "Processing region: $$region" + import_existing_service $$region + import_existing_iam $$region + echo "" + done + + # Regenerate plan after imports + echo "Regenerating Terraform plan after imports..." + terraform plan -out=plan.tfplan -input=false \ + -var="project_id=${PROJECT_ID}" \ + -var="service_name=${_SERVICE_NAME}" \ + -var="image_url=${_DIGEST}" + + echo "" + echo "Applying Terraform after importing existing resources..." + terraform apply -auto-approve -input=false plan.tfplan + + echo "" + echo "✓ Terraform apply completed after imports" + fi + env: + - TF_VAR_project_id=${PROJECT_ID} + - TF_VAR_service_name=${_SERVICE_NAME} + - TF_VAR_image_url=${_DIGEST} + +substitutions: + _TF_VERSION: "1.5.5" + _SERVICE_NAME: "widget" + +timeout: "1800s" # 30 minutes + +tags: + - terraform + - widget + - cloud-run + - playgrounds-vite-lite + +options: + logging: CLOUD_LOGGING_ONLY + dynamic_substitutions: true \ No newline at end of file diff --git a/devops/cloudbuild/trigger-widget-cdn-deploy-dev.yaml b/devops/cloudbuild/trigger-widget-cdn-deploy-dev.yaml new file mode 100644 index 0000000..298d0db --- /dev/null +++ b/devops/cloudbuild/trigger-widget-cdn-deploy-dev.yaml @@ -0,0 +1,15 @@ +name: widget-cdn-deploy-dev +description: Build and deploy widget assets to CDN (dev) +filename: devops/cloudbuild/widget-cdn-deploy.yaml +substitutions: + _BUCKET_NAME: swapkit-widget-cdn-dev + _USE_DEV_API: 'true' +repositoryEventConfig: + repository: projects/sk-ui-dev/locations/us-central1/connections/swapkit-org/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^develop$ +includedFiles: + - packages/ui/** + - devops/cloudbuild/widget-cdn-deploy.yaml +serviceAccount: projects/sk-ui-dev/serviceAccounts/cloudbuild@sk-ui-dev.iam.gserviceaccount.com diff --git a/devops/cloudbuild/trigger-widget-cdn-deploy-prod.yaml b/devops/cloudbuild/trigger-widget-cdn-deploy-prod.yaml new file mode 100644 index 0000000..b8bb8a9 --- /dev/null +++ b/devops/cloudbuild/trigger-widget-cdn-deploy-prod.yaml @@ -0,0 +1,15 @@ +name: widget-cdn-deploy-prod +description: Build and deploy widget assets to CDN (production) +filename: devops/cloudbuild/widget-cdn-deploy.yaml +substitutions: + _BUCKET_NAME: swapkit-widget-cdn-prod + _USE_DEV_API: 'false' +repositoryEventConfig: + repository: projects/sk-ui-prod/locations/us-central1/connections/sk/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^main$ +includedFiles: + - packages/ui/** + - devops/cloudbuild/widget-cdn-deploy.yaml +serviceAccount: projects/sk-ui-prod/serviceAccounts/cloudbuild@sk-ui-prod.iam.gserviceaccount.com diff --git a/devops/cloudbuild/trigger-widget-cdn-deploy-stage.yaml b/devops/cloudbuild/trigger-widget-cdn-deploy-stage.yaml new file mode 100644 index 0000000..1699a8a --- /dev/null +++ b/devops/cloudbuild/trigger-widget-cdn-deploy-stage.yaml @@ -0,0 +1,15 @@ +name: widget-cdn-deploy-stage +description: Build and deploy widget assets to CDN (staging) +filename: devops/cloudbuild/widget-cdn-deploy.yaml +substitutions: + _BUCKET_NAME: swapkit-widget-cdn-stage + _USE_DEV_API: 'false' +repositoryEventConfig: + repository: projects/sk-ui-stage/locations/us-central1/connections/sk/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^staging$ +includedFiles: + - packages/ui/** + - devops/cloudbuild/widget-cdn-deploy.yaml +serviceAccount: projects/sk-ui-stage/serviceAccounts/cloudbuild@sk-ui-stage.iam.gserviceaccount.com diff --git a/devops/cloudbuild/widget-cdn-deploy.yaml b/devops/cloudbuild/widget-cdn-deploy.yaml new file mode 100644 index 0000000..844a6ad --- /dev/null +++ b/devops/cloudbuild/widget-cdn-deploy.yaml @@ -0,0 +1,58 @@ +steps: + # 1. Install dependencies and build widget + - name: 'oven/bun:1' + entrypoint: 'bash' + env: + - 'SWAPKIT_USE_DEV_API=${_USE_DEV_API}' + args: + - '-c' + - | + bun install + bun run build + bun --cwd=packages/ui run build:widget + + # 2. Extract version from package.json + - name: 'gcr.io/cloud-builders/gcloud' + entrypoint: 'bash' + args: + - '-c' + - | + VERSION=$$(python3 -c "import json; print(json.load(open('packages/ui/package.json'))['version'])") + echo "Deploying widget v$$VERSION" + echo "$$VERSION" > /workspace/version.txt + + # 3. Upload to /widget/latest/ (mutable, no cache) + - name: 'gcr.io/cloud-builders/gsutil' + entrypoint: 'bash' + args: + - '-c' + - | + gsutil -m rsync -r -d packages/ui/dist/widget gs://${_BUCKET_NAME}/widget/latest + gsutil -m setmeta -h "Cache-Control:public, max-age=0, must-revalidate" \ + "gs://${_BUCKET_NAME}/widget/latest/**" + + # 4. Upload to /widget/v{version}/ (immutable, 1-year cache) + - name: 'gcr.io/cloud-builders/gsutil' + entrypoint: 'bash' + args: + - '-c' + - | + VERSION=$$(cat /workspace/version.txt) + if gsutil ls "gs://${_BUCKET_NAME}/widget/v$$VERSION/" >/dev/null 2>&1; then + echo "v$$VERSION already exists — skipping (immutable)" + else + gsutil -m cp -r packages/ui/dist/widget/* "gs://${_BUCKET_NAME}/widget/v$$VERSION/" + gsutil -m setmeta -h "Cache-Control:public, immutable, max-age=31536000" \ + "gs://${_BUCKET_NAME}/widget/v$$VERSION/**" + echo "Deployed v$$VERSION" + fi + +substitutions: + _BUCKET_NAME: 'swapkit-widget-cdn-dev' + _USE_DEV_API: 'true' + +options: + logging: CLOUD_LOGGING_ONLY + machineType: 'E2_HIGHCPU_32' + +timeout: '1200s' diff --git a/devops/terraform/cdn/CDN.md b/devops/terraform/cdn/CDN.md new file mode 100644 index 0000000..683034b --- /dev/null +++ b/devops/terraform/cdn/CDN.md @@ -0,0 +1,181 @@ +# Widget CDN Infrastructure + +Serves the SwapKit widget (``) as static JS from Google Cloud CDN behind Cloudflare, and routes `/studio` to the Cloud Run widget app. + +## Architecture + +``` +Client → Cloudflare (SSL + proxy) → Google Cloud CDN LB + ↓ + cdn-*.swapkit.dev: /widget/latest/ → GCS Bucket (always-fresh) + /widget/v1.2.3/ → GCS Bucket (immutable, 1-year cache) + + widget-*.swapkit.dev: /studio/* → Cloud Run (url_rewrite: /studio → /) +``` + +## Per-Environment Resources + +Each environment is identical and fully isolated in its own GCP project. + +| Resource | Dev (`sk-ui-dev`) | Stage (`sk-ui-stage`) | Prod (`sk-ui-prod`) | +|---|---|---|---| +| GCS Bucket | `swapkit-widget-cdn-dev` | `swapkit-widget-cdn-stage` | `swapkit-widget-cdn-prod` | +| Static IP | `34.50.157.176` | `136.110.188.26` | `34.49.56.104` | +| SSL Cert Domains | `cdn-dev-direct`, `widget-dev-direct` | `cdn-stage-direct`, `widget-stage-direct` | `cdn-direct`, `widget-direct` | +| CDN Domain (proxied) | `cdn-dev.swapkit.dev` | `cdn-stage.swapkit.dev` | `cdn.swapkit.dev` | +| CDN Direct Domain | `cdn-dev-direct.swapkit.dev` | `cdn-stage-direct.swapkit.dev` | `cdn-direct.swapkit.dev` | +| Studio Domain (proxied) | `widget-dev.swapkit.dev` | `widget-stage.swapkit.dev` | `widget.swapkit.dev` | +| Studio Direct Domain | `widget-dev-direct.swapkit.dev` | `widget-stage-direct.swapkit.dev` | `widget-direct.swapkit.dev` | +| Studio Enabled | Yes | Yes | Yes | + +## Terraform Structure + +``` +devops/terraform/cdn/ +├── cloudbuild.yaml # Parameterized: init → refresh → apply +├── trigger-config-dev.yaml # develop branch → sk-ui-dev +├── trigger-config-stage.yaml # staging branch → sk-ui-stage +├── trigger-config-prod.yaml # main branch → sk-ui-prod +├── sk-ui-dev/ # Dev terraform (project_id=sk-ui-dev) +├── sk-ui-stage/ # Stage terraform (project_id=sk-ui-stage) +└── sk-ui-prod/ # Prod terraform (project_id=sk-ui-prod) +``` + +Each project directory contains identical `main.tf`, `versions.tf`, `outputs.tf` with environment-specific `variables.tf` and `backend.tf`. + +### Terraform Resources (per environment) + +- `google_storage_bucket` — public GCS bucket with CORS +- `google_compute_backend_bucket` — Cloud CDN with CACHE_ALL_STATIC policy +- `google_compute_url_map` — routes `cdn-*` host to `/widget/*`, and (when `enable_studio=true`) `widget-*` host to `/studio/*` via Cloud Run +- `data.google_compute_backend_service` — references existing Cloud Run backend (conditional on `enable_studio`) +- `google_compute_global_address` — static external IP +- `google_compute_managed_ssl_certificate` — covers both CDN and studio `-direct` domains +- `google_compute_target_https_proxy` + `target_http_proxy` — HTTPS + HTTP→HTTPS redirect +- `google_compute_global_forwarding_rule` (x2) — port 80 + 443 + +### Studio Routing + +The `enable_studio` variable (bool) controls whether `/studio` routing is active. When enabled: + +1. A `data` source reads the existing `widget-backend-default` backend service (created by `playgrounds/vite-lite/terraform/`) +2. A dynamic `host_rule` matches the `studio_domain` and routes to a `studio-paths` path matcher +3. The path matcher uses `route_rules` with `prefix_match = "/studio"` and `path_prefix_rewrite = "/"` to strip the prefix before forwarding to Cloud Run + +To enable studio in stage/prod, deploy the Cloud Run widget service first (via `playgrounds/vite-lite/terraform//`), then set `enable_studio = true` in the CDN terraform variables. + +### State Backend + +All environments use `gs://sk-frontend-terraform-be` with prefixes: +- Dev: `cdn` +- Stage: `cdn/stage` +- Prod: `cdn/prod` + +## DNS Pattern + +Each domain served by this LB uses **two** Cloudflare DNS records (CDN domains and studio domains both follow this pattern): + +1. **Direct A record** (`*-direct.swapkit.dev`, not proxied) — points to the Google LB IP. Used for Google-managed SSL cert validation. +2. **Proxied CNAME** (`*.swapkit.dev`, proxied) — points to the direct record. Cloudflare terminates SSL and proxies to origin. + +Google-managed certs only cover the `-direct` domain because Cloudflare's proxy blocks Google's HTTP validation challenge on the proxied domain. Cloudflare provides its own SSL cert on the proxied endpoint. + +Total DNS records: **12** (2 per domain x 2 services x 3 environments). + +## Auto-Apply Triggers + +Infrastructure triggers fire on push to the environment's branch when `devops/terraform/cdn//**` changes: + +| Trigger | Project | Branch | +|---|---|---| +| `widget-cdn-infrastructure-dev` | `sk-ui-dev` | `develop` | +| `widget-cdn-infrastructure-stage` | `sk-ui-stage` | `staging` | +| `widget-cdn-infrastructure-prod` | `sk-ui-prod` | `main` | + +The `cloudbuild.yaml` uses a `_PROJECT_ID` substitution to target the correct terraform directory. + +## Manual Operations + +### Apply terraform manually +```bash +gcloud builds submit \ + --config=devops/terraform/cdn/cloudbuild.yaml \ + --project= --region=us-central1 \ + --service-account="projects//serviceAccounts/cloudbuild@.iam.gserviceaccount.com" \ + --substitutions=_PROJECT_ID= . +``` + +### Check cert status +```bash +# List all certs to find current name +gcloud compute ssl-certificates list --global --project= \ + --format="table(name,managed.status,managed.domainStatus)" +``` + +### Check static IP +```bash +gcloud compute addresses describe swapkit-widget-cdn-ip- \ + --global --project= --format="value(address)" +``` + +## Verification + +### Test end-to-end serving +```bash +# Upload a test file +echo '{"status":"ok"}' | gcloud storage cp - gs://swapkit-widget-cdn-prod/widget/latest/health.json --content-type="application/json" + +# Fetch through proxied CDN +curl -s https://cdn.swapkit.dev/widget/latest/health.json + +# Fetch through direct CDN +curl -s https://cdn-direct.swapkit.dev/widget/latest/health.json + +# Check response headers (CORS, caching) +curl -sI https://cdn.swapkit.dev/widget/latest/health.json + +# Clean up +gcloud storage rm gs://swapkit-widget-cdn-prod/widget/latest/health.json +``` + +Expected: 200 OK, `access-control-allow-origin: *`, correct `content-type`. + +### Verify DNS records +```bash +# All 12 records (6 CDN + 6 studio: direct A + proxied CNAME each) +curl -s -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records?per_page=100" \ + -H "X-Auth-Email: $CLOUDFLARE_EMAIL" -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \ + | python3 -c "import sys,json; [print(f'{r[\"name\"]:40s} {r[\"type\"]:6s} {r[\"content\"]}') for r in sorted(json.load(sys.stdin)['result'], key=lambda x: x['name']) if 'cdn' in r['name'] or 'widget' in r['name']]" +``` + +### Test studio routing (dev) +```bash +curl -sI https://widget-dev.swapkit.dev/studio +# Expected: 200 OK, content-type: text/html +``` + +## SSL Certificate Lifecycle + +Google-managed SSL certs are **immutable** — changing the domain list forces a destroy/recreate. Key gotchas: + +1. **`create_before_destroy`** is set in terraform, but the new cert must have a **different name** (Google won't create a cert with the same name as an existing one) +2. When domains change, **bump the version in the cert name** (e.g., `v4` → `v5`) in `main.tf` +3. Cert provisioning takes **15-60 minutes** after DNS is live +4. If a cert shows `FAILED_NOT_VISIBLE`, recreate it by bumping the name — Google gave up on validation and won't retry + +### CRITICAL: Cert Swap Causes HTTPS Downtime + +When a cert is recreated (domain list change), **HTTPS will be unavailable** until the new cert fully provisions. This is because: +- Terraform creates the new cert (PROVISIONING state), then attaches it to the HTTPS proxy, then destroys the old cert +- While the new cert is provisioning, the HTTPS proxy cannot complete TLS handshakes +- Cloudflare will return **HTTP 525 (SSL Handshake Failed)** on proxied domains during this window + +**Mitigation:** Schedule cert changes during low-traffic windows. The downtime is typically 5-15 minutes but can be up to 60 minutes. HTTP (port 80) redirects continue to work during this period. + +## IAM Requirements + +Each project's `cloudbuild@.iam.gserviceaccount.com` needs: +- `roles/storage.admin` — GCS bucket creation and IAM +- `roles/compute.loadBalancerAdmin` — forwarding rules, URL maps, proxies, backend buckets +- `roles/compute.networkAdmin` — global static IP +- `roles/certificatemanager.owner` — Google-managed SSL certificates diff --git a/devops/terraform/cdn/cloudbuild.yaml b/devops/terraform/cdn/cloudbuild.yaml new file mode 100644 index 0000000..6d4f0c0 --- /dev/null +++ b/devops/terraform/cdn/cloudbuild.yaml @@ -0,0 +1,45 @@ +# Deploy Widget CDN infrastructure +# Manages GCS bucket, Cloud CDN, load balancer, and SSL + +steps: + # Initialize Terraform + - name: 'hashicorp/terraform:latest' + entrypoint: 'sh' + args: + - '-c' + - | + cd devops/terraform/cdn/${_PROJECT_ID} + terraform init + env: + - 'TF_IN_AUTOMATION=true' + + # Refresh Terraform state to sync with GCP actual resources + - name: 'hashicorp/terraform:latest' + entrypoint: 'sh' + args: + - '-c' + - | + cd devops/terraform/cdn/${_PROJECT_ID} + terraform apply -refresh-only -auto-approve + env: + - 'TF_IN_AUTOMATION=true' + + # Apply Terraform configuration + - name: 'hashicorp/terraform:latest' + entrypoint: 'sh' + args: + - '-c' + - | + cd devops/terraform/cdn/${_PROJECT_ID} + terraform apply -auto-approve + env: + - 'TF_IN_AUTOMATION=true' + +substitutions: + _PROJECT_ID: 'sk-ui-dev' + +options: + logging: CLOUD_LOGGING_ONLY + machineType: 'E2_HIGHCPU_8' + +timeout: '900s' diff --git a/devops/terraform/cdn/sk-ui-dev/backend.tf b/devops/terraform/cdn/sk-ui-dev/backend.tf new file mode 100644 index 0000000..89ebfb6 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-dev/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "sk-frontend-terraform-be" + prefix = "cdn" + } +} diff --git a/devops/terraform/cdn/sk-ui-dev/main.tf b/devops/terraform/cdn/sk-ui-dev/main.tf new file mode 100644 index 0000000..784ccaf --- /dev/null +++ b/devops/terraform/cdn/sk-ui-dev/main.tf @@ -0,0 +1,176 @@ +locals { + labels = { + environment = var.environment + managed-by = "terraform" + project = "swapkit" + } +} + +# --- Cloud Storage Bucket --- + +resource "google_storage_bucket" "widget_cdn" { + name = var.bucket_name + location = var.region + storage_class = "STANDARD" + + uniform_bucket_level_access = true + + cors { + origin = ["*"] + method = ["GET", "HEAD"] + response_header = ["Content-Type", "Cache-Control", "Content-Length"] + max_age_seconds = 3600 + } + + labels = local.labels +} + +resource "google_storage_bucket_iam_member" "public_read" { + bucket = google_storage_bucket.widget_cdn.name + role = "roles/storage.objectViewer" + member = "allUsers" +} + +# --- Cloud CDN Backend Bucket --- + +resource "google_compute_backend_bucket" "widget_cdn" { + name = "swapkit-widget-cdn-backend-${var.environment}" + bucket_name = google_storage_bucket.widget_cdn.name + enable_cdn = true + + cdn_policy { + cache_mode = "CACHE_ALL_STATIC" + default_ttl = 3600 + max_ttl = 86400 + client_ttl = 3600 + negative_caching = true + serve_while_stale = 86400 + } +} + +# --- Studio Backend (Cloud Run) --- + +data "google_compute_backend_service" "widget" { + count = var.enable_studio ? 1 : 0 + name = var.studio_backend_service + project = var.project_id +} + +# --- URL Map --- + +resource "google_compute_url_map" "widget_cdn" { + name = "swapkit-widget-cdn-url-map-${var.environment}" + default_service = google_compute_backend_bucket.widget_cdn.id + + host_rule { + hosts = [var.cdn_domain] + path_matcher = "widget-paths" + } + + dynamic "host_rule" { + for_each = var.enable_studio ? [1] : [] + content { + hosts = [var.studio_domain] + path_matcher = "studio-paths" + } + } + + path_matcher { + name = "widget-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + path_rule { + paths = ["/widget/*"] + service = google_compute_backend_bucket.widget_cdn.id + } + } + + dynamic "path_matcher" { + for_each = var.enable_studio ? [1] : [] + content { + name = "studio-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + route_rules { + priority = 1 + service = data.google_compute_backend_service.widget[0].id + + match_rules { + prefix_match = "/studio" + } + + route_action { + url_rewrite { + path_prefix_rewrite = "/" + } + } + } + } + } +} + +# --- Global External IP --- + +resource "google_compute_global_address" "widget_cdn" { + name = "swapkit-widget-cdn-ip-${var.environment}" + address_type = "EXTERNAL" +} + +# --- Google-managed SSL Certificate --- + +resource "google_compute_managed_ssl_certificate" "widget_cdn" { + name = "swapkit-widget-cdn-cert-v5-${var.environment}" + + managed { + domains = compact([var.cdn_direct_domain, var.studio_direct_domain]) + } + + lifecycle { + create_before_destroy = true + } +} + +# --- HTTPS Proxy --- + +resource "google_compute_target_https_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-https-proxy-${var.environment}" + url_map = google_compute_url_map.widget_cdn.id + ssl_certificates = [google_compute_managed_ssl_certificate.widget_cdn.id] +} + +# --- HTTP → HTTPS Redirect --- + +resource "google_compute_url_map" "http_redirect" { + name = "swapkit-widget-cdn-http-redirect-${var.environment}" + + default_url_redirect { + https_redirect = true + redirect_response_code = "MOVED_PERMANENTLY_DEFAULT" + strip_query = false + } +} + +resource "google_compute_target_http_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-http-proxy-${var.environment}" + url_map = google_compute_url_map.http_redirect.id +} + +# --- Global Forwarding Rules --- + +resource "google_compute_global_forwarding_rule" "https" { + name = "swapkit-widget-cdn-https-${var.environment}" + target = google_compute_target_https_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "443" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} + +resource "google_compute_global_forwarding_rule" "http" { + name = "swapkit-widget-cdn-http-${var.environment}" + target = google_compute_target_http_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "80" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} diff --git a/devops/terraform/cdn/sk-ui-dev/outputs.tf b/devops/terraform/cdn/sk-ui-dev/outputs.tf new file mode 100644 index 0000000..0686dce --- /dev/null +++ b/devops/terraform/cdn/sk-ui-dev/outputs.tf @@ -0,0 +1,16 @@ +output "cdn_ip_address" { + description = "External IP address — point cdn.swapkit.dev DNS A record here" + value = google_compute_global_address.widget_cdn.address +} + +output "cdn_url" { + value = "https://${var.cdn_domain}" +} + +output "bucket_name" { + value = google_storage_bucket.widget_cdn.name +} + +output "widget_latest_url" { + value = "https://${var.cdn_domain}/widget/latest/swapkit-widget.js" +} diff --git a/devops/terraform/cdn/sk-ui-dev/variables.tf b/devops/terraform/cdn/sk-ui-dev/variables.tf new file mode 100644 index 0000000..4ebc4f5 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-dev/variables.tf @@ -0,0 +1,61 @@ +variable "project_id" { + description = "GCP project ID" + type = string + default = "sk-ui-dev" +} + +variable "region" { + description = "GCP region for resources" + type = string + default = "us-central1" +} + +variable "cdn_domain" { + description = "Domain name for the CDN" + type = string + default = "cdn-dev.swapkit.dev" +} + +variable "cdn_direct_domain" { + description = "Direct (non-proxied) domain name for SSL cert validation" + type = string + default = "cdn-dev-direct.swapkit.dev" +} + +variable "bucket_name" { + description = "Name of the GCS bucket for CDN storage" + type = string + default = "swapkit-widget-cdn-dev" +} + +variable "environment" { + description = "Deployment environment (dev, staging, production)" + type = string + default = "dev" +} + +# --- Studio (Cloud Run widget app) --- + +variable "enable_studio" { + description = "Enable /studio routing to Cloud Run backend service" + type = bool + default = true +} + +variable "studio_domain" { + description = "Proxied domain for the studio app" + type = string + default = "widget-dev.swapkit.dev" +} + +variable "studio_direct_domain" { + description = "Direct (non-proxied) domain for SSL cert validation" + type = string + default = "widget-dev-direct.swapkit.dev" +} + +variable "studio_backend_service" { + description = "Name of the existing Cloud Run backend service" + type = string + default = "widget-backend-default" +} diff --git a/devops/terraform/cdn/sk-ui-dev/versions.tf b/devops/terraform/cdn/sk-ui-dev/versions.tf new file mode 100644 index 0000000..42bc1e6 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-dev/versions.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 5.0.0" + } + } +} + +provider "google" { + project = var.project_id + region = var.region +} diff --git a/devops/terraform/cdn/sk-ui-prod/backend.tf b/devops/terraform/cdn/sk-ui-prod/backend.tf new file mode 100644 index 0000000..2f309df --- /dev/null +++ b/devops/terraform/cdn/sk-ui-prod/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "sk-frontend-terraform-be" + prefix = "cdn/prod" + } +} diff --git a/devops/terraform/cdn/sk-ui-prod/main.tf b/devops/terraform/cdn/sk-ui-prod/main.tf new file mode 100644 index 0000000..fa042e5 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-prod/main.tf @@ -0,0 +1,176 @@ +locals { + labels = { + environment = var.environment + managed-by = "terraform" + project = "swapkit" + } +} + +# --- Cloud Storage Bucket --- + +resource "google_storage_bucket" "widget_cdn" { + name = var.bucket_name + location = var.region + storage_class = "STANDARD" + + uniform_bucket_level_access = true + + cors { + origin = ["*"] + method = ["GET", "HEAD"] + response_header = ["Content-Type", "Cache-Control", "Content-Length"] + max_age_seconds = 3600 + } + + labels = local.labels +} + +resource "google_storage_bucket_iam_member" "public_read" { + bucket = google_storage_bucket.widget_cdn.name + role = "roles/storage.objectViewer" + member = "allUsers" +} + +# --- Cloud CDN Backend Bucket --- + +resource "google_compute_backend_bucket" "widget_cdn" { + name = "swapkit-widget-cdn-backend-${var.environment}" + bucket_name = google_storage_bucket.widget_cdn.name + enable_cdn = true + + cdn_policy { + cache_mode = "CACHE_ALL_STATIC" + default_ttl = 3600 + max_ttl = 86400 + client_ttl = 3600 + negative_caching = true + serve_while_stale = 86400 + } +} + +# --- Studio Backend (Cloud Run) --- + +data "google_compute_backend_service" "widget" { + count = var.enable_studio ? 1 : 0 + name = var.studio_backend_service + project = var.project_id +} + +# --- URL Map --- + +resource "google_compute_url_map" "widget_cdn" { + name = "swapkit-widget-cdn-url-map-${var.environment}" + default_service = google_compute_backend_bucket.widget_cdn.id + + host_rule { + hosts = [var.cdn_domain] + path_matcher = "widget-paths" + } + + dynamic "host_rule" { + for_each = var.enable_studio ? [1] : [] + content { + hosts = [var.studio_domain] + path_matcher = "studio-paths" + } + } + + path_matcher { + name = "widget-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + path_rule { + paths = ["/widget/*"] + service = google_compute_backend_bucket.widget_cdn.id + } + } + + dynamic "path_matcher" { + for_each = var.enable_studio ? [1] : [] + content { + name = "studio-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + route_rules { + priority = 1 + service = data.google_compute_backend_service.widget[0].id + + match_rules { + prefix_match = "/studio" + } + + route_action { + url_rewrite { + path_prefix_rewrite = "/" + } + } + } + } + } +} + +# --- Global External IP --- + +resource "google_compute_global_address" "widget_cdn" { + name = "swapkit-widget-cdn-ip-${var.environment}" + address_type = "EXTERNAL" +} + +# --- Google-managed SSL Certificate --- + +resource "google_compute_managed_ssl_certificate" "widget_cdn" { + name = "swapkit-widget-cdn-cert-v4-${var.environment}" + + managed { + domains = compact([var.cdn_direct_domain, var.studio_direct_domain]) + } + + lifecycle { + create_before_destroy = true + } +} + +# --- HTTPS Proxy --- + +resource "google_compute_target_https_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-https-proxy-${var.environment}" + url_map = google_compute_url_map.widget_cdn.id + ssl_certificates = [google_compute_managed_ssl_certificate.widget_cdn.id] +} + +# --- HTTP → HTTPS Redirect --- + +resource "google_compute_url_map" "http_redirect" { + name = "swapkit-widget-cdn-http-redirect-${var.environment}" + + default_url_redirect { + https_redirect = true + redirect_response_code = "MOVED_PERMANENTLY_DEFAULT" + strip_query = false + } +} + +resource "google_compute_target_http_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-http-proxy-${var.environment}" + url_map = google_compute_url_map.http_redirect.id +} + +# --- Global Forwarding Rules --- + +resource "google_compute_global_forwarding_rule" "https" { + name = "swapkit-widget-cdn-https-${var.environment}" + target = google_compute_target_https_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "443" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} + +resource "google_compute_global_forwarding_rule" "http" { + name = "swapkit-widget-cdn-http-${var.environment}" + target = google_compute_target_http_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "80" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} diff --git a/devops/terraform/cdn/sk-ui-prod/outputs.tf b/devops/terraform/cdn/sk-ui-prod/outputs.tf new file mode 100644 index 0000000..0686dce --- /dev/null +++ b/devops/terraform/cdn/sk-ui-prod/outputs.tf @@ -0,0 +1,16 @@ +output "cdn_ip_address" { + description = "External IP address — point cdn.swapkit.dev DNS A record here" + value = google_compute_global_address.widget_cdn.address +} + +output "cdn_url" { + value = "https://${var.cdn_domain}" +} + +output "bucket_name" { + value = google_storage_bucket.widget_cdn.name +} + +output "widget_latest_url" { + value = "https://${var.cdn_domain}/widget/latest/swapkit-widget.js" +} diff --git a/devops/terraform/cdn/sk-ui-prod/variables.tf b/devops/terraform/cdn/sk-ui-prod/variables.tf new file mode 100644 index 0000000..b2e1d5b --- /dev/null +++ b/devops/terraform/cdn/sk-ui-prod/variables.tf @@ -0,0 +1,61 @@ +variable "project_id" { + description = "GCP project ID" + type = string + default = "sk-ui-prod" +} + +variable "region" { + description = "GCP region for resources" + type = string + default = "us-central1" +} + +variable "cdn_domain" { + description = "Domain name for the CDN" + type = string + default = "cdn.swapkit.dev" +} + +variable "cdn_direct_domain" { + description = "Direct (non-proxied) domain name for SSL cert validation" + type = string + default = "cdn-direct.swapkit.dev" +} + +variable "bucket_name" { + description = "Name of the GCS bucket for CDN storage" + type = string + default = "swapkit-widget-cdn-prod" +} + +variable "environment" { + description = "Deployment environment (dev, staging, production)" + type = string + default = "production" +} + +# --- Studio (Cloud Run widget app) --- + +variable "enable_studio" { + description = "Enable /studio routing to Cloud Run backend service" + type = bool + default = true +} + +variable "studio_domain" { + description = "Proxied domain for the studio app" + type = string + default = "widget.swapkit.dev" +} + +variable "studio_direct_domain" { + description = "Direct (non-proxied) domain for SSL cert validation" + type = string + default = "widget-direct.swapkit.dev" +} + +variable "studio_backend_service" { + description = "Name of the existing Cloud Run backend service" + type = string + default = "widget-backend-default" +} diff --git a/devops/terraform/cdn/sk-ui-prod/versions.tf b/devops/terraform/cdn/sk-ui-prod/versions.tf new file mode 100644 index 0000000..42bc1e6 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-prod/versions.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 5.0.0" + } + } +} + +provider "google" { + project = var.project_id + region = var.region +} diff --git a/devops/terraform/cdn/sk-ui-stage/backend.tf b/devops/terraform/cdn/sk-ui-stage/backend.tf new file mode 100644 index 0000000..bb9596a --- /dev/null +++ b/devops/terraform/cdn/sk-ui-stage/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "sk-frontend-terraform-be" + prefix = "cdn/stage" + } +} diff --git a/devops/terraform/cdn/sk-ui-stage/main.tf b/devops/terraform/cdn/sk-ui-stage/main.tf new file mode 100644 index 0000000..784ccaf --- /dev/null +++ b/devops/terraform/cdn/sk-ui-stage/main.tf @@ -0,0 +1,176 @@ +locals { + labels = { + environment = var.environment + managed-by = "terraform" + project = "swapkit" + } +} + +# --- Cloud Storage Bucket --- + +resource "google_storage_bucket" "widget_cdn" { + name = var.bucket_name + location = var.region + storage_class = "STANDARD" + + uniform_bucket_level_access = true + + cors { + origin = ["*"] + method = ["GET", "HEAD"] + response_header = ["Content-Type", "Cache-Control", "Content-Length"] + max_age_seconds = 3600 + } + + labels = local.labels +} + +resource "google_storage_bucket_iam_member" "public_read" { + bucket = google_storage_bucket.widget_cdn.name + role = "roles/storage.objectViewer" + member = "allUsers" +} + +# --- Cloud CDN Backend Bucket --- + +resource "google_compute_backend_bucket" "widget_cdn" { + name = "swapkit-widget-cdn-backend-${var.environment}" + bucket_name = google_storage_bucket.widget_cdn.name + enable_cdn = true + + cdn_policy { + cache_mode = "CACHE_ALL_STATIC" + default_ttl = 3600 + max_ttl = 86400 + client_ttl = 3600 + negative_caching = true + serve_while_stale = 86400 + } +} + +# --- Studio Backend (Cloud Run) --- + +data "google_compute_backend_service" "widget" { + count = var.enable_studio ? 1 : 0 + name = var.studio_backend_service + project = var.project_id +} + +# --- URL Map --- + +resource "google_compute_url_map" "widget_cdn" { + name = "swapkit-widget-cdn-url-map-${var.environment}" + default_service = google_compute_backend_bucket.widget_cdn.id + + host_rule { + hosts = [var.cdn_domain] + path_matcher = "widget-paths" + } + + dynamic "host_rule" { + for_each = var.enable_studio ? [1] : [] + content { + hosts = [var.studio_domain] + path_matcher = "studio-paths" + } + } + + path_matcher { + name = "widget-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + path_rule { + paths = ["/widget/*"] + service = google_compute_backend_bucket.widget_cdn.id + } + } + + dynamic "path_matcher" { + for_each = var.enable_studio ? [1] : [] + content { + name = "studio-paths" + default_service = google_compute_backend_bucket.widget_cdn.id + + route_rules { + priority = 1 + service = data.google_compute_backend_service.widget[0].id + + match_rules { + prefix_match = "/studio" + } + + route_action { + url_rewrite { + path_prefix_rewrite = "/" + } + } + } + } + } +} + +# --- Global External IP --- + +resource "google_compute_global_address" "widget_cdn" { + name = "swapkit-widget-cdn-ip-${var.environment}" + address_type = "EXTERNAL" +} + +# --- Google-managed SSL Certificate --- + +resource "google_compute_managed_ssl_certificate" "widget_cdn" { + name = "swapkit-widget-cdn-cert-v5-${var.environment}" + + managed { + domains = compact([var.cdn_direct_domain, var.studio_direct_domain]) + } + + lifecycle { + create_before_destroy = true + } +} + +# --- HTTPS Proxy --- + +resource "google_compute_target_https_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-https-proxy-${var.environment}" + url_map = google_compute_url_map.widget_cdn.id + ssl_certificates = [google_compute_managed_ssl_certificate.widget_cdn.id] +} + +# --- HTTP → HTTPS Redirect --- + +resource "google_compute_url_map" "http_redirect" { + name = "swapkit-widget-cdn-http-redirect-${var.environment}" + + default_url_redirect { + https_redirect = true + redirect_response_code = "MOVED_PERMANENTLY_DEFAULT" + strip_query = false + } +} + +resource "google_compute_target_http_proxy" "widget_cdn" { + name = "swapkit-widget-cdn-http-proxy-${var.environment}" + url_map = google_compute_url_map.http_redirect.id +} + +# --- Global Forwarding Rules --- + +resource "google_compute_global_forwarding_rule" "https" { + name = "swapkit-widget-cdn-https-${var.environment}" + target = google_compute_target_https_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "443" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} + +resource "google_compute_global_forwarding_rule" "http" { + name = "swapkit-widget-cdn-http-${var.environment}" + target = google_compute_target_http_proxy.widget_cdn.id + ip_address = google_compute_global_address.widget_cdn.address + port_range = "80" + load_balancing_scheme = "EXTERNAL" + labels = local.labels +} diff --git a/devops/terraform/cdn/sk-ui-stage/outputs.tf b/devops/terraform/cdn/sk-ui-stage/outputs.tf new file mode 100644 index 0000000..0686dce --- /dev/null +++ b/devops/terraform/cdn/sk-ui-stage/outputs.tf @@ -0,0 +1,16 @@ +output "cdn_ip_address" { + description = "External IP address — point cdn.swapkit.dev DNS A record here" + value = google_compute_global_address.widget_cdn.address +} + +output "cdn_url" { + value = "https://${var.cdn_domain}" +} + +output "bucket_name" { + value = google_storage_bucket.widget_cdn.name +} + +output "widget_latest_url" { + value = "https://${var.cdn_domain}/widget/latest/swapkit-widget.js" +} diff --git a/devops/terraform/cdn/sk-ui-stage/variables.tf b/devops/terraform/cdn/sk-ui-stage/variables.tf new file mode 100644 index 0000000..80b0d5d --- /dev/null +++ b/devops/terraform/cdn/sk-ui-stage/variables.tf @@ -0,0 +1,61 @@ +variable "project_id" { + description = "GCP project ID" + type = string + default = "sk-ui-stage" +} + +variable "region" { + description = "GCP region for resources" + type = string + default = "us-central1" +} + +variable "cdn_domain" { + description = "Domain name for the CDN" + type = string + default = "cdn-stage.swapkit.dev" +} + +variable "cdn_direct_domain" { + description = "Direct (non-proxied) domain name for SSL cert validation" + type = string + default = "cdn-stage-direct.swapkit.dev" +} + +variable "bucket_name" { + description = "Name of the GCS bucket for CDN storage" + type = string + default = "swapkit-widget-cdn-stage" +} + +variable "environment" { + description = "Deployment environment (dev, staging, production)" + type = string + default = "staging" +} + +# --- Studio (Cloud Run widget app) --- + +variable "enable_studio" { + description = "Enable /studio routing to Cloud Run backend service" + type = bool + default = true +} + +variable "studio_domain" { + description = "Proxied domain for the studio app" + type = string + default = "widget-stage.swapkit.dev" +} + +variable "studio_direct_domain" { + description = "Direct (non-proxied) domain for SSL cert validation" + type = string + default = "widget-stage-direct.swapkit.dev" +} + +variable "studio_backend_service" { + description = "Name of the existing Cloud Run backend service" + type = string + default = "widget-backend-default" +} diff --git a/devops/terraform/cdn/sk-ui-stage/versions.tf b/devops/terraform/cdn/sk-ui-stage/versions.tf new file mode 100644 index 0000000..42bc1e6 --- /dev/null +++ b/devops/terraform/cdn/sk-ui-stage/versions.tf @@ -0,0 +1,15 @@ +terraform { + required_version = ">= 1.5.0" + + required_providers { + google = { + source = "hashicorp/google" + version = ">= 5.0.0" + } + } +} + +provider "google" { + project = var.project_id + region = var.region +} diff --git a/devops/terraform/cdn/trigger-config-dev.yaml b/devops/terraform/cdn/trigger-config-dev.yaml new file mode 100644 index 0000000..b5828c4 --- /dev/null +++ b/devops/terraform/cdn/trigger-config-dev.yaml @@ -0,0 +1,14 @@ +name: widget-cdn-infrastructure-dev +description: Deploy Widget CDN infrastructure (dev) on Terraform changes +filename: devops/terraform/cdn/cloudbuild.yaml +substitutions: + _PROJECT_ID: sk-ui-dev +repositoryEventConfig: + repository: projects/sk-ui-dev/locations/us-central1/connections/swapkit-org/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^develop$ +includedFiles: + - devops/terraform/cdn/sk-ui-dev/** + - devops/terraform/cdn/cloudbuild.yaml +serviceAccount: projects/sk-ui-dev/serviceAccounts/cloudbuild@sk-ui-dev.iam.gserviceaccount.com diff --git a/devops/terraform/cdn/trigger-config-prod.yaml b/devops/terraform/cdn/trigger-config-prod.yaml new file mode 100644 index 0000000..72a8169 --- /dev/null +++ b/devops/terraform/cdn/trigger-config-prod.yaml @@ -0,0 +1,14 @@ +name: widget-cdn-infrastructure-prod +description: Deploy Widget CDN infrastructure (production) on Terraform changes +filename: devops/terraform/cdn/cloudbuild.yaml +substitutions: + _PROJECT_ID: sk-ui-prod +repositoryEventConfig: + repository: projects/sk-ui-prod/locations/us-central1/connections/sk/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^main$ +includedFiles: + - devops/terraform/cdn/sk-ui-prod/** + - devops/terraform/cdn/cloudbuild.yaml +serviceAccount: projects/sk-ui-prod/serviceAccounts/cloudbuild@sk-ui-prod.iam.gserviceaccount.com diff --git a/devops/terraform/cdn/trigger-config-stage.yaml b/devops/terraform/cdn/trigger-config-stage.yaml new file mode 100644 index 0000000..cde131a --- /dev/null +++ b/devops/terraform/cdn/trigger-config-stage.yaml @@ -0,0 +1,14 @@ +name: widget-cdn-infrastructure-stage +description: Deploy Widget CDN infrastructure (staging) on Terraform changes +filename: devops/terraform/cdn/cloudbuild.yaml +substitutions: + _PROJECT_ID: sk-ui-stage +repositoryEventConfig: + repository: projects/sk-ui-stage/locations/us-central1/connections/sk/repositories/swapkit-wallets + repositoryType: GITHUB + push: + branch: ^staging$ +includedFiles: + - devops/terraform/cdn/sk-ui-stage/** + - devops/terraform/cdn/cloudbuild.yaml +serviceAccount: projects/sk-ui-stage/serviceAccounts/cloudbuild@sk-ui-stage.iam.gserviceaccount.com diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..1e227b0 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,8 @@ +pre-commit: + commands: + lint: + glob: "*.{jsx,tsx,ts,js,json}" + run: bun biome check --write --no-errors-on-unmatched {staged_files} && git add {staged_files} + type-check: + glob: "*.{ts,tsx}" + run: bun type-check diff --git a/package.json b/package.json index f645f36..8fd4c2e 100644 --- a/package.json +++ b/package.json @@ -16,13 +16,24 @@ "@swapkit/wallet-keystore": "^4.4.1", "@types/bun": "1.3.13", "@types/node": "25.6.0", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "caniuse-lite": "1.0.30001776", + "happy-dom": "^20.8.9", "ledger-bitcoin": "0.3.0", + "lefthook": "2.1.2", "typescript": "6.0.3", "zod": "4.4.3" }, "name": "swapkit-wallets", - "overrides": { "nuqs": "2.8.9" }, - "packageManager": "bun@1.3.4", + "overrides": { + "@swapkit/helpers": "4.14.0", + "@swapkit/types": "0.8.0", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "nuqs": "2.8.9" + }, + "packageManager": "bun@1.3.9", "private": true, "scripts": { "build": "bun run --filter './packages/*' build", @@ -32,7 +43,8 @@ "changeset": "bunx changeset", "lint": "bun biome check --fix .", "lint:ws": "bunx sherif@latest", - "postinstall": "bun lint:ws", + "playground:vite-lite": "bun --cwd=./playgrounds/vite-lite", + "postinstall": "lefthook install; bun lint:ws", "publish-packages": "bun run build:ci && bun run ./tools/builder/set-versions.ts && bunx changeset publish", "test": "bun test", "type-check": "bun run --filter './packages/*' type-check", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index e595472..f64921d 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -45,21 +45,12 @@ "types": "./dist/types/wallets.d.ts" } }, - "files": [ - "dist/", - "src/" - ], + "files": ["dist/", "src/"], "homepage": "https://github.com/swapkit/wallets", "license": "SEE LICENSE IN LICENSE", "name": "@swapkit/sdk", - "publishConfig": { - "access": "public" - }, - "repository": { - "directory": "packages/sdk", - "type": "git", - "url": "git+https://github.com/swapkit/wallets.git" - }, + "publishConfig": { "access": "public" }, + "repository": { "directory": "packages/sdk", "type": "git", "url": "git+https://github.com/swapkit/wallets.git" }, "scripts": { "build": "bun run ./build.ts", "build:clean": "rm -rf dist && bun run ./build.ts", diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md new file mode 100644 index 0000000..774980a --- /dev/null +++ b/packages/ui/CHANGELOG.md @@ -0,0 +1,310 @@ +# @swapkit/ui + +## 0.19.1 + +### Patch Changes + +- [`9fd99aa`](https://github.com/swapkit/ui/commit/9fd99aad6159da2908cefbe8d530774949239bbf) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - Declare SwapKit peer dependencies required by toolbox consumers and keep balance refresh available for connected zero-balance wallets. + +## 0.19.0 + +### Minor Changes + +- [#113](https://github.com/swapkit/ui/pull/113) [`417ccf7`](https://github.com/swapkit/ui/commit/417ccf72f734a22a17bffb1525311a5346121086) Thanks [@towanTG](https://github.com/towanTG)! - Wallet drawer + connect-wallet flow improvements, plus a SwapKit dependency bump. + + - **Wallet drawer grouped by wallet.** Connected chains are now grouped under a per-wallet header (avatar, name, "N chains · M tokens", total USD) that collapses/expands when more than one wallet is connected; a single wallet renders as a flat label. The Connect-wallet action is always visible, pinned above Disconnect, and uses a generic label (no input/output chain reference). Disconnect reads "Disconnect all" when multiple wallets are connected. + - **Main swap button connect logic.** The button shows a plain "Connect wallet" while there is no wallet connected and no quote yet — clicking it opens the generic connect dialog. The chain-specific connect flow only triggers once a route exists, and the input chain (what the user pays from) is always resolved before the output chain. + - **Dependency bump:** `@swapkit/core@4.4.31`, `@swapkit/helpers@4.13.13`, `@swapkit/plugins@4.6.45`, `@swapkit/toolboxes@4.16.2`, `@swapkit/wallet-keystore@4.3.37`, `@swapkit/wallets@4.8.22`. + +## 0.18.2 + +### Patch Changes + +- [#110](https://github.com/swapkit/ui/pull/110) [`7128a31`](https://github.com/swapkit/ui/commit/7128a31bd59a28cbdfb635ee99c4c2ef8b0cea74) Thanks [@towanTG](https://github.com/towanTG)! - Bump SwapKit packages to the latest releases, including wallets 4.8.19, and apply developer-mode chain filtering consistently in the wallet connect dialog. Ledger Litecoin is no longer hidden behind developer mode. + +## 0.18.1 + +### Patch Changes + +- [#106](https://github.com/swapkit/ui/pull/106) [`349a199`](https://github.com/swapkit/ui/commit/349a1996d13129b13aabcfa2aa477bb117095456) Thanks [@towanTG](https://github.com/towanTG)! - Bump SwapKit package dependencies to their latest patch releases (`@swapkit/core@4.4.28`, `@swapkit/helpers@4.13.11`, `@swapkit/plugins@4.6.42`, `@swapkit/toolboxes@4.15.15`, `@swapkit/wallet-keystore@4.3.34`, `@swapkit/wallets@4.8.18`). + +- [#107](https://github.com/swapkit/ui/pull/107) [`67da9b1`](https://github.com/swapkit/ui/commit/67da9b1a7b47caf75601c08835cd03190142d4c1) Thanks [@towanTG](https://github.com/towanTG)! - Validate `getRouteWithTx` amount fields before calling `swap`, matching the stricter SwapKit route type required by the latest helpers/core packages. + +## 0.18.0 + +### Minor Changes + +- [#103](https://github.com/swapkit/ui/pull/103) [`0c379f9`](https://github.com/swapkit/ui/commit/0c379f942ef32a5135d233563893c49bace0dc84) Thanks [@towanTG](https://github.com/towanTG)! - **Chains configuration + redesigned wallet rows in the studio.** + + Adds a new **Chains** section to the studio's Settings tab letting integrators restrict the chain set the widget operates on. Disabling a chain hides it from the asset selector and auto-disables wallets whose required chains are all gone (Ripple → Xaman, Radix → Radix Wallet, all Cosmos chains → Keplr / Leap). The change is full-stack: + + - React widget gains a `chains` prop (`Chain[] | "all" | { include } | { exclude }`, mirroring `wallets`). + - Web component gains `chains` / `chains-include` / `chains-exclude` attributes; the snippet generator emits them when the user picks anything other than "all". + - `SwapKitConfigProvider` exposes `enabledChains` and `isChainAllowed`; the asset-select chain filter, popular-chain pills, asset list hook, and wallet-connect dialog all honour the gate. + - New `lib/chain-catalog.ts` declares the 32 controllable chains, preset groupings (All / EVM only / BTC + ETH / Cosmos / UTXO), and the chain → required-wallets dependency map. + + Also redesigns the **Wallet Configuration** rows in the same tab. The single-line layout was wrapping to 5+ visual lines at the sidebar's 380px width. New row: glyph · name · status tag (Needs config / Ready / Disabled) on the title line, description + doc link on the sub-line, switch + chevron-to-configure on the right. Fields expand inline below the row instead of all at once. Sort order: needs-config → ready → disabled. + +### Patch Changes + +- [#98](https://github.com/swapkit/ui/pull/98) [`d4ed0e2`](https://github.com/swapkit/ui/commit/d4ed0e20b472635ea894524d61eb3364f0a87af3) Thanks [@towanTG](https://github.com/towanTG)! - Drop `React.forwardRef` across all UI primitives (accordion, button, card, checkbox, chip, dialog, form, input, label, separator, sheet, sidebar, tabs, textarea, tooltip) — React 19 accepts `ref` as a regular prop. Ref types are widened to `React.Ref` so callback refs from libraries like React Hook Form still work. Behaviour is unchanged. Also drops three unused biome suppression comments and refactors `` `getConfig` into smaller helpers to clear a cognitive-complexity warning. + +## 0.17.0 + +### Minor Changes + +- [#96](https://github.com/swapkit/ui/pull/96) [`d8bca4a`](https://github.com/swapkit/ui/commit/d8bca4acd4f32540498a31ab014cdfbb8d0d37aa) Thanks [@towanTG](https://github.com/towanTG)! - Gate KeepKey, Vultisig, and Litecoin-on-Ledger behind the dev-mode flag. In production builds they're hidden from the wallet connect dialog, the studio sidebar wallet selector, and (for LTC-on-Ledger) the chain select dialog. In dev mode they remain visible but are tagged with a "DEV" badge so the wallets repo can iterate on them through this UI. + + The dev signal is `SKConfig.envs.isDev`, which is wired to the studio's `developMode` toggle, the web component's `develop-mode` attribute, and the `__SWAPKIT_IS_DEV__` compile-time default (`SWAPKIT_USE_DEV_API=true` at build). + +### Patch Changes + +- [#92](https://github.com/swapkit/ui/pull/92) [`c9213b0`](https://github.com/swapkit/ui/commit/c9213b035ba0165ff2f518c12533f28eac91930f) Thanks [@towanTG](https://github.com/towanTG)! - Bump SwapKit dependencies and limit swap confirmation amounts to 10 significant digits. + +- [#92](https://github.com/swapkit/ui/pull/92) [`c9213b0`](https://github.com/swapkit/ui/commit/c9213b035ba0165ff2f518c12533f28eac91930f) Thanks [@towanTG](https://github.com/towanTG)! - Remove the "Customised" / "Defaults" label from the studio sidebar footer. The Reset button's disabled state already communicates whether the config differs from defaults, so the label was redundant. + +## 0.16.5 + +### Patch Changes + +- [#88](https://github.com/swapkit/ui/pull/88) [`74cefd7`](https://github.com/swapkit/ui/commit/74cefd7a575ad97bcce020a0ec4d84f11f90dc77) Thanks [@towanTG](https://github.com/towanTG)! - Add input-chain wallet connection actions when a quote exists but the connected wallet does not cover the pay asset chain. + +- [#87](https://github.com/swapkit/ui/pull/87) [`b3ce60b`](https://github.com/swapkit/ui/commit/b3ce60b61b4146f345aa0ab9cdd8c4862599cc6e) Thanks [@towanTG](https://github.com/towanTG)! - Persist tracker polling metadata with transaction history and schedule pending transaction checks with backoff, visibility gating, and a per-tick request cap. + +## 0.16.4 + +### Patch Changes + +- [#84](https://github.com/swapkit/ui/pull/84) [`d4c1c0a`](https://github.com/swapkit/ui/commit/d4c1c0ac580bfc6862638070d91ad72c98761fde) Thanks [@towanTG](https://github.com/towanTG)! - Use wallet-level UTXO xpub discovery before hardware address selection, then bind the selected derived address on final connect. + +## 0.16.3 + +### Patch Changes + +- [#81](https://github.com/swapkit/ui/pull/81) [`170f352`](https://github.com/swapkit/ui/commit/170f3528aab5ea3134a1946a8320f3b5311efbe7) Thanks [@towanTG](https://github.com/towanTG)! - Bump `@swapkit/wallets` to 4.8.12. + +- [#81](https://github.com/swapkit/ui/pull/81) [`170f352`](https://github.com/swapkit/ui/commit/170f3528aab5ea3134a1946a8320f3b5311efbe7) Thanks [@towanTG](https://github.com/towanTG)! - Request the send-chain wallet connection before swap execution when a quote exists but the input chain is not connected. + +## 0.16.2 + +### Patch Changes + +- [#78](https://github.com/swapkit/ui/pull/78) [`9d6ede4`](https://github.com/swapkit/ui/commit/9d6ede4022d17da75cb64791567e280ecb191d7a) Thanks [@towanTG](https://github.com/towanTG)! - Bump `@swapkit/wallets` to 4.8.11 and keep web-component swap state local so embedded widgets do not refresh when assets change. + +## 0.16.1 + +### Patch Changes + +- [#74](https://github.com/swapkit/ui/pull/74) [`d74ed28`](https://github.com/swapkit/ui/commit/d74ed28b2ca28b3808b7a19ace338a3dd0e2cc7e) Thanks [@towanTG](https://github.com/towanTG)! - Enable the UTXO xpub address selection flow for Trezor hardware wallets. + +## 0.16.0 + +### Minor Changes + +- [#68](https://github.com/swapkit/ui/pull/68) [`d14e317`](https://github.com/swapkit/ui/commit/d14e317b0ec9a54588d066f89b21c60184ab962c) Thanks [@towanTG](https://github.com/towanTG)! - Studio sidebar — new "Wallet configuration" section under Settings. + + Lets developers persist wallet/integration credentials (`apiKeys.walletConnectProjectId`, `apiKeys.xaman`, `apiKeys.passkeys`, `apiKeys.keepKey`, plus `integrations.{coinbase, nearWalletSelector, trezor, keepKey, radix}`) directly in the studio. Persisted to localStorage alongside the rest of the form, applied to `SKConfig` immediately and on next page load so the studio's live preview reflects the values. + + Each wallet's block: + + - Header with the wallet name + "Get it →" link to where the credential is acquired (cloud.reown.com, apps.xumm.dev, console.radixdlt.com, etc.). + - Inline `Missing` badge when an enabled wallet's required field is empty. + - Top-of-section warning banner when any enabled wallet is missing a hard-required field. + + The configurator-side picker continues to surface the full wallet list regardless of mobile UA — only the connect dialog filters to mobile-supported wallets. + +- [#68](https://github.com/swapkit/ui/pull/68) [`d14e317`](https://github.com/swapkit/ui/commit/d14e317b0ec9a54588d066f89b21c60184ab962c) Thanks [@towanTG](https://github.com/towanTG)! - Wallet config now flows from the studio into the embed snippet and the deployed `` web component. + + **Snippet generator** — when any wallet/integration credential is set, emits a JSON `config` attribute on the `` element next to `widget-id` / `widget-key`. The payload is the same partial `SKConfig.set` shape the studio's live preview already feeds into the SDK (apiKeys + integrations, with empty fields filtered). + + **Web component** — `config` is now an `observedAttribute`. `getConfig()` parses it as JSON; `renderWidget()` applies it via `SKConfig.set` before any wallet connect runs, so the widget's `SwapKit()` client picks up the credentials at construct time. Bad JSON is `console.warn`'d and ignored — doesn't crash the widget. + + **Wallet config blocks** in the studio sidebar now sort dynamically: blocks missing a hard-required field bubble to the top, then blocks with any required spec, then recommended-only / NEAR. Original order is the tiebreaker so the layout stays stable as users fill things in. + + **Per-wallet enable toggle** — each wallet config block has a compact switch on the right side of its header that toggles `enabledWalletOptions` in sync with the wallet picker below. + +### Patch Changes + +- [#70](https://github.com/swapkit/ui/pull/70) [`6c8d007`](https://github.com/swapkit/ui/commit/6c8d00724a5384bb18f48c89a40c1c4d188721e7) Thanks [@towanTG](https://github.com/towanTG)! - Fix `apiKeyInvalid` on the very first `SwapKitApi.*` request after `` mounts. + + `useSwapTo` is declared earlier in `` than the `applyAuthConfig` `useEffect`, and React fires effects in declaration order — so swap-to fired its fetch before the widget had a chance to write `widgetId/widgetKey` (or `apiKeys.swapKit`) into `SKConfig`. The helpers' `dynamicHeader` callback returned `{}`, the request shipped without auth, and the API responded `{"error":"apiKeyInvalid","message":"Invalid API key"}`. + + Apply auth synchronously during the first render via a `useRef` sentinel, before any effect runs. `SKConfig` is a zustand store — sync writes from render are safe because they don't touch React's own state graph. Subsequent prop changes are still picked up by the debounced re-apply effect. + + The web-component path (``) was already race-free since `renderWidget()` writes to `SKConfig` synchronously before mounting React. + +- [#67](https://github.com/swapkit/ui/pull/67) [`470ffe9`](https://github.com/swapkit/ui/commit/470ffe9440c1c6fc5c14749524c26291d6f97c4c) Thanks [@towanTG](https://github.com/towanTG)! - Bump `@swapkit/wallets` to 4.8.8 — picks up upstream wallet connect fixes. + +- [#63](https://github.com/swapkit/ui/pull/63) [`fdbcca6`](https://github.com/swapkit/ui/commit/fdbcca622cb9f1195184f0339d70a6e451f12bc9) Thanks [@towanTG](https://github.com/towanTG)! - `ColorPickerField` — open the native colour picker reliably on mobile. + + Tapping the colour swatch on iOS Safari (and some Android browsers) didn't open the native picker because the swatch was a ` + )} + +
+
+ setQuery(e.target.value)} + placeholder="Search chains" + ref={inputRef} + value={query} + /> + +
+
+
+ {visibleChains.length === 0 ? ( +
+ No chains match +
+ ) : ( + visibleChains.map((c) => { + const isSel = selectedSet.has(c); + const cfg = getChainConfig(c); + return ( + // biome-ignore lint/a11y/useSemanticElements: button+role=checkbox keeps chain icon and name inside a single clickable row; +
+ + ); +} diff --git a/packages/ui/src/react/components/composable/chain-filter-sheet.tsx b/packages/ui/src/react/components/composable/chain-filter-sheet.tsx new file mode 100644 index 0000000..35e043a --- /dev/null +++ b/packages/ui/src/react/components/composable/chain-filter-sheet.tsx @@ -0,0 +1,150 @@ +"use client"; + +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { type Chain, getChainConfig } from "@swapkit/helpers"; +import { CheckIcon, ChevronLeftIcon, SearchIcon } from "lucide-react"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { cn } from "../../../lib/utils"; +import { ChainIcon } from "../simple/chain-icon"; + +/** + * Mobile chain filter — full-screen bottom sheet replacement for `ChainFilterPopover` + * on viewports `< 640px`. Single-select UX: tapping a chain row replaces the multi + * selection with that one chain and dismisses; tapping "All chains" clears and + * dismisses; the close affordance dismisses without applying. + * + * Multi-select is preserved on desktop via the popover; mobile users still have the + * popular-chain pills above the search for quick toggles. + */ +export function ChainFilterSheet({ + open, + onOpenChange, + allChains, + selected, + onChange, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; + allChains: Chain[]; + selected: Chain[]; + onChange: (next: Chain[]) => void; +}) { + const [query, setQuery] = useState(""); + + // Open with a clean search state and reset on close. + useEffect(() => { + if (!open) setQuery(""); + }, [open]); + + const matches = useCallback( + (c: Chain) => { + if (!query) return true; + const q = query.toLowerCase(); + return c.toLowerCase().includes(q) || (getChainConfig(c)?.name ?? c).toLowerCase().includes(q); + }, + [query], + ); + + const visibleChains = useMemo(() => allChains.filter(matches), [allChains, matches]); + + // The sheet UX is single-select. Translate at the boundary: a single-element + // `selected` highlights that row; a multi-selection (set via the popular-chain + // pills) shows nothing highlighted so the next tap is a clean replace. + const activeChain: Chain | null = selected.length === 1 ? (selected[0] ?? null) : null; + + const handleSelect = (c: Chain | null) => { + onChange(c ? [c] : []); + onOpenChange(false); + }; + + return ( + + + + +
+ + + + + Chain + + +
+ +
+ + setQuery(e.target.value)} + placeholder="Search chains" + type="search" + value={query} + /> +
+ +
+
+ +
+ + {visibleChains.map((c) => { + const cfg = getChainConfig(c); + const isActive = activeChain === c; + return ( +
+ +
+ ); + })} + + {visibleChains.length === 0 && ( +
+ No chains match "{query}" +
+ )} +
+
+
+
+ ); +} diff --git a/packages/ui/src/react/components/composable/destination-address-input.tsx b/packages/ui/src/react/components/composable/destination-address-input.tsx new file mode 100644 index 0000000..850176e --- /dev/null +++ b/packages/ui/src/react/components/composable/destination-address-input.tsx @@ -0,0 +1,87 @@ +"use client"; + +import type { Chain } from "@swapkit/helpers"; +import { cn } from "../../../lib/utils"; +import { Button } from "../ui/button"; +import { Card, CardContent } from "../ui/card"; +import { Input } from "../ui/input"; + +export function DestinationAddressInput({ + chain, + customAddress, + error, + isExpanded, + isOutputChainConnected, + isWalletConnected, + walletAddress, + onAddressChange, + onExpandedChange, +}: { + chain: Chain | undefined; + customAddress: string; + error: string | null; + isExpanded: boolean; + isOutputChainConnected: boolean; + isWalletConnected: boolean; + walletAddress: string; + onAddressChange: (address: string) => void; + onExpandedChange: (expanded: boolean) => void; +}) { + if (!isWalletConnected || !chain) return null; + + // Output chain IS connected and field is collapsed — show compact address card + if (isOutputChainConnected && !isExpanded) { + return ( + + + + Receiving at{" "} + + {walletAddress.slice(0, 6)}...{walletAddress.slice(-4)} + + + + + + ); + } + + const hasError = !!error; + + // Output chain NOT connected OR field expanded — show address input + return ( + + +

+ {hasError + ? error + : isOutputChainConnected + ? "Enter a custom receiving address" + : "Enter a receiving address or connect a wallet"} +

+ + onAddressChange(e.target.value)} + placeholder={`${chain} address`} + value={customAddress} + /> + + {isOutputChainConnected && ( + + )} +
+
+ ); +} diff --git a/packages/ui/src/react/components/composable/route-provider-parts.tsx b/packages/ui/src/react/components/composable/route-provider-parts.tsx new file mode 100644 index 0000000..c2ff165 --- /dev/null +++ b/packages/ui/src/react/components/composable/route-provider-parts.tsx @@ -0,0 +1,285 @@ +"use client"; + +import { AssetValue, PriorityLabel, type QuoteResponseRoute } from "@swapkit/helpers"; +import { match } from "ts-pattern"; +import { cn, formatTokenAmount } from "../../../lib/utils"; +import { formatProviderName } from "../../hooks/use-swap-quote"; +import { getProviderLogoUrl } from "../config"; +import { AssetIcon } from "../simple/asset-icon"; + +// Build stable React keys for repeated providers. A multi-hop route can hit +// the same provider twice (e.g. ONEINCH on both legs), so we suffix each +// occurrence with its index to keep keys unique without falling back to a +// raw array index. +function keyedProviders(providers: ReadonlyArray) { + const counts = new Map(); + return providers.map((provider, index) => { + const occurrence = (counts.get(provider) ?? 0) + 1; + counts.set(provider, occurrence); + return { index, key: `${provider}#${occurrence}`, provider }; + }); +} + +// Sized for the collapsed quote header by default; consumers (dialog rows) can +// bump it up. Face-piles when more than one provider with negative margin and +// a ring matching the surface so logos read distinct from each other. +export function StackedProviderLogos({ + providers, + size = 24, + ringColor = "sk-ui-ring-background", + className, +}: { + providers: ReadonlyArray; + size?: number; + ringColor?: string; + className?: string; +}) { + if (!providers?.length) return null; + + return ( + + {keyedProviders(providers).map(({ provider, key, index }) => ( + {formatProviderName(provider)} 0 && "sk-ui-ring-2", + index > 0 && ringColor, + )} + height={size} + key={key} + onError={(e) => { + e.currentTarget.style.display = "none"; + }} + src={getProviderLogoUrl(provider)} + style={{ + height: size, + marginLeft: index === 0 ? 0 : -Math.round(size / 3), + width: size, + zIndex: providers.length - index, + }} + title={formatProviderName(provider)} + width={size} + /> + ))} + + ); +} + +export function pathLabel(providers: ReadonlyArray): string { + const names = providers.map(formatProviderName); + if (names.length <= 1) return names[0] ?? ""; + // Three or more providers compress the middle to keep the label single-line + // at the 380px widget width: "1inch → … → Chainflip". + if (names.length > 3) return `${names[0]} → … → ${names[names.length - 1]}`; + return names.join(" → "); +} + +function tagLabel(tags: ReadonlyArray | undefined): string | null { + return ( + match(tags) + .when( + (t): t is PriorityLabel[] => Array.isArray(t) && t.includes(PriorityLabel.RECOMMENDED), + () => "Recommended", + ) + .when( + (t): t is PriorityLabel[] => Array.isArray(t) && t.includes(PriorityLabel.CHEAPEST), + () => "Cheapest", + ) + .when( + (t): t is PriorityLabel[] => Array.isArray(t) && t.includes(PriorityLabel.FASTEST), + () => "Fastest", + ) + .otherwise(() => null) ?? null + ); +} + +// Sits at the top-right of the card, straddling its border so the inline row +// has room for the path + timer + amount. The fill is an opaque equivalent of +// the inline `bg-success` (translucent green @ 0.16) composited over whichever +// surface the ribbon straddles — the card by default, the base background for +// dialog rows. Computing it live with `color-mix` keeps it in sync when a +// studio user re-themes either token, instead of muddying as a translucent +// chip would over the row border. +export function RoutePriorityRibbon({ + tags, + className, + surfaceVar = "--sk-ui-card", +}: { + tags?: ReadonlyArray; + className?: string; + /** Theme variable for the surface the ribbon sits over. */ + surfaceVar?: "--sk-ui-card" | "--sk-ui-background"; +}) { + const label = tagLabel(tags); + if (!label) return null; + return ( + + {label} + + ); +} + +function safeTicker(asset: string | undefined): string { + if (!asset) return ""; + try { + return AssetValue.from({ asset }).ticker ?? asset; + } catch { + // Fall back to the suffix after the chain dot if AssetValue can't parse. + return asset.split(".")[1]?.split("-")[0] ?? asset; + } +} + +export type RouteLeg = NonNullable[number]; + +// Vertical timeline laid out as input asset → provider step → mid asset → … → +// receive asset. Mirrors the design's expanded detail. +export function RouteLegsTimeline({ + legs, + outAmount, + outTicker, + sellAmount, + sellTicker, +}: { + legs: ReadonlyArray; + outAmount?: string | number | null; + outTicker?: string | null; + sellAmount?: string | number | null; + sellTicker?: string | null; +}) { + if (!legs?.length) return null; + + type AssetNode = { type: "asset"; asset: string; role: "pay" | "mid" | "receive" }; + type StepNode = { type: "step"; leg: RouteLeg }; + type Node = AssetNode | StepNode; + + const nodes: Node[] = [{ asset: legs[0]?.sellAsset ?? "", role: "pay", type: "asset" }]; + legs.forEach((leg, index) => { + nodes.push({ leg, type: "step" }); + nodes.push({ asset: leg.buyAsset, role: index === legs.length - 1 ? "receive" : "mid", type: "asset" }); + }); + + return ( +
    + {nodes.map((node, index) => { + const isFirst = index === 0; + const isLast = index === nodes.length - 1; + const key = node.type === "asset" ? `asset-${index}-${node.asset}` : `step-${index}-${node.leg.provider}`; + return ( +
  1. + {/* Rail + marker */} +
    + {!isFirst && ( + + )} + {!isLast && ( + + )} + {node.type === "asset" ? ( + // Reuse AssetIcon so the timeline marker is identical to + // every other place the widget shows assets (asset select, + // wallet drawer): real token icon + chain badge bottom-right + // for non-native tokens, deterministic-hue fallback if the + // icon URL 404s. + + + + ) : ( + // Larger than the asset markers (size-8 vs size-6) so the + // provider reads as the actor mediating between assets, not + // a peer node. Matches the design's 32px provider vs 24px asset. + {formatProviderName(node.leg.provider)} { + e.currentTarget.style.visibility = "hidden"; + }} + src={getProviderLogoUrl(node.leg.provider)} + width={32} + /> + )} +
    + + {/* Content */} + {node.type === "asset" ? ( + + ) : ( + + )} +
  2. + ); + })} +
+ ); +} + +function RouteAssetRow({ + asset, + role, + sellAmount, + sellTicker, + outAmount, + outTicker, +}: { + asset: string; + role: "pay" | "mid" | "receive"; + sellAmount?: string | number | null; + sellTicker?: string | null; + outAmount?: string | number | null; + outTicker?: string | null; +}) { + const ticker = safeTicker(asset); + const chain = asset.split(".")[0] ?? ""; + + return ( +
+
+ {ticker} + {chain && {chain}} +
+ {role === "pay" && sellAmount != null && ( +
+ You send + + {formatTokenAmount(sellAmount)} {sellTicker ?? ticker} + +
+ )} + {role === "receive" && outAmount != null && ( +
+ You receive + + {formatTokenAmount(outAmount)} {outTicker ?? ticker} + +
+ )} +
+ ); +} + +function RouteStepRow({ leg }: { leg: RouteLeg }) { + return ( +
+ + {formatProviderName(leg.provider)} + + + Swap Provider + +
+ ); +} diff --git a/packages/ui/src/react/components/composable/swap-amount-input.tsx b/packages/ui/src/react/components/composable/swap-amount-input.tsx new file mode 100644 index 0000000..79f2f06 --- /dev/null +++ b/packages/ui/src/react/components/composable/swap-amount-input.tsx @@ -0,0 +1,38 @@ +import { Loader2Icon } from "lucide-react"; +import { cn } from "../../../lib/utils"; +import { Input } from "../ui/input"; + +export function SwapAmountInput({ + amount, + setAmount, + isLoading, + formattedAmountUSD, + disabled = false, + className, +}: { + amount: string | null | undefined; + formattedAmountUSD: string | undefined; + isLoading?: boolean; + disabled?: boolean; + className?: string; + setAmount?: (amount: string) => void; +}) { + return ( +
+ setAmount?.(e.target.value)} + placeholder="0.00" + type="text" + value={amount ?? "0.00"} + /> + +
+ {isLoading && } + + {formattedAmountUSD} +
+
+ ); +} diff --git a/packages/ui/src/react/components/composable/swap-asset-item.tsx b/packages/ui/src/react/components/composable/swap-asset-item.tsx new file mode 100644 index 0000000..9052363 --- /dev/null +++ b/packages/ui/src/react/components/composable/swap-asset-item.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { AssetValue } from "@swapkit/helpers"; +import type { Ref } from "react"; +import { cn } from "../../../lib/utils"; +import { AssetIcon } from "../simple/asset-icon"; + +type SwapAssetItemProps = { asset: string | null | undefined; className?: string; ref?: Ref }; + +export function SwapAssetItem({ asset, className, ref }: SwapAssetItemProps) { + if (!asset) return null; + + const assetValue = AssetValue.from({ asset }); + + return ( +
+ + +
+ + {assetValue?.ticker} + + + {assetValue?.chain} +
+
+ ); +} diff --git a/packages/ui/src/react/components/composable/swap-asset-select.tsx b/packages/ui/src/react/components/composable/swap-asset-select.tsx new file mode 100644 index 0000000..7929a3c --- /dev/null +++ b/packages/ui/src/react/components/composable/swap-asset-select.tsx @@ -0,0 +1,283 @@ +"use client"; + +import { Chain, getChainConfig } from "@swapkit/helpers"; +import { ChevronDownIcon, ListFilterIcon, Loader2Icon, SearchIcon } from "lucide-react"; +import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { cn, formatCurrency } from "../../../lib/utils"; +import { useFilteredSortedAssets } from "../../hooks/use-filtered-sorted-assets"; +import { useMediaQuery } from "../../hooks/use-media-query"; +import { showModal, useModal } from "../../hooks/use-modal"; +import { useTokenPrices } from "../../hooks/use-token-prices"; +import { useWalletsConfig } from "../../swapkit-config-context"; +import { useSwapKitStore } from "../../swapkit-context"; +import { ChainIcon } from "../simple/chain-icon"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Input } from "../ui/input"; +import { ChainFilterPopover } from "./chain-filter-popover"; +import { ChainFilterSheet } from "./chain-filter-sheet"; +import { SwapAssetItem } from "./swap-asset-item"; + +// Quick-filter pills shown under the search bar. First-class chains most users swap to/from. +const POPULAR_CHAIN_PILLS = [Chain.Bitcoin, Chain.Ethereum, Chain.Solana, Chain.Tron, Chain.Base] as const; + +export const SwapAssetSelect = memo(function SwapAssetSelect({ + selectedAsset, + setSelectedAsset, + isOutputSelect = false, +}: { + selectedAsset: string | undefined; + setSelectedAsset: (asset: string) => void; + isOutputSelect?: boolean; +}) { + const handleSelectAssetClick = async () => { + const { confirmed, data: assetIdentifier } = await showModal( + , + ); + + if (!confirmed) return; + + setSelectedAsset(assetIdentifier); + }; + + return ( + + ); +}); + +export function SwapAssetSelectTokenDialog({ isOutputSelect = false }: { isOutputSelect?: boolean }) { + const modal = useModal(); + + const { assets, filters, setFilters } = useFilteredSortedAssets({ filterBySwapTo: isOutputSelect }); + const { pricesByTokenId } = useTokenPrices(); + const { isFetchingSwapTo } = useSwapKitStore(); + const { effectiveChains, isChainAllowed } = useWalletsConfig(); + + const popularChainPills = useMemo(() => POPULAR_CHAIN_PILLS.filter(isChainAllowed), [isChainAllowed]); + + const [selectedNetworks, setSelectedNetworks] = useState([]); + const [chainFilterOpen, setChainFilterOpen] = useState(false); + const chainFilterTriggerRef = useRef(null); + // Mobile breakpoint per the design — keeps the asset list out from behind the picker + // and gives the search input the keyboard real estate it needs. + const isMobileChainFilter = useMediaQuery("(max-width: 639px)"); + + useEffect(() => { + setFilters((f) => ({ ...f, selectedNetworks })); + }, [selectedNetworks, setFilters]); + + const searchQuery = filters?.searchQuery ?? ""; + const hasActiveFilters = searchQuery.length > 0 || selectedNetworks.length > 0; + + const clearFilters = useCallback(() => { + setSelectedNetworks([]); + setFilters((f) => ({ ...f, searchQuery: "" })); + }, [setFilters]); + + // Split into held vs rest. `assets` from the hook is already sorted balance-first, + // but the visual grouping requires explicit partitioning. + const { held, rest } = useMemo(() => { + const limited = assets?.slice(0, 100) ?? []; + const h: typeof limited = []; + const r: typeof limited = []; + for (const a of limited) { + if ((a?.getValue?.("number") ?? 0) > 0) h.push(a); + else r.push(a); + } + return { held: h, rest: r }; + }, [assets]); + + return ( + + + + Select token + + + {/* Search + chain filter popover trigger */} +
+
+ setFilters((f) => ({ ...f, searchQuery: e.target.value }))} + placeholder="Search by name, symbol or address" + value={searchQuery} + /> + +
+ +
+ + {isMobileChainFilter ? ( + + ) : ( + chainFilterOpen && ( + setChainFilterOpen(false)} + selected={selectedNetworks} + triggerRef={chainFilterTriggerRef} + /> + ) + )} +
+
+ + {/* Popular chain pills — quick toggles */} +
+ {popularChainPills.map((chain) => { + const cfg = getChainConfig(chain); + const isOn = selectedNetworks.includes(chain); + return ( + + ); + })} +
+ + {/* Scrollable grouped list. DialogContent is a fixed height on desktop (620px), so flex-1 here fills the remaining space. */} +
+ {isOutputSelect && isFetchingSwapTo && ( +
+ + Finding available pairs… +
+ )} + + {held.length === 0 && rest.length === 0 ? ( +
+ No assets found + + Try changing the selected networks or the search query + + {hasActiveFilters && ( + + )} +
+ ) : ( + <> + {held.length > 0 && ( + + {held.map((asset) => ( + modal.resolve({ confirmed: true, data: identifier })} + priceUSD={pricesByTokenId?.get(asset.toString())?.priceUSD} + /> + ))} + + )} + {rest.length > 0 && ( + + {rest.map((asset) => ( + modal.resolve({ confirmed: true, data: identifier })} + priceUSD={pricesByTokenId?.get(asset.toString())?.priceUSD} + /> + ))} + + )} + + )} +
+
+
+ ); +} + +function AssetGroup({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+
+ {title} +
+
{children}
+
+ ); +} + +function AssetRow({ + asset, + onSelect, + priceUSD, +}: { + asset: ReturnType["assets"][number]; + onSelect: (identifier: string) => void; + priceUSD: number | undefined; +}) { + const identifier = asset.toString(); + const heldAmount = asset?.getValue("number") ?? 0; + const hasBalance = heldAmount > 0; + + return ( + + ); +} diff --git a/packages/ui/src/react/components/composable/swap-input-chain-selector.tsx b/packages/ui/src/react/components/composable/swap-input-chain-selector.tsx new file mode 100644 index 0000000..65163e8 --- /dev/null +++ b/packages/ui/src/react/components/composable/swap-input-chain-selector.tsx @@ -0,0 +1,69 @@ +"use client"; + +import type { AssetValue } from "@swapkit/helpers"; +import { SwapAmountInput } from "./swap-amount-input"; +import { SwapAssetSelect } from "./swap-asset-select"; + +export function SwapInputWithChainSelector({ + label, + formattedAmountUSD, + + isSwapping, + isLoading, + isOutputSelect = false, + + selectedAsset, + setSelectedAsset, + + amount, + setAmount, + + balance, +}: { + label: string; + formattedAmountUSD: string | undefined; + + isSwapping: boolean; + isLoading?: boolean; + isOutputSelect?: boolean; + + selectedAsset: string | undefined; + setSelectedAsset: (asset: string) => void; + + amount: string | null | undefined; + setAmount?: (amount: string) => void; + + balance?: AssetValue | null; +}) { + const isInputDisabled = !selectedAsset || isSwapping || isLoading || !setAmount; + + return ( +
+ {label} + +
+
+ + + {balance && ( + + Bal: {balance.toSignificant(6)} + + )} +
+ + +
+
+ ); +} diff --git a/packages/ui/src/react/components/composable/swap-quote-preview.tsx b/packages/ui/src/react/components/composable/swap-quote-preview.tsx new file mode 100644 index 0000000..9b3bd25 --- /dev/null +++ b/packages/ui/src/react/components/composable/swap-quote-preview.tsx @@ -0,0 +1,224 @@ +"use client"; + +import { ArrowLeftRight, ChevronRight, InfoIcon, TimerIcon } from "lucide-react"; +import { type ReactNode, useState } from "react"; +import { formatTokenAmount } from "../../../lib/utils"; +import { useMediaQuery } from "../../hooks/use-media-query"; +import { showModal } from "../../hooks/use-modal"; +import type { UseSwapQuoteReturn } from "../../hooks/use-swap-quote"; +import { SwapQuoteRouteSelectDialog } from "../dialogs/swap-quote-route-select-dialog"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../ui/accordion"; +import { Button } from "../ui/button"; +import { Card, CardContent, CardHeader } from "../ui/card"; +import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "../ui/sheet"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import { pathLabel, RouteLegsTimeline, RoutePriorityRibbon, StackedProviderLogos } from "./route-provider-parts"; + +// Each fees-row info icon surfaces a short explanation. Desktop uses Radix +// Tooltip (hover-driven); on touch Radix Tooltip's pointerdown handler closes +// what just opened, so mobile gets a top-sliding Sheet instead — tap the +// icon, sheet slides in with the title + body, tap outside / close to dismiss. +// Rendered as inline-block + baseline-aligned so the icon flows with the +// preceding text rather than dropping to its own line when the label wraps. +function FeeInfo({ title, children }: { title: ReactNode; children: ReactNode }) { + const isMobile = useMediaQuery("(max-width: 639px)"); + const [open, setOpen] = useState(false); + + const trigger = ( + + ); + + if (isMobile) { + return ( + <> + {trigger} + + + + {title} + {children} + + + + + ); + } + + return ( + + {trigger} + {children} + + ); +} + +export function SwapQuotePreview({ + selectedRoute, + routes, + setSelectedRouteIndex, + className, +}: { + selectedRoute: UseSwapQuoteReturn["selectedRoute"]; + routes: UseSwapQuoteReturn["routes"]; + setSelectedRouteIndex: UseSwapQuoteReturn["setSelectedRouteIndex"]; + className?: string; +}) { + if (!selectedRoute) return null; + + const selectQuoteRoute = async () => { + const { confirmed, data: selectedRouteIndex } = await showModal( + , + ); + + if (!confirmed) return; + + setSelectedRouteIndex(selectedRouteIndex); + }; + + const providers = selectedRoute.route?.providers ?? []; + const legs = selectedRoute.route?.legs ?? []; + const tags = selectedRoute.tags; + + return ( + // sk-ui-relative on the wrapper so the corner ribbon positions against the + // card edge (Card itself has no overflow:hidden so the ribbon doesn't clip). +
+ + + + + + + + + + + + + 1 {selectedRoute?.inputAssetTicker} ≈ {formatTokenAmount(selectedRoute?.expectedBuyAmountFor1Input)}{" "} + {selectedRoute?.outputAssetTicker} + + + + Fees: {selectedRoute?.formattedTotalFeesUSD} + + + + + {legs.length > 0 && ( + <> + +
+ + )} + +
    +
  • + + Minimum received after slippage ({selectedRoute?.formattedMaxSlippagePercentage}) + + The smallest amount you'll receive if the price moves against you within your slippage + tolerance. If the route would deliver less than this, the swap is cancelled. + + + + + {formatTokenAmount(selectedRoute?.expectedBuyAmountMaxSlippage)}{" "} + {selectedRoute?.outputAssetTicker} + +
  • + +
  • + + Liquidity fee + + Cost of sourcing the output asset along this route. May include pool fees, bridge spreads, or + DEX-aggregator pricing depending on the provider. + + + + {selectedRoute?.formattedLiquidityFeeUSD === "$0.00" ? ( + FREE + ) : ( + + {selectedRoute?.formattedLiquidityFeeUSD} + + )} +
  • + +
  • + + Exchange fee + Fee taken to provide you with the swap service. + + + {selectedRoute?.formattedExchangeFeeUSD === "$0.00" ? ( + FREE + ) : ( + + {selectedRoute?.formattedExchangeFeeUSD} + + )} +
  • + +
  • + + Inbound network fee + + Gas paid to the source chain to send your input into the route. Varies with current network + conditions. + + + + {selectedRoute?.formattedInboundNetworkFeeUSD === "$0.00" ? ( + FREE + ) : ( + + {selectedRoute?.formattedInboundNetworkFeeUSD} + + )} +
  • +
+ + + + + +
+ ); +} diff --git a/packages/ui/src/react/components/composable/transaction-history-drawer.tsx b/packages/ui/src/react/components/composable/transaction-history-drawer.tsx new file mode 100644 index 0000000..3d68d43 --- /dev/null +++ b/packages/ui/src/react/components/composable/transaction-history-drawer.tsx @@ -0,0 +1,290 @@ +"use client"; + +import { AssetValue } from "@swapkit/helpers"; +import { SwapKitApi } from "@swapkit/helpers/api"; +import { ArrowRight, CheckCircle2, ExternalLink, History, Trash2, XCircle } from "lucide-react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { showModal, useModal } from "../../hooks/use-modal"; +import { + type TransactionRecord, + type TransactionStatus, + useTransactionHistory, +} from "../../stores/transaction-history-store"; +import { AssetIcon } from "../simple/asset-icon"; +import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "../ui/sheet"; + +const TRACKER_POLL_TICK_MS = 10_000; +const TRACKER_MAX_REQUESTS_PER_TICK = 5; +const MINUTE_MS = 60_000; +const HOUR_MS = 60 * MINUTE_MS; + +export function showTransactionHistoryDrawer() { + return showModal(); +} + +function getRelativeTime(timestamp: number) { + const now = Date.now(); + const diff = now - timestamp; + const seconds = Math.floor(diff / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + if (days > 0) return `${days}d ago`; + if (hours > 0) return `${hours}h ago`; + if (minutes > 0) return `${minutes}m ago`; + return "just now"; +} + +function StatusIcon({ status }: { status: TransactionStatus }) { + switch (status) { + case "completed": + return ; + case "failed": + return ; + default: + return
; + } +} + +function truncateHash(hash: string) { + if (hash.length <= 12) return hash; + return `${hash.slice(0, 6)}...${hash.slice(-4)}`; +} + +function formatAmount(amount: string | undefined, asset: string | undefined) { + if (!amount || !asset) return null; + try { + const assetValue = AssetValue.from({ asset, value: amount }); + return assetValue.toSignificant(6); + } catch { + return amount; + } +} + +function mapTrackerStatus(status: string | undefined): TransactionStatus | null { + if (status === "completed") return "completed"; + if (status === "failed" || status === "refunded") return "failed"; + return null; +} + +function getTrackerBackoffMs(transaction: TransactionRecord, checkCount: number, checkedAt: number) { + const ageMs = checkedAt - transaction.timestamp; + + if (ageMs < MINUTE_MS && checkCount <= 6) return 10_000; + if (ageMs < 5 * MINUTE_MS) return 30_000; + if (ageMs < 30 * MINUTE_MS) return MINUTE_MS; + if (ageMs < 6 * HOUR_MS) return 5 * MINUTE_MS; + + return 15 * MINUTE_MS; +} + +function getNextTrackerCheckAt(transaction: TransactionRecord, checkCount: number, checkedAt: number) { + return checkedAt + getTrackerBackoffMs(transaction, checkCount, checkedAt); +} + +function getDuePendingTransactions(transactions: TransactionRecord[], now: number) { + return transactions + .filter((transaction) => transaction.status === "pending" && (transaction.nextCheckAt ?? 0) <= now) + .sort((a, b) => (a.nextCheckAt ?? 0) - (b.nextCheckAt ?? 0) || a.timestamp - b.timestamp) + .slice(0, TRACKER_MAX_REQUESTS_PER_TICK); +} + +function TransactionItem({ transaction }: { transaction: TransactionRecord }) { + const handleClick = useCallback(() => { + const url = `https://track.swapkit.dev/?hash=${transaction.hash}&chainId=${transaction.chainId}`; + window.open(url, "_blank", "noopener,noreferrer"); + }, [transaction.hash, transaction.chainId]); + + const sellTicker = transaction.sellAsset ? AssetValue.from({ asset: transaction.sellAsset }).ticker : null; + const buyTicker = transaction.buyAsset ? AssetValue.from({ asset: transaction.buyAsset }).ticker : null; + const sellAmount = formatAmount(transaction.sellAmount, transaction.sellAsset); + const buyAmount = formatAmount(transaction.buyAmount, transaction.buyAsset); + + return ( + + ); +} + +export function TransactionHistoryDrawer() { + const modal = useModal(); + const { transactions, clearHistory, updateTransaction } = useTransactionHistory(); + const [showConfirm, setShowConfirm] = useState(false); + const isPollingTransactions = useRef(false); + const transactionsRef = useRef(transactions); + const pendingTransactionIds = useMemo( + () => + transactions + .filter((tx) => tx.status === "pending") + .map((tx) => tx.id) + .join("|"), + [transactions], + ); + + useEffect(() => { + transactionsRef.current = transactions; + }, [transactions]); + + // Auto-refresh pending transactions + useEffect(() => { + if (!pendingTransactionIds) return; + + const pollTransactions = async () => { + if (typeof document !== "undefined" && document.visibilityState === "hidden") return; + if (isPollingTransactions.current) return; + + isPollingTransactions.current = true; + + try { + const dueTransactions = getDuePendingTransactions(transactionsRef.current, Date.now()); + + for (const tx of dueTransactions) { + const checkedAt = Date.now(); + const checkCount = (tx.checkCount ?? 0) + 1; + + try { + const response = await SwapKitApi.getTrackerDetails({ chainId: tx.chainId.toString(), hash: tx.hash }); + const trackerStatus = response.status ?? response.legs?.[0]?.status; + const status = mapTrackerStatus(trackerStatus) ?? tx.status; + + updateTransaction(tx.id, { + checkCount, + lastCheckedAt: checkedAt, + lastErrorAt: undefined, + nextCheckAt: status === "pending" ? getNextTrackerCheckAt(tx, checkCount, checkedAt) : undefined, + status, + trackerStatus, + }); + } catch { + updateTransaction(tx.id, { + checkCount, + lastCheckedAt: checkedAt, + lastErrorAt: checkedAt, + nextCheckAt: getNextTrackerCheckAt(tx, checkCount, checkedAt), + }); + } + } + } finally { + isPollingTransactions.current = false; + } + }; + + const pollIfVisible = () => { + void pollTransactions(); + }; + + pollIfVisible(); + const interval = setInterval(() => { + pollIfVisible(); + }, TRACKER_POLL_TICK_MS); + + window.addEventListener("focus", pollIfVisible); + document.addEventListener("visibilitychange", pollIfVisible); + + return () => { + clearInterval(interval); + window.removeEventListener("focus", pollIfVisible); + document.removeEventListener("visibilitychange", pollIfVisible); + }; + }, [pendingTransactionIds, updateTransaction]); + + const handleClearHistory = useCallback(() => { + if (showConfirm) { + clearHistory(); + setShowConfirm(false); + } else { + setShowConfirm(true); + setTimeout(() => setShowConfirm(false), 3000); + } + }, [showConfirm, clearHistory]); + + const sortedTransactions = useMemo(() => { + return [...transactions].sort((a, b) => b.timestamp - a.timestamp); + }, [transactions]); + + return ( + + + + Transaction History + + {transactions.length === 0 + ? "No transactions yet" + : `${transactions.length} transaction${transactions.length !== 1 ? "s" : ""}`} + + + +
+ {sortedTransactions.length > 0 ? ( + sortedTransactions.map((tx) => ) + ) : ( +
+
+ +

No transactions yet

+

+ Your swap and approval transactions will appear here +

+
+
+ )} +
+ + {transactions.length > 0 && ( + + )} +
+
+ ); +} diff --git a/packages/ui/src/react/components/config.ts b/packages/ui/src/react/components/config.ts new file mode 100644 index 0000000..483d793 --- /dev/null +++ b/packages/ui/src/react/components/config.ts @@ -0,0 +1,194 @@ +import type { Chain, ProviderName, TokenNames } from "@swapkit/helpers"; +import { WalletOption } from "@swapkit/helpers"; + +const getAssetsBaseUrl = () => { + if (import.meta.env?.MODE === "development") { + return "https://storage.googleapis.com/token-list-swapkit-dev"; + } + + return "https://storage.googleapis.com/token-list-swapkit"; +}; + +export const getTokenLogoUrl = (token: TokenNames | (string & {})) => { + return `${getAssetsBaseUrl()}/images/${token?.toLowerCase()}.png`; +}; + +export const getProviderLogoUrl = (provider: ProviderName | (string & {})) => { + const normalizedProvider = provider?.replace(/(_V\d+|_STREAMING)$/g, "").toLowerCase(); + return `${getAssetsBaseUrl()}/images/providers/${normalizedProvider}.png`; +}; + +export const getChainLogoUrl = (chain: Chain | (string & {})) => { + return `${getAssetsBaseUrl()}/images/chains/${chain?.toLowerCase()}.${chain?.toLowerCase()}.png`; +}; + +export const getWalletLogoUrl = (wallet: WalletOption | (string & {})) => { + return `${getAssetsBaseUrl()}/images/wallets/${wallet?.toLowerCase()}.png`; +}; + +export const WALLET_DISPLAY_NAMES: Partial> = { + [WalletOption.BITGET]: "Bitget", + [WalletOption.BRAVE]: "Brave", + [WalletOption.COINBASE_MOBILE]: "Coinbase", + [WalletOption.COINBASE_WEB]: "Coinbase", + [WalletOption.COSMOSTATION]: "Cosmostation", + [WalletOption.CTRL]: "CTRL", + [WalletOption.EIP6963]: "Browser Wallet", + [WalletOption.EXODUS]: "Exodus", + [WalletOption.KEEPKEY]: "KeepKey", + [WalletOption.KEEPKEY_BEX]: "KeepKey", + [WalletOption.KEPLR]: "Keplr", + [WalletOption.KEYSTORE]: "Keystore", + [WalletOption.LEAP]: "Leap", + [WalletOption.LEDGER]: "Ledger", + [WalletOption.METAMASK]: "MetaMask", + [WalletOption.OKX]: "OKX", + [WalletOption.OKX_MOBILE]: "OKX", + [WalletOption.ONEKEY]: "OneKey", + [WalletOption.PASSKEYS]: "Passkeys", + [WalletOption.PHANTOM]: "Phantom", + [WalletOption.RADIX_WALLET]: "Radix Wallet", + [WalletOption.TALISMAN]: "Talisman", + [WalletOption.TREZOR]: "Trezor", + [WalletOption.TRONLINK]: "TronLink", + [WalletOption.TRUSTWALLET_WEB]: "Trust Wallet", + [WalletOption.VULTISIG]: "Vultisig", + [WalletOption.WALLETCONNECT]: "WalletConnect", + [WalletOption.WALLET_SELECTOR]: "Wallet Selector", + [WalletOption.XAMAN]: "Xaman", +}; + +/** + * Theme colors for the SwapKit widget. + * All values should be in HSL format: "H S% L%" or "H S% L% / A" + * + * Note: These map to dedicated theme variables (--sk-bg-*, --sk-ui-accent, etc.) + * to avoid conflicts with component-level styles. + */ +export interface SwapKitColors { + /** Main widget background color */ + background?: string; + /** Elevated surface color (cards, dialogs) */ + surface?: string; + /** Hover state overlay */ + hover?: string; + /** Active/pressed state overlay */ + active?: string; + /** Modal backdrop overlay */ + overlay?: string; + /** Primary foreground (primary button background) */ + primaryForeground?: string; + /** Main text color */ + text?: string; + /** Muted/subtle text color */ + mutedForeground?: string; + /** Muted text (alias for mutedForeground) */ + mutedText?: string; + /** Text color on primary buttons (for contrast on bright backgrounds) */ + primaryButtonText?: string; + /** Brand/accent color (steppers, progress indicators, highlights) */ + accent?: string; + /** Text on accent backgrounds */ + accentForeground?: string; + /** Primary button background color */ + primaryButton?: string; + /** Primary button text color */ + primaryButtonForeground?: string; + /** Border color */ + border?: string; +} + +/** Default color values for dark theme */ +export const DEFAULT_COLORS: Required = { + accent: "140 87% 79%", + accentForeground: "140 6% 8%", + active: "0 0% 100% / 0.12", + background: "140 6% 8%", + border: "0 0% 100% / 0.12", + hover: "0 0% 100% / 0.08", + mutedForeground: "0 0% 100% / 0.64", + mutedText: "0 0% 100% / 0.64", + overlay: "0 0% 0% / 0.8", + primaryButton: "0 0% 100% / 0.92", + primaryButtonForeground: "140 6% 8%", + primaryButtonText: "140 6% 8%", + primaryForeground: "140 87% 79%", + surface: "120 3% 13%", + text: "0 0% 100% / 0.92", +}; + +/** CSS variable names mapped to SwapKitColors keys */ +const COLOR_VAR_MAP: Record = { + accent: "--sk-ui-accent", + accentForeground: "--sk-ui-accent-foreground", + active: "--sk-bg-active", + background: "--sk-bg", + border: "--sk-ui-border", + hover: "--sk-bg-hover", + mutedForeground: "--sk-ui-muted-foreground", + mutedText: "--sk-ui-muted-foreground", + overlay: "--sk-bg-overlay", + primaryButton: "--sk-ui-primary-button", + primaryButtonForeground: "--sk-ui-primary-button-foreground", + primaryButtonText: "--sk-ui-primary-button-text", + primaryForeground: "--sk-ui-primary", + surface: "--sk-bg-surface", + text: "--sk-ui-primary-foreground", +}; + +/** + * Applies custom colors to CSS variables on a DOM element. + * Only sets variables for colors that are provided. + * Also sets derived variables that reference base variables to ensure + * proper cascading (CSS var() references resolve at definition scope, not use scope). + */ +export function applyColorsToElement(element: HTMLElement, colors: SwapKitColors) { + for (const [key, value] of Object.entries(colors)) { + if (value) { + const varName = COLOR_VAR_MAP[key as keyof SwapKitColors]; + element.style.setProperty(varName, value); + + // Derived variables must be set explicitly (CSS var() resolves at definition scope) + if (key === "background") { + element.style.setProperty("--sk-ui-background", value); + element.style.setProperty("--sk-ui-sidebar-background", value); + element.style.setProperty("--sk-ui-sidebar-primary", value); + } + if (key === "surface") { + element.style.setProperty("--sk-ui-card", value); + element.style.setProperty("--sk-ui-secondary", value); + element.style.setProperty("--sk-ui-muted", value); + } + if (key === "primaryForeground") { + element.style.setProperty("--sk-ui-accent", value); + } + if (key === "primaryButtonText") { + element.style.setProperty("--sk-ui-accent-foreground", value); + } + if (key === "text") { + element.style.setProperty("--sk-ui-foreground", value); + element.style.setProperty("--sk-ui-secondary-foreground", value); + element.style.setProperty("--sk-ui-card-foreground", value); + } + } + } +} + +/** + * Generates inline style object for React components. + * Returns CSS custom property declarations for provided colors. + */ +export function getColorsStyleProps(colors?: SwapKitColors): React.CSSProperties { + if (!colors) return {}; + + const style: Record = {}; + + for (const [key, value] of Object.entries(colors)) { + if (value) { + const varName = COLOR_VAR_MAP[key as keyof SwapKitColors]; + style[varName] = value; + } + } + + return style as React.CSSProperties; +} diff --git a/packages/ui/src/react/components/dialogs/approval-confirm-dialog.tsx b/packages/ui/src/react/components/dialogs/approval-confirm-dialog.tsx new file mode 100644 index 0000000..0a1a816 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/approval-confirm-dialog.tsx @@ -0,0 +1,92 @@ +"use client"; + +import { AssetValue } from "@swapkit/helpers"; +import { Loader2Icon } from "lucide-react"; +import { useMemo, useState } from "react"; +import { useModal } from "../../hooks/use-modal"; +import { getTokenLogoUrl } from "../config"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; + +export interface ApprovalConfirmDialogProps { + tokenAsset: string; + amount: string; + spenderAddress: string; + isWaiting?: boolean; + onApproveClick?: () => Promise; +} + +export const ApprovalConfirmDialog = ({ + tokenAsset, + amount, + spenderAddress, + isWaiting: externalIsWaiting = false, + onApproveClick, +}: ApprovalConfirmDialogProps) => { + const modal = useModal(); + const [internalIsWaiting, setInternalIsWaiting] = useState(false); + + const isWaiting = externalIsWaiting || internalIsWaiting; + + const { tokenTicker, tokenLogoUrl, truncatedSpenderAddress } = useMemo(() => { + const assetValue = AssetValue.from({ asset: tokenAsset }); + const tokenTicker = assetValue.ticker; + const tokenLogoUrl = getTokenLogoUrl(tokenAsset); + const truncatedSpenderAddress = `${spenderAddress.slice(0, 6)}...${spenderAddress.slice(-4)}`; + + return { tokenLogoUrl, tokenTicker, truncatedSpenderAddress }; + }, [tokenAsset, spenderAddress]); + + const handleApprove = async () => { + if (onApproveClick) { + setInternalIsWaiting(true); + try { + await onApproveClick(); + modal.resolve({ confirmed: true, data: undefined }); + } catch (error) { + setInternalIsWaiting(false); + throw error; + } + } else { + modal.resolve({ confirmed: true, data: undefined }); + } + }; + + return ( + + + + Approve Token + + +
+ {tokenTicker} + +
+ + {amount} {tokenTicker} + +
+ +
+ {isWaiting ? ( + <> + + Waiting for confirmation... + + ) : ( + <> + Approving for contract: + {truncatedSpenderAddress} + + )} +
+
+ + +
+
+ ); +}; diff --git a/packages/ui/src/react/components/dialogs/swap-confirm-dialog.tsx b/packages/ui/src/react/components/dialogs/swap-confirm-dialog.tsx new file mode 100644 index 0000000..2a99da7 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/swap-confirm-dialog.tsx @@ -0,0 +1,144 @@ +import { AssetValue } from "@swapkit/helpers"; +import { ChevronDown, MoveDownIcon } from "lucide-react"; +import { useMemo } from "react"; +import { formatTokenAmount } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import type { useSwapQuote } from "../../hooks/use-swap-quote"; +import { SwapAmountInput } from "../composable/swap-amount-input"; +import { SwapAssetItem } from "../composable/swap-asset-item"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "../ui/accordion"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; + +const CONFIRM_AMOUNT_MAX_SIGNIFICANT_DIGITS = 10; + +function formatConfirmAmount(amount: number | string | null | undefined) { + return formatTokenAmount(amount, { maximumSignificantDigits: CONFIRM_AMOUNT_MAX_SIGNIFICANT_DIGITS }); +} + +export const SwapConfirmDialog = ({ + swapRoute, + destinationAddress, +}: { + swapRoute: NonNullable["selectedRoute"]>; + destinationAddress: string; +}) => { + const modal = useModal(); + + const { totalFeesListItems, swapSummaryListItems } = useMemo(() => { + const totalFeesListItems = [ + { title: "Network fee", value: swapRoute.formattedInboundNetworkFeeUSD }, + { title: "Liquidity fee", value: swapRoute.formattedLiquidityFeeUSD }, + { title: "Exchange fee", value: swapRoute.formattedExchangeFeeUSD }, + ]; + + const buyTicker = swapRoute.route?.buyAsset ? AssetValue.from({ asset: swapRoute.route.buyAsset }).ticker : ""; + + const truncatedAddress = destinationAddress + ? `${destinationAddress.slice(0, 6)}...${destinationAddress.slice(-4)}` + : ""; + + const swapSummaryListItems = [ + { title: "Estimated time", value: swapRoute.formattedEstimatedTime }, + { title: "Max. slippage", value: swapRoute?.formattedMaxSlippagePercentage }, + { title: "Recipient", value: truncatedAddress }, + { title: "Min received", value: `${formatConfirmAmount(swapRoute.expectedBuyAmountMaxSlippage)} ${buyTicker}` }, + ]; + + return { swapSummaryListItems, totalFeesListItems }; + }, [swapRoute, destinationAddress]); + + return ( + + + + Confirm swap + + +
+
+ + + +
+ +
+
+ + + +
+
+ +
+ + + +
+
+ +
+ + + + Total fee + + + + + {swapRoute?.formattedTotalFeesUSD} + + + + +
    + {totalFeesListItems.map((item) => ( +
  • + {item.title} + + + {item.value} + +
  • + ))} +
+
+ +
    + {swapSummaryListItems.map((item) => ( +
  • + {item.title} + + + {item.value} + +
  • + ))} +
+
+
+
+ + + +
+ ); +}; diff --git a/packages/ui/src/react/components/dialogs/swap-quote-route-select-dialog.tsx b/packages/ui/src/react/components/dialogs/swap-quote-route-select-dialog.tsx new file mode 100644 index 0000000..8789263 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/swap-quote-route-select-dialog.tsx @@ -0,0 +1,66 @@ +import { TimerIcon } from "lucide-react"; +import { cn, formatTokenAmount } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import type { UseSwapQuoteReturn } from "../../hooks/use-swap-quote"; +import { pathLabel, RoutePriorityRibbon, StackedProviderLogos } from "../composable/route-provider-parts"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; + +export const SwapQuoteRouteSelectDialog = ({ + routes, + selectedRoute, +}: { + routes: UseSwapQuoteReturn["routes"]; + selectedRoute: UseSwapQuoteReturn["selectedRoute"]; +}) => { + const modal = useModal["routeIndex"]>(); + + return ( + + + + Select route + + +
+ {routes?.map((route) => { + const providers = route?.route?.providers ?? []; + const isSelected = route?.routeIndex === selectedRoute?.routeIndex; + return ( +
+ + +
+ ); + })} +
+
+
+ ); +}; diff --git a/packages/ui/src/react/components/dialogs/wallet-chain-select-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-chain-select-dialog.tsx new file mode 100644 index 0000000..6b2b0ef --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-chain-select-dialog.tsx @@ -0,0 +1,108 @@ +"use client"; + +import { type Chain, getChainConfig } from "@swapkit/helpers"; +import { AlertTriangleIcon } from "lucide-react"; +import { useState } from "react"; +import { cn } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import { isExperimentalChainForWallet } from "../../lib/experimental-wallets"; +import { useWalletsConfig } from "../../swapkit-config-context"; +import type { WalletDescriptor } from "../../types"; +import { ChainIcon } from "../simple/chain-icon"; +import { WalletIcon } from "../simple/wallet-icon"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; + +export function WalletChainSelectDialog({ + wallet, + chains, + defaultChain, + showDeviceHint, +}: { + wallet: WalletDescriptor; + chains: Chain[]; + defaultChain?: Chain; + showDeviceHint?: boolean; +}) { + const modal = useModal(); + const { isDev } = useWalletsConfig(); + const initialChain = defaultChain && chains.includes(defaultChain) ? defaultChain : chains[0]; + // biome-ignore lint/style/noNonNullAssertion: chains is always non-empty + const [selectedChain, setSelectedChain] = useState(initialChain!); + + const chainConfig = getChainConfig(selectedChain); + + return ( + + + + + + Connect {wallet.displayName} + + + +

+ {wallet.displayName} only supports connecting one chain at a time. Please select the chain you want to + connect. +

+ + {showDeviceHint && ( +
+ +

+ Make sure the {chainConfig?.name ?? selectedChain} app is open + on your device before connecting. +

+
+ )} + +
+ {chains.map((chain) => { + const config = getChainConfig(chain); + const isSelected = chain === selectedChain; + const isExperimental = isDev && isExperimentalChainForWallet(wallet.walletOption, chain); + + return ( + + + + + + {config?.name ?? chain} + {isExperimental && ( + + Development only — not supported in production + + )} + + + ); + })} +
+ + + + +
+
+ ); +} diff --git a/packages/ui/src/react/components/dialogs/wallet-chains-config.ts b/packages/ui/src/react/components/dialogs/wallet-chains-config.ts new file mode 100644 index 0000000..1761423 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-chains-config.ts @@ -0,0 +1,16 @@ +import { Chain } from "@swapkit/helpers"; + +// Widget supported EVM chains - matches API_SUPPORTED_CHAINS from swapkit-context.tsx +export const WIDGET_SUPPORTED_EVM_CHAINS = [ + Chain.Ethereum, + Chain.Arbitrum, + Chain.Avalanche, + Chain.Base, + Chain.BinanceSmartChain, + Chain.Berachain, + Chain.Gnosis, + Chain.Monad, + Chain.Optimism, + Chain.Polygon, + Chain.XLayer, +] as const; diff --git a/packages/ui/src/react/components/dialogs/wallet-connect-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-connect-dialog.tsx new file mode 100644 index 0000000..6ca9f08 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-connect-dialog.tsx @@ -0,0 +1,814 @@ +"use client"; + +import { + type Chain, + type DerivationPathArray, + type EIP6963AnnounceProviderEvent, + getChainConfig, + WalletOption, +} from "@swapkit/helpers"; +import { + CheckIcon, + ChevronDownIcon, + ChevronRightIcon, + KeyRoundIcon, + ListFilterIcon, + PlusCircleIcon, + SearchIcon, + UploadIcon, + WalletMinimalIcon, + XIcon, +} from "lucide-react"; +import { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { toast } from "sonner"; +import { match } from "ts-pattern"; +import { cn } from "../../../lib/utils"; +import { useMediaQuery } from "../../hooks/use-media-query"; +import { showModal, useModal } from "../../hooks/use-modal"; +import { filterExperimentalChainsForWallet, isExperimentalWallet } from "../../lib/experimental-wallets"; +import { useWalletsConfig } from "../../swapkit-config-context"; +import { API_SUPPORTED_CHAINS, useSwapKit, useSwapKitStore } from "../../swapkit-context"; +import type { WalletDescriptor } from "../../types"; +import { ChainFilterPopover } from "../composable/chain-filter-popover"; +import { ChainFilterSheet } from "../composable/chain-filter-sheet"; +import { ChainIcon } from "../simple/chain-icon"; +import { WalletIcon } from "../simple/wallet-icon"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Input } from "../ui/input"; +import { SWAPKIT_WIDGET_TOASTER_ID } from "../ui/sonner"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip"; +import { WalletChainSelectDialog } from "./wallet-chain-select-dialog"; +import { WIDGET_SUPPORTED_EVM_CHAINS } from "./wallet-chains-config"; +import { supportsXpubDerivation } from "./wallet-derive-address-dialog"; +import { + discoverEIP6963Wallets, + eip6963ToDescriptor, + getWalletOptionForEIP6963, + staticWalletToDescriptor, +} from "./wallet-utils"; + +const SINGLE_CHAIN_CONNECT_WALLETS = new Set([WalletOption.LEDGER, WalletOption.TREZOR]); + +const WALLET_GROUPS = { + "Browser Extensions": [ + WalletOption.BITGET, + WalletOption.BRAVE, + WalletOption.COINBASE_WEB, + WalletOption.CTRL, + WalletOption.KEEPKEY_BEX, + WalletOption.KEPLR, + WalletOption.LEAP, + WalletOption.METAMASK, + WalletOption.OKX, + WalletOption.ONEKEY, + WalletOption.PASSKEYS, + WalletOption.PHANTOM, + WalletOption.RADIX_WALLET, + WalletOption.TALISMAN, + ], + "Hardware Wallets": [WalletOption.KEEPKEY, WalletOption.LEDGER, WalletOption.TREZOR], + "Mobile Wallets": [ + WalletOption.COINBASE_MOBILE, + WalletOption.OKX_MOBILE, + WalletOption.TRUSTWALLET_WEB, + WalletOption.VULTISIG, + WalletOption.WALLETCONNECT, + WalletOption.XAMAN, + ], + Other: [WalletOption.KEYSTORE], +}; + +const FEATURED_WALLETS = [ + WalletOption.METAMASK, + WalletOption.CTRL, + WalletOption.COINBASE_WEB, + WalletOption.KEYSTORE, + WalletOption.LEDGER, + WalletOption.TREZOR, + WalletOption.BRAVE, + WalletOption.OKX, +]; + +export const ALL_WALLET_OPTIONS = Array.from(new Set([...Object.values(WALLET_GROUPS).flat(), ...FEATURED_WALLETS])); + +function RequiredChainBanner({ + requiredChain, + requiredFor, + filterIsApplied, + onApply, + onDismiss, +}: { + requiredChain: Chain; + /** Whether the banner is asking the user to connect the *input* chain (what they're paying from) or the *output* chain (where the swap settles). */ + requiredFor: "input" | "output"; + filterIsApplied: boolean; + onApply: () => void; + onDismiss: () => void; +}) { + const requiredCfg = getChainConfig(requiredChain); + const chainName = requiredCfg?.name ?? requiredChain; + const headline = requiredFor === "input" ? `You're swapping from ${chainName}` : `Your swap pays out to ${chainName}`; + const subtitle = requiredFor === "input" ? "Pick a wallet that holds it." : "Pick a wallet that supports it."; + return ( +
+ +
+ {headline} + {subtitle} +
+ {filterIsApplied ? ( + + + Filter on + + ) : ( + + )} + +
+ ); +} + +export function WalletConnectDialog({ + requiredChain, + requiredFor = "output", +}: { + requiredChain?: Chain; + requiredFor?: "input" | "output"; +} = {}) { + const modal = useModal(); + const { getWalletExtendedPublicKey } = useSwapKit(); + const { enabledWallets, isWalletAllowed, isChainAllowed, isDev } = useWalletsConfig(); + const walletChainsMap = useSwapKitStore((state) => state.walletChainsMap); + const [isShowingAllWallets, setIsShowingAllWallets] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const [chainFilterOpen, setChainFilterOpen] = useState(false); + const [selectedChains, setSelectedChains] = useState([]); + // Below 640px the popover crowds the wallet list — switch to a full-screen sheet. + const isMobileChainFilter = useMediaQuery("(max-width: 639px)"); + const [requiredBannerDismissed, setRequiredBannerDismissed] = useState(false); + const [eip6963Wallets, setEip6963Wallets] = useState([]); + const chainFilterTriggerRef = useRef(null); + + const getWalletChains = useCallback( + (wallet: WalletOption): Chain[] => + filterExperimentalChainsForWallet(wallet, walletChainsMap[wallet] ?? [], isDev).filter(isChainAllowed), + [walletChainsMap, isChainAllowed, isDev], + ); + const getStaticWalletDescriptor = useCallback( + (wallet: WalletOption) => + staticWalletToDescriptor(wallet, getWalletChains(wallet), getWalletExtendedPublicKey(wallet)), + [getWalletChains, getWalletExtendedPublicKey], + ); + + // Shown while still loading (chains === undefined) OR has at least one + // direct-signing chain the integrator has enabled. + const hasDirectSigningChains = useCallback( + (wallet: WalletOption): boolean => { + const chains = walletChainsMap[wallet]; + if (chains === undefined) return true; + return filterExperimentalChainsForWallet(wallet, chains, isDev).some(isChainAllowed); + }, + [walletChainsMap, isChainAllowed, isDev], + ); + + // Discover EIP-6963 wallets on mount + useEffect(() => { + const { providers, cleanup } = discoverEIP6963Wallets(); + + // Convert to descriptors + setEip6963Wallets(providers.map((p) => eip6963ToDescriptor(p, [...WIDGET_SUPPORTED_EVM_CHAINS], walletChainsMap))); + + // Continue listening for late announcements + const handleAnnouncement = (event: Event) => { + const e = event as EIP6963AnnounceProviderEvent; + setEip6963Wallets((prev) => { + const existing = prev.find((w) => w.eip6963Info?.uuid === e.detail.info.uuid); + if (existing) return prev; + return [...prev, eip6963ToDescriptor(e.detail, [...WIDGET_SUPPORTED_EVM_CHAINS], walletChainsMap)]; + }); + }; + + window.addEventListener("eip6963:announceProvider", handleAnnouncement); + + return () => { + cleanup(); + window.removeEventListener("eip6963:announceProvider", handleAnnouncement); + }; + }, [walletChainsMap]); + + // Reset state when dialog closes + useEffect(() => { + if (!modal.open) { + setChainFilterOpen(false); + setSelectedChains([]); + setSearchQuery(""); + setIsShowingAllWallets(false); + setRequiredBannerDismissed(false); + } + }, [modal.open]); + + const filteredFeaturedWallets = useMemo(() => { + const allowed = (wallet: WalletOption) => isWalletAllowed(wallet) && hasDirectSigningChains(wallet); + const featured = FEATURED_WALLETS.filter(allowed); + if (featured.length >= 8) return featured; + + const featuredSet = new Set(featured); + const fillOrder: WalletOption[] = [ + WalletOption.WALLETCONNECT, + WalletOption.PHANTOM, + WalletOption.COINBASE_MOBILE, + WalletOption.BITGET, + WalletOption.KEEPKEY, + WalletOption.KEPLR, + WalletOption.TALISMAN, + WalletOption.VULTISIG, + WalletOption.TRUSTWALLET_WEB, + WalletOption.ONEKEY, + ]; + const fillOrderSet = new Set(fillOrder); + const remaining = Object.values(WALLET_GROUPS) + .flat() + .filter((w) => !fillOrderSet.has(w)); + + for (const wallet of [...fillOrder, ...remaining]) { + if (featured.length >= 8) break; + if (!featuredSet.has(wallet) && allowed(wallet)) { + featured.push(wallet); + featuredSet.add(wallet); + } + } + + return featured; + }, [isWalletAllowed, hasDirectSigningChains]); + + const allAvailableChains = useMemo(() => { + const chains = new Set(); + for (const [wallet, walletChains] of Object.entries(walletChainsMap) as [WalletOption, Chain[] | undefined][]) { + if (!isWalletAllowed(wallet)) continue; + if (!walletChains) continue; + for (const chain of filterExperimentalChainsForWallet(wallet, walletChains, isDev)) { + if (isChainAllowed(chain)) chains.add(chain); + } + } + // Sort by real-world importance / market cap so the filter list matches the wallet rows. + return Array.from(chains).sort((a, b) => rankChain(a) - rankChain(b)); + }, [walletChainsMap, isWalletAllowed, isChainAllowed, isDev]); + + // Filter static wallets based on configuration + const filteredStaticWalletGroups = useMemo(() => { + const groupsToFilter = + enabledWallets === "all" + ? WALLET_GROUPS + : Object.entries(WALLET_GROUPS).reduce( + (acc, [groupName, wallets]) => { + const filtered = wallets.filter((w) => enabledWallets.includes(w)); + if (filtered.length > 0) { + acc[groupName as keyof typeof WALLET_GROUPS] = filtered; + } + return acc; + }, + {} as Partial, + ); + + return Object.entries(groupsToFilter) + ?.map(([groupTitle, wallets]) => { + const matchingWallets = wallets?.filter( + (wallet) => + isWalletAllowed(wallet) && + hasDirectSigningChains(wallet) && + wallet.toLowerCase().includes(searchQuery.toLowerCase()), + ); + + if (matchingWallets?.length === 0) return null; + + return { groupTitle, wallets: matchingWallets }; + }) + ?.filter((group) => group !== null); + }, [enabledWallets, searchQuery, isWalletAllowed, hasDirectSigningChains]); + + const filteredEip6963Wallets = useMemo(() => { + return eip6963Wallets.filter((wallet) => { + if (wallet.eip6963Info) { + const mappedOption = getWalletOptionForEIP6963(wallet.eip6963Info); + if (mappedOption && !isWalletAllowed(mappedOption)) return false; + if (mappedOption && !hasDirectSigningChains(mappedOption)) return false; + } + // EIP-6963 descriptors carry their own supportedChains (EVM fallback for + // unmapped providers), so we filter directly rather than via walletChainsMap. + if (!wallet.supportedChains.some(isChainAllowed)) return false; + if (searchQuery.length >= 1 && !wallet.displayName.toLowerCase().includes(searchQuery.toLowerCase())) { + return false; + } + return true; + }); + }, [eip6963Wallets, searchQuery, isWalletAllowed, hasDirectSigningChains, isChainAllowed]); + + return ( + + + + Connect wallet + + + {requiredChain && !requiredBannerDismissed && ( + setSelectedChains([requiredChain])} + onDismiss={() => setRequiredBannerDismissed(true)} + requiredChain={requiredChain} + requiredFor={requiredFor} + /> + )} + +
+
+ setSearchQuery(e.target.value)} + placeholder="Search wallet provider" + value={searchQuery} + /> + +
+ +
+ + {isMobileChainFilter ? ( + + ) : ( + chainFilterOpen && ( + setChainFilterOpen(false)} + selected={selectedChains} + triggerRef={chainFilterTriggerRef} + /> + ) + )} +
+
+ +
+
+ {/* Detected wallets — always visible (first screen and expanded) */} + {filteredEip6963Wallets.length > 0 && ( +
+ Detected +
+ {filteredEip6963Wallets.map((wallet) => ( + + ))} +
+
+ )} + + {/* Popular wallets - first screen only */} + {!isShowingAllWallets && searchQuery.length < 2 && filteredFeaturedWallets.length > 0 && ( +
+ Popular +
+ {filteredFeaturedWallets.map((wallet) => ( + + ))} +
+
+ )} + + {/* All wallets - animated show/hide (detected already rendered above) */} +
= 2 ? "sk-ui-grid-rows-[1fr]" : "sk-ui-grid-rows-[0fr]", + )}> +
+
+ {/* Static wallet groups */} + {filteredStaticWalletGroups?.map(({ groupTitle, wallets }) => { + if (wallets?.length === 0) return null; + + const isKeystoreGroup = wallets?.length === 1 && wallets[0] === WalletOption.KEYSTORE; + const keystoreDescriptor = isKeystoreGroup + ? getStaticWalletDescriptor(WalletOption.KEYSTORE) + : null; + + return ( +
+ {groupTitle} + +
+ {isKeystoreGroup && keystoreDescriptor ? ( + <> + + + + + ) : ( + wallets?.map((wallet) => ( + + )) + )} +
+
+ ); + })} +
+
+
+
+ {/* Fade the last row so the scroll edge visibly "cuts off" a wallet below — a clear "there's more" hint. + Offset by -1rem so it sits flush with the scroll container's visual bottom (which has -mb-4). */} +
+
+ + + +

+ By connecting your wallet, you agree to our{" "} + + Terms of Service + {" "} + and{" "} + + Privacy Policy + +

+
+ +
+ ); +} + +type KeystoreMethod = "upload" | "create" | "import"; + +const KEYSTORE_METHOD_CONFIG: Record = { + create: { icon: , label: "Create Wallet" }, + import: { icon: , label: "Import Phrase" }, + upload: { icon: , label: "Upload Keystore" }, +}; + +type ConnectWallet = ReturnType["connectWallet"]; + +async function connectNonKeystoreWallet({ + connectWallet, + finalChains, + requiredChain, + wallet, + isDev, +}: { + connectWallet: ConnectWallet; + finalChains: Chain[]; + requiredChain?: Chain; + wallet: WalletDescriptor; + isDev: boolean; +}): Promise<"connected" | "cancelled" | "idle"> { + let chains = filterExperimentalChainsForWallet(wallet.walletOption, finalChains, isDev); + + if (SINGLE_CHAIN_CONNECT_WALLETS.has(wallet.walletOption)) { + const { confirmed, data: selectedChain } = await showModal( + , + ); + + // User dismissed the chain-select step (outside click / X / no selection). + // Leave the outer connect-wallet modal open so they can pick a different wallet. + if (!confirmed || !selectedChain) return "idle"; + chains = [selectedChain as Chain]; + } + + const singleChain = chains.length === 1 ? chains[0] : undefined; + + if (wallet.type === "eip6963" && wallet.walletOption === WalletOption.EIP6963 && wallet.eip6963Provider) { + await connectWallet(WalletOption.EIP6963, chains, wallet.eip6963Provider, wallet.eip6963Info); + return "connected"; + } + + if (singleChain && supportsXpubDerivation(singleChain, wallet)) { + const { WalletDeriveAddressDialog } = await import("./wallet-derive-address-dialog"); + const { confirmed, data } = await showModal<{ + address: string; + derivationPath: DerivationPathArray; + index: number; + }>(); + + if (!confirmed) return "cancelled"; + + if (data) { + await connectWallet(wallet.walletOption, chains, undefined, undefined, data.derivationPath, { + address: data.address, + }); + } + + return "connected"; + } + + await connectWallet(wallet.walletOption, chains); + return "connected"; +} + +function WalletConnectButton({ + wallet, + selectedChains, + requiredChain, + keystoreMethod, + detected, +}: { + wallet: WalletDescriptor; + selectedChains: Chain[]; + requiredChain?: Chain; + keystoreMethod?: KeystoreMethod; + detected?: boolean; +}) { + const { connectWallet, isConnectingWallet, walletType } = useSwapKit(); + const { isDev, isChainAllowed } = useWalletsConfig(); + const modal = useModal(); + + // EIP-6963 descriptors carry an unfiltered EVM fallback list. Filtering once + // here keeps the chain stack and the matching-chain count consistent. + const allowedSupportedChains = useMemo( + () => filterExperimentalChainsForWallet(wallet.walletOption, wallet.supportedChains, isDev).filter(isChainAllowed), + [wallet.supportedChains, wallet.walletOption, isChainAllowed, isDev], + ); + + const supportsSelectedChains = + selectedChains.length === 0 || selectedChains.every((c) => allowedSupportedChains.includes(c)); + + const handleWalletClick = useCallback(async () => { + try { + const supportedChains = wallet.supportedChains; + + if (!supportedChains || supportedChains?.length === 0) { + toast.error("This wallet does not support any chains", { + description: "Please try a different wallet.", + toasterId: SWAPKIT_WIDGET_TOASTER_ID, + }); + modal.resolve({ confirmed: false }); + return; + } + + const chainsToConnect = + selectedChains.length > 0 ? supportedChains.filter((c) => selectedChains.includes(c)) : supportedChains; + + const finalChains = chainsToConnect.length > 0 ? chainsToConnect : supportedChains; + + await match({ keystoreMethod, walletOption: wallet.walletOption }) + .with({ keystoreMethod: "create", walletOption: WalletOption.KEYSTORE }, async () => { + const { WalletKeystoreCreateDialog } = await import("./wallet-keystore-create-dialog"); + const { confirmed } = await showModal(); + modal.resolve(confirmed ? { confirmed: true, data: WalletOption.KEYSTORE } : { confirmed: false }); + }) + .with({ keystoreMethod: "import", walletOption: WalletOption.KEYSTORE }, async () => { + const { WalletKeystorePhraseDialog } = await import("./wallet-keystore-phrase-dialog"); + const { confirmed } = await showModal(); + modal.resolve(confirmed ? { confirmed: true, data: WalletOption.KEYSTORE } : { confirmed: false }); + }) + .with({ walletOption: WalletOption.KEYSTORE }, async () => { + const { WalletKeystoreConnectDialog } = await import("./wallet-keystore-connect-dialog"); + const { confirmed } = await showModal(); + modal.resolve(confirmed ? { confirmed: true, data: WalletOption.KEYSTORE } : { confirmed: false }); + }) + .otherwise(async () => { + const result = await connectNonKeystoreWallet({ connectWallet, finalChains, isDev, requiredChain, wallet }); + + if (result === "connected") modal.resolve({ confirmed: true, data: wallet.walletOption }); + if (result === "cancelled") modal.resolve({ confirmed: false }); + }); + } catch { + toast.error("Failed to connect your wallet", { + description: "Make sure your wallet is connected and accessible by the browser.", + toasterId: SWAPKIT_WIDGET_TOASTER_ID, + }); + modal.resolve({ confirmed: false }); + } + }, [connectWallet, modal, wallet, selectedChains, requiredChain, keystoreMethod, isDev]); + + const methodConfig = keystoreMethod ? KEYSTORE_METHOD_CONFIG[keystoreMethod] : null; + const isSingleChain = SINGLE_CHAIN_CONNECT_WALLETS.has(wallet.walletOption); + const matchingChains = + selectedChains.length === 0 + ? allowedSupportedChains + : allowedSupportedChains.filter((c) => selectedChains.includes(c)); + const displayName = methodConfig ? methodConfig.label : wallet.displayName; + + if (!supportsSelectedChains) { + return ( + + ); + } + + return ( + + ); +} + +// Rank map derived from API_SUPPORTED_CHAINS, which is already ordered by real-world +// importance / market cap. Chains not in the list land at the end in a stable order. +const CHAIN_RANK = new Map(API_SUPPORTED_CHAINS.map((chain, index) => [chain, index])); + +function rankChain(chain: Chain): number { + return CHAIN_RANK.get(chain) ?? Number.MAX_SAFE_INTEGER; +} + +function ChainStack({ chains, max = 6 }: { chains: Chain[]; max?: number }) { + const sorted = [...chains].sort((a, b) => rankChain(a) - rankChain(b)); + const shown = sorted.slice(0, max); + const extra = sorted.length - shown.length; + return ( + + {shown.map((c, i) => ( + + + + ))} + {extra > 0 && ( + + +{extra} + + )} + + ); +} + +function WalletGroupHeader({ children, count }: { children: ReactNode; count?: number }) { + return ( +
+ {children} + {typeof count === "number" && count > 0 && ( + + {count} + + )} +
+ ); +} diff --git a/packages/ui/src/react/components/dialogs/wallet-derive-address-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-derive-address-dialog.tsx new file mode 100644 index 0000000..ecf39f7 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-derive-address-dialog.tsx @@ -0,0 +1,618 @@ +"use client"; + +import { + type AssetValue, + type Chain, + type DerivationPathArray, + derivationPathToString, + getChainConfig, + NetworkDerivationPath, + type UTXOChain, + UTXOChains, +} from "@swapkit/helpers"; +import type { GetExtendedPublicKey } from "@swapkit/wallets"; +import { AlertTriangleIcon, CheckIcon, LoaderIcon, RefreshCwIcon } from "lucide-react"; +import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"; +import { cn } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import type { WalletDescriptor } from "../../types"; +import { ChainIcon } from "../simple/chain-icon"; +import { WalletIcon } from "../simple/wallet-icon"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; + +function isUtxoChain(chain: Chain): chain is UTXOChain { + return (UTXOChains as readonly Chain[]).includes(chain); +} + +/** Whether to show the derive-address flow for a given wallet+chain combo. */ +export type WalletDescriptorWithXpub = WalletDescriptor & { getExtendedPublicKey: GetExtendedPublicKey }; + +export function supportsXpubDerivation(chain: Chain, wallet: WalletDescriptor): wallet is WalletDescriptorWithXpub { + return isUtxoChain(chain) && typeof wallet.getExtendedPublicKey === "function"; +} + +// Number of indices derived per batch. Each index expands to 2 rows (receive + change), +// so a batch of 5 renders 10 rows at a time. +const ADDRESS_BATCH_SIZE = 5; + +type DerivedRow = { + index: number; + change: boolean; + path: DerivationPathArray; + pathString: string; + address: string; + balance: AssetValue | null; + balanceLoading: boolean; +}; + +type XpubRequest = { chain: Chain; derivationPath: DerivationPathArray; wallet: WalletDescriptorWithXpub }; + +async function fetchXpub({ request, account }: { request: XpubRequest; account: number }): Promise { + const raw = await request.wallet.getExtendedPublicKey(request.chain, request.derivationPath, { + accountIndex: account, + }); + const xpub = raw?.xpub; + if (!xpub || typeof xpub !== "string") { + console.warn("[derive-address] unexpected getExtendedPublicKey return:", raw); + throw new Error(`Wallet did not return a usable extended public key for account ${account}`); + } + return xpub; +} + +async function deriveBatchFromXpub({ + xpub, + chain, + startIndex, + count, + account, + derivationPath, +}: { + xpub: string; + chain: UTXOChain; + startIndex: number; + count: number; + account: number; + derivationPath: DerivationPathArray; +}): Promise { + const { deriveAddressesFromXpub, getUTXOAddressPath } = await import("@swapkit/toolboxes/utxo"); + const derived = deriveAddressesFromXpub({ accountIndex: account, chain, count, startIndex, xpub }); + + // deriveAddressesFromXpub returns both receiving (change=false) and change (change=true) branches. + // Order pairs so the grid reads: index0/receive, index0/change, index1/receive, … + const rows = derived.map((item) => { + const path = getUTXOAddressPath({ + accountIndex: account, + chain, + change: item.change, + derivationPath, + index: item.index, + }); + const row: DerivedRow = { + address: item.address, + balance: null, + balanceLoading: true, + change: item.change, + index: item.index, + path, + pathString: derivationPathToString(path), + }; + return row; + }); + + rows.sort((a, b) => a.index - b.index || Number(a.change) - Number(b.change)); + return rows; +} + +/** + * Map common hardware-wallet / transport errors into a short, user-facing message. + * Returns null when no specific pattern matched — caller should keep the original message. + */ +function friendlyDeviceError(err: unknown): string | null { + const raw = err instanceof Error ? `${err.name}: ${err.message}` : String(err ?? ""); + const lower = raw.toLowerCase(); + + if (lower.includes("disconnected") || lower.includes("device_disconnected") || lower.includes("no device")) { + return "Device disconnected. Reconnect it, unlock, and open the app for this chain."; + } + if (lower.includes("locked")) { + return "Device is locked. Unlock it and keep the app for this chain open."; + } + if (lower.includes("app is not open") || lower.includes("0x6d02") || lower.includes("0x6e00")) { + return "The wallet app on your device is not open. Open the app for this chain and retry."; + } + if (lower.includes("access denied") || lower.includes("notallowed") || lower.includes("user declined")) { + return "Permission denied at the browser or device prompt. Grant access and retry."; + } + if (lower.includes("busy")) { + return "Device is busy with another request. Wait a moment and retry."; + } + if (lower.includes("timeout") || lower.includes("timed out")) { + return "Device didn't respond in time. Reconnect and retry."; + } + return null; +} + +async function fetchBalance({ chain, address }: { chain: UTXOChain; address: string }): Promise { + try { + const { getUtxoToolbox } = await import("@swapkit/toolboxes/utxo"); + const toolbox = getUtxoToolbox(chain); + const balances = await toolbox.getBalance(address, true); + return balances?.[0] ?? null; + } catch (error) { + console.warn(`[derive-address] balance fetch failed for ${address}:`, error); + return null; + } +} + +export function WalletDeriveAddressDialog({ wallet, chain }: { wallet: WalletDescriptorWithXpub; chain: Chain }) { + const modal = useModal<{ address: string; derivationPath: DerivationPathArray; index: number }>(); + + const [rows, setRows] = useState([]); + const [selectedRowId, setSelectedRowId] = useState(null); + const [loadingMore, setLoadingMore] = useState(false); + const [initialLoading, setInitialLoading] = useState(true); + const [error, setError] = useState(null); + const [showChange, setShowChange] = useState(true); + const [jumpIndex, setJumpIndex] = useState(""); + const [account, setAccount] = useState(0); + const [accountDraft, setAccountDraft] = useState("0"); + + const accountInputId = useId(); + const jumpInputId = useId(); + + // xpub is cached per-account: switching accounts triggers one extra device call + // for that account's xpub, then every derive on that account is local. + const xpubByAccount = useRef>(new Map()); + const initialLoadStarted = useRef(false); + const rowRefs = useRef>(new Map()); + // Queue a one-shot scroll-into-view for the row we expect to land in rows. + // Tracked by (index, change) because the exact pathString isn't known synchronously — + // derivation uses SDK helpers that are lazy-loaded with the toolbox. + const scrollTargetRef = useRef<{ index: number; change: boolean } | null>(null); + // Remember the last attempted load so the Retry button can re-run exactly that call. + const lastAttemptRef = useRef<{ startIndex: number } | null>(null); + const [retrying, setRetrying] = useState(false); + + const chainConfig = getChainConfig(chain); + const derivationPath = NetworkDerivationPath[chain] as DerivationPathArray; + + const loadMore = useCallback( + async (startIndex: number) => { + if (!isUtxoChain(chain)) return; + lastAttemptRef.current = { startIndex }; + try { + // Fetch xpub once per account — subsequent derives at that account are local. + let xpub = xpubByAccount.current.get(account); + if (!xpub) { + xpub = await fetchXpub({ account, request: { chain, derivationPath, wallet } }); + xpubByAccount.current.set(account, xpub); + } + + const newRows = await deriveBatchFromXpub({ + account, + chain, + count: ADDRESS_BATCH_SIZE, + derivationPath, + startIndex, + xpub, + }); + setRows((prev) => [...prev, ...newRows]); + setError(null); + + // Fetch balances in parallel; update each row as it resolves (keyed by pathString to tell receive vs change apart). + for (const row of newRows) { + void fetchBalance({ address: row.address, chain }).then((balance) => { + setRows((prev) => + prev.map((r) => (r.pathString === row.pathString ? { ...r, balance, balanceLoading: false } : r)), + ); + }); + } + } catch (err) { + console.warn("[derive-address] loadMore failed:", err); + const friendly = friendlyDeviceError(err); + const raw = err instanceof Error ? err.message : "Failed to derive addresses"; + setError(friendly ?? raw); + } + }, + [account, chain, derivationPath, wallet], + ); + + const handleRetry = useCallback(async () => { + if (retrying) return; + setRetrying(true); + setError(null); + const attempt = lastAttemptRef.current?.startIndex ?? 0; + await loadMore(attempt); + setRetrying(false); + }, [loadMore, retrying]); + + // Initial batch on mount — ref-guarded to survive React StrictMode double-mount, + // which would otherwise fire two concurrent device calls and trip Ledger's transport lock. + useEffect(() => { + if (initialLoadStarted.current) return; + initialLoadStarted.current = true; + void (async () => { + await loadMore(0); + setInitialLoading(false); + })(); + }, [loadMore]); + + // When the chosen account changes, wipe state and re-derive from the fresh xpub. + const previousAccountRef = useRef(account); + useEffect(() => { + if (previousAccountRef.current === account) return; + previousAccountRef.current = account; + setRows([]); + setSelectedRowId(null); + setError(null); + setInitialLoading(true); + void (async () => { + await loadMore(0); + setInitialLoading(false); + })(); + }, [account, loadMore]); + + // After any derivation that might have produced our scroll target, scroll-select it once. + useEffect(() => { + const target = scrollTargetRef.current; + if (!target) return; + const row = rows.find((r) => r.index === target.index && r.change === target.change); + if (!row) return; + scrollTargetRef.current = null; + setSelectedRowId(row.pathString); + requestAnimationFrame(() => { + rowRefs.current.get(row.pathString)?.scrollIntoView({ behavior: "smooth", block: "center" }); + }); + }, [rows]); + + const handleLoadMore = useCallback(async () => { + setLoadingMore(true); + const nextStartIndex = rows.length ? Math.max(...rows.map((row) => row.index)) + 1 : 0; + await loadMore(nextStartIndex); + setLoadingMore(false); + }, [loadMore, rows]); + + const handleConnect = useCallback(() => { + if (!selectedRowId) return; + const row = rows.find((r) => r.pathString === selectedRowId); + if (!row) return; + modal.resolve({ confirmed: true, data: { address: row.address, derivationPath: row.path, index: row.index } }); + }, [modal, rows, selectedRowId]); + + const formattedBalance = useMemo(() => { + return (row: DerivedRow) => { + if (row.balanceLoading) return "…"; + if (!row.balance) return "0"; + return row.balance.toSignificant(6); + }; + }, []); + + const hasBalance = (row: DerivedRow) => { + if (!row.balance) return false; + try { + return row.balance.gt(0); + } catch { + return Number(row.balance.toSignificant(6)) > 0; + } + }; + + const visibleRows = useMemo(() => (showChange ? rows : rows.filter((r) => !r.change)), [rows, showChange]); + + const selectedRow = useMemo(() => rows.find((r) => r.pathString === selectedRowId) ?? null, [rows, selectedRowId]); + + const handleJumpSubmit = useCallback( + (e: React.FormEvent) => { + e.preventDefault(); + const target = Number.parseInt(jumpIndex, 10); + if (!Number.isFinite(target) || target < 0) return; + + // Queue the scroll+select for when the receive row at `target` exists in state. + scrollTargetRef.current = { change: false, index: target }; + + // If already present, the rows effect will fire on next render thanks to the ref being set. + const existing = rows.find((r) => r.index === target && !r.change); + if (existing) { + setSelectedRowId(existing.pathString); + requestAnimationFrame(() => { + rowRefs.current.get(existing.pathString)?.scrollIntoView({ behavior: "smooth", block: "center" }); + }); + scrollTargetRef.current = null; + return; + } + + // Otherwise derive from current tail up through target, in batches of ADDRESS_BATCH_SIZE. + void (async () => { + setLoadingMore(true); + const maxIndex = rows.length ? Math.max(...rows.map((r) => r.index)) : -1; + let start = maxIndex + 1; + while (start <= target) { + await loadMore(start); + start += ADDRESS_BATCH_SIZE; + } + setLoadingMore(false); + })(); + }, + [jumpIndex, loadMore, rows], + ); + + const handleAccountCommit = useCallback( + (e?: React.FormEvent) => { + e?.preventDefault(); + const next = Number.parseInt(accountDraft, 10); + if (!Number.isFinite(next) || next < 0) { + setAccountDraft(String(account)); + return; + } + if (next === account) return; + setAccount(next); + }, + [account, accountDraft], + ); + + const truncateAddress = (addr: string, lead = 14, trail = 8) => + addr.length <= lead + trail + 1 ? addr : `${addr.slice(0, lead)}…${addr.slice(-trail)}`; + + return ( + + + + + + + Select {chainConfig?.name ?? chain} address + + + +

+ Pick the address to connect. Balances are fetched live from your wallet. +

+ + {/* Control strip — account switcher, jump-to-index, change-path toggle */} +
+
+ +
+ # + handleAccountCommit()} + onChange={(e) => setAccountDraft(e.target.value.replace(/[^0-9]/g, ""))} + placeholder="0" + title="BIP44 account index (slot 2 of m/44'/coin'/account'/change/index)" + value={accountDraft} + /> +
+
+ +
+ +
+ +
+ # + setJumpIndex(e.target.value.replace(/[^0-9]/g, ""))} + placeholder="0" + title="Derive through this receive index and select it" + value={jumpIndex} + /> +
+
+ +
+ +
+
+ + {error && ( +
+ +

{error}

+ +
+ )} + +
+ {initialLoading && rows.length === 0 && ( +
+ + Deriving addresses… +
+ )} + + {visibleRows.map((row) => { + const isSelected = row.pathString === selectedRowId; + const funded = hasBalance(row); + return ( + // biome-ignore lint/a11y/useSemanticElements: button+role=radio keeps rich layout (address, path, balance) inside the clickable region; a native +
+ + {/* Selection summary strip — shows which address will be connected */} +
+ {selectedRow ? ( + <> +
+ Selected + + {truncateAddress(selectedRow.address, 18, 12)} + +
+
+ + {formattedBalance(selectedRow)} {chain} + +
+ + ) : ( + Select an address above + )} +
+ + +
+ + + +
+
+ +
+ ); +} diff --git a/packages/ui/src/react/components/dialogs/wallet-keystore-connect-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-keystore-connect-dialog.tsx new file mode 100644 index 0000000..ec4a0fa --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-keystore-connect-dialog.tsx @@ -0,0 +1,294 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import type { Chain } from "@swapkit/helpers"; +import type { Keystore } from "@swapkit/wallet-keystore"; +import { CheckIcon, UploadIcon } from "lucide-react"; +import { useCallback, useEffect, useId } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; +import { z } from "zod"; +import { cn } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import { captureWidgetError } from "../../sentry"; +import { useSwapKit } from "../../swapkit-context"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "../ui/form"; +import { Input } from "../ui/input"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"; + +const step1Schema = z.object({ + currentStep: z.literal(1), + keystoreFile: z.object({ + file: z.instanceof(File), + keystore: z.object({ + crypto: z.object({ + cipher: z.string(), + cipherparams: z.object({ iv: z.string() }), + ciphertext: z.string(), + kdf: z.string(), + kdfparams: z.object({ c: z.number(), dklen: z.number(), prf: z.string(), salt: z.string() }), + mac: z.string(), + }), + meta: z.string(), + version: z.number(), + }), + }), + password: z.string(), +}); + +const step2Schema = step1Schema.extend({ + currentStep: z.literal(2), + password: z.string().min(1, "Password is required"), +}); + +const step3Schema = step2Schema.extend({ currentStep: z.literal(3) }); + +const keystoreSchema = z.discriminatedUnion("currentStep", [step1Schema, step2Schema, step3Schema]); + +type KeystoreFormData = z.infer; + +export interface WalletKeystoreConnectDialogProps { + selectedChains?: Chain[]; +} + +export function WalletKeystoreConnectDialog({ selectedChains }: WalletKeystoreConnectDialogProps) { + const modal = useModal(); + const fileInputId = useId(); + const { connectKeystore, isConnectingWallet } = useSwapKit(); + + const form = useForm({ + defaultValues: { currentStep: 1, keystoreFile: { file: undefined, keystore: undefined }, password: "" }, + resolver: zodResolver(keystoreSchema), + }); + + // Clear sensitive data when dialog unmounts + useEffect(() => { + return () => { + form.setValue("password", ""); + }; + }, [form]); + + const handleConnectWallet = form.handleSubmit(async (data) => { + if (!data?.password) return; + + try { + const { KEYSTORE_SUPPORTED_CHAINS } = await import("@swapkit/wallet-keystore"); + + // Use selected chains if provided, otherwise use all supported chains + const chainsToConnect = + selectedChains && selectedChains.length > 0 + ? KEYSTORE_SUPPORTED_CHAINS.filter((c) => selectedChains.includes(c)) + : KEYSTORE_SUPPORTED_CHAINS; + + // If filter results in empty (no overlap), fall back to all + const finalChains = chainsToConnect.length > 0 ? chainsToConnect : KEYSTORE_SUPPORTED_CHAINS; + + await connectKeystore({ ...data?.keystoreFile, chains: finalChains }, data?.password); + + // Clear password from memory immediately after successful use + form.setValue("password", ""); + form.setValue("currentStep", 3); + } catch { + form.setError("password", { message: "You used an incorrect password or something went wrong." }); + } + }); + + const handleKeystoreFileChange = useCallback( + async (e: React.ChangeEvent) => { + const keystoreFile = e?.target?.files?.[0]; + + if (!keystoreFile) return; + + try { + form.setValue( + "keystoreFile", + { file: keystoreFile, keystore: JSON.parse(await keystoreFile.text()) as Keystore }, + { shouldValidate: true }, + ); + } catch (error) { + console.error("Error parsing keystore file:", error); + captureWidgetError(error, { category: "wallet", tags: { action: "parse", provider: "keystore" } }); + toast.error("Something went wrong while parsing the keystore file", { + description: "Please check if the file is a valid keystore file", + }); + } + }, + [form], + ); + + const [currentStep, keystoreFile] = form.watch(["currentStep", "keystoreFile"]); + + return ( + + + + Connect keystore wallet + + + form.setValue("currentStep", Number.parseInt(newValue, 10) as 1 | 2 | 3)} + value={currentStep.toString()}> + + 1 && "!sk-ui-bg-accent")} value="1" variant="stepper" /> + 2 && "!sk-ui-bg-accent")} value="2" variant="stepper" /> + = 3 && "!sk-ui-bg-accent")} value="3" variant="stepper" /> + + + +
{ + form.setValue("currentStep", 2); + })}> +
+ + Upload your keystore file to connect your wallet + + +
+ Keystore file + + + +
+ + {keystoreFile?.file && ( +
+ Selected: {keystoreFile?.file?.name} ({(keystoreFile?.file?.size / 1024).toFixed(1)} KB) +
+ )} +
+ + + + + + +
+
+ + +
+
+ + Enter the password for your keystore file + + + {keystoreFile?.file && ( +
+
+ + + Keystore file: {keystoreFile?.file?.name} + +
+
+ )} + + + ( + + Password + + + + + + + + )} + /> + +
+ + + + + + + +
+ + +
+
+ +

Wallet Connected Successfully!

+

+ Your keystore wallet is now connected and ready to use. +

+
+
+ + + + + + +
+
+
+
+ ); +} diff --git a/packages/ui/src/react/components/dialogs/wallet-keystore-create-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-keystore-create-dialog.tsx new file mode 100644 index 0000000..1092d42 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-keystore-create-dialog.tsx @@ -0,0 +1,326 @@ +"use client"; + +import type { Chain } from "@swapkit/helpers"; +import type { Keystore } from "@swapkit/wallet-keystore"; +import { CheckIcon, CopyIcon, DownloadIcon, ShieldAlertIcon } from "lucide-react"; +import { useCallback, useEffect, useId, useRef, useState } from "react"; +import { toast } from "sonner"; +import { cn } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import { useSwapKit } from "../../swapkit-context"; +import { Button } from "../ui/button"; +import { Checkbox } from "../ui/checkbox"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Input } from "../ui/input"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"; + +export interface WalletKeystoreCreateDialogProps { + selectedChains?: Chain[]; +} + +export function WalletKeystoreCreateDialog({ selectedChains }: WalletKeystoreCreateDialogProps) { + const modal = useModal(); + const { connectKeystore } = useSwapKit(); + const checkboxId = useId(); + const passwordInputId = useId(); + const confirmPasswordInputId = useId(); + + const [currentStep, setCurrentStep] = useState(1); + const [phrase, setPhrase] = useState(""); + const [savedPhrase, setSavedPhrase] = useState(false); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [passwordError, setPasswordError] = useState(""); + const [isConnecting, setIsConnecting] = useState(false); + const [keystore, setKeystore] = useState(null); + const [copied, setCopied] = useState(false); + const phraseRef = useRef(""); + + // Generate phrase on mount + useEffect(() => { + let cancelled = false; + void (async () => { + const { generatePhrase } = await import("@swapkit/wallet-keystore"); + const generated = generatePhrase(12); + if (!cancelled) { + phraseRef.current = generated; + setPhrase(generated); + } + })(); + return () => { + cancelled = true; + }; + }, []); + + // Clear sensitive refs and state on unmount + useEffect(() => { + return () => { + phraseRef.current = ""; + setPhrase(""); + setPassword(""); + setConfirmPassword(""); + setKeystore(null); + }; + }, []); + + const phraseWords = phrase ? phrase.split(" ") : []; + + const handleCopyPhrase = useCallback(async () => { + if (!phrase) return; + await navigator.clipboard.writeText(phrase); + setCopied(true); + toast.success("Recovery phrase copied to clipboard", { description: "Auto-clears in 60s. Store it securely." }); + setTimeout(() => setCopied(false), 2000); + // Auto-clear clipboard after 60s, but only if it still contains our phrase + setTimeout(async () => { + try { + const current = await navigator.clipboard.readText(); + if (current === phrase) await navigator.clipboard.writeText(""); + } catch { + // Clipboard read may be blocked; fall back to unconditional clear + try { + await navigator.clipboard.writeText(""); + } catch { + // User denied clipboard access — nothing we can do + } + } + }, 60_000); + }, [phrase]); + + const handleConnect = useCallback(async () => { + if (password.length < 8) { + setPasswordError("Password must be at least 8 characters"); + return; + } + if (password !== confirmPassword) { + setPasswordError("Passwords do not match"); + return; + } + + setPasswordError(""); + + try { + setIsConnecting(true); + setCurrentStep(3); + + const { encryptToKeyStore, KEYSTORE_SUPPORTED_CHAINS } = await import("@swapkit/wallet-keystore"); + + const encrypted = await encryptToKeyStore(phraseRef.current, password); + setKeystore(encrypted); + + const chainsToConnect = + selectedChains && selectedChains.length > 0 + ? KEYSTORE_SUPPORTED_CHAINS.filter((c) => selectedChains.includes(c)) + : KEYSTORE_SUPPORTED_CHAINS; + + const finalChains = chainsToConnect.length > 0 ? chainsToConnect : KEYSTORE_SUPPORTED_CHAINS; + + await connectKeystore( + { chains: finalChains, file: new File([JSON.stringify(encrypted)], "keystore.json"), keystore: encrypted }, + password, + ); + + // Clear sensitive data after successful connection + setPassword(""); + setConfirmPassword(""); + setPhrase(""); + phraseRef.current = ""; + setCurrentStep(4); + } catch { + setPasswordError("Something went wrong while creating the wallet."); + setCurrentStep(2); + // Clear sensitive data even on failure — user may abandon the dialog + setPassword(""); + setConfirmPassword(""); + setPhrase(""); + phraseRef.current = ""; + } finally { + setIsConnecting(false); + } + }, [password, confirmPassword, selectedChains, connectKeystore]); + + const handleDownloadKeystore = useCallback(() => { + if (!keystore) return; + const blob = new Blob([JSON.stringify(keystore, null, 2)], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "keystore.json"; + a.click(); + URL.revokeObjectURL(url); + }, [keystore]); + + return ( + + + + Create new wallet + + + + + 1 && "!sk-ui-bg-accent")} value="1" variant="stepper" /> + 2 && "!sk-ui-bg-accent")} value="2" variant="stepper" /> + 3 && "!sk-ui-bg-accent")} value="3" variant="stepper" /> + = 4 && "!sk-ui-bg-accent")} value="4" variant="stepper" /> + + + {/* Step 1: Generate & Display Phrase */} + +
+
+
+ +
+

+ Write down your recovery phrase +

+

+ This is the only way to recover your wallet. Store it securely and never share it with anyone. +

+
+
+
+ +
+ {phraseWords.map((word, index) => { + const key = `word-${index}-${word}`; + return ( +
+ {index + 1}. + {word} +
+ ); + })} +
+ + + +
+ setSavedPhrase(checked === true)} + /> + +
+
+ + + + + + +
+ + {/* Step 2: Set Password */} + +
+ + Create a password to encrypt your wallet keystore file + + +
+ + { + setPassword(e.target.value); + setPasswordError(""); + }} + placeholder="Enter password (min. 8 characters)..." + type="password" + value={password} + /> +
+ +
+ + { + setConfirmPassword(e.target.value); + setPasswordError(""); + }} + placeholder="Confirm your password..." + type="password" + value={confirmPassword} + /> +
+ + {passwordError &&

{passwordError}

} +
+ + + + + + +
+ + {/* Step 3: Connecting */} + +
+
+
+

Creating and connecting your wallet...

+
+
+ + + {/* Step 4: Success */} + +
+
+ +

Wallet Created Successfully!

+

+ Your new keystore wallet is connected and ready to use. Download your keystore file to access your + wallet in the future. +

+
+ + {keystore && ( + + )} +
+ + + + +
+ + +
+ ); +} diff --git a/packages/ui/src/react/components/dialogs/wallet-keystore-phrase-dialog.tsx b/packages/ui/src/react/components/dialogs/wallet-keystore-phrase-dialog.tsx new file mode 100644 index 0000000..27a4b82 --- /dev/null +++ b/packages/ui/src/react/components/dialogs/wallet-keystore-phrase-dialog.tsx @@ -0,0 +1,294 @@ +"use client"; + +import type { Chain } from "@swapkit/helpers"; +import type { Keystore } from "@swapkit/wallet-keystore"; +import { CheckCircleIcon, CheckIcon, DownloadIcon, XCircleIcon } from "lucide-react"; +import { useCallback, useEffect, useId, useRef, useState } from "react"; +import { cn } from "../../../lib/utils"; +import { useModal } from "../../hooks/use-modal"; +import { useSwapKit } from "../../swapkit-context"; +import { Button } from "../ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog"; +import { Input } from "../ui/input"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs"; +import { Textarea } from "../ui/textarea"; + +export interface WalletKeystorePhraseDialogProps { + selectedChains?: Chain[]; +} + +export function WalletKeystorePhraseDialog({ selectedChains }: WalletKeystorePhraseDialogProps) { + const modal = useModal(); + const { connectKeystore } = useSwapKit(); + const passwordInputId = useId(); + const confirmPasswordInputId = useId(); + + const [currentStep, setCurrentStep] = useState(1); + const [phrase, setPhrase] = useState(""); + const [phraseValid, setPhraseValid] = useState(null); + const [password, setPassword] = useState(""); + const [confirmPassword, setConfirmPassword] = useState(""); + const [passwordError, setPasswordError] = useState(""); + const [isConnecting, setIsConnecting] = useState(false); + const [keystore, setKeystore] = useState(null); + const phraseRef = useRef(""); + // Cache the dynamically-imported keystore module so we don't re-fetch it on every keystroke + const keystoreModuleRef = useRef(null); + + // Clear sensitive refs and state on unmount + useEffect(() => { + return () => { + phraseRef.current = ""; + setPhrase(""); + setPassword(""); + setConfirmPassword(""); + setKeystore(null); + }; + }, []); + + const wordCount = phrase.trim() ? phrase.trim().split(/\s+/).length : 0; + + const handlePhraseChange = useCallback(async (value: string) => { + setPhrase(value); + phraseRef.current = value; + + const trimmed = value.trim(); + if (!trimmed) { + setPhraseValid(null); + return; + } + + if (!keystoreModuleRef.current) { + keystoreModuleRef.current = await import("@swapkit/wallet-keystore"); + } + // Re-read trimmed value from ref to avoid acting on a stale closure if newer keystrokes have arrived + setPhraseValid(keystoreModuleRef.current.validatePhrase(phraseRef.current.trim())); + }, []); + + const handleConnect = useCallback(async () => { + if (password.length < 8) { + setPasswordError("Password must be at least 8 characters"); + return; + } + if (password !== confirmPassword) { + setPasswordError("Passwords do not match"); + return; + } + + setPasswordError(""); + + try { + setIsConnecting(true); + setCurrentStep(3); + + const { encryptToKeyStore, KEYSTORE_SUPPORTED_CHAINS } = await import("@swapkit/wallet-keystore"); + + const encrypted = await encryptToKeyStore(phraseRef.current.trim(), password); + setKeystore(encrypted); + + const chainsToConnect = + selectedChains && selectedChains.length > 0 + ? KEYSTORE_SUPPORTED_CHAINS.filter((c) => selectedChains.includes(c)) + : KEYSTORE_SUPPORTED_CHAINS; + + const finalChains = chainsToConnect.length > 0 ? chainsToConnect : KEYSTORE_SUPPORTED_CHAINS; + + await connectKeystore( + { chains: finalChains, file: new File([JSON.stringify(encrypted)], "keystore.json"), keystore: encrypted }, + password, + ); + + // Clear sensitive data after successful connection + setPassword(""); + setConfirmPassword(""); + setPhrase(""); + phraseRef.current = ""; + } catch { + setPasswordError("Something went wrong while importing the wallet."); + setCurrentStep(2); + // Clear sensitive data even on failure — user may abandon the dialog + setPassword(""); + setConfirmPassword(""); + setPhrase(""); + phraseRef.current = ""; + } finally { + setIsConnecting(false); + } + }, [password, confirmPassword, selectedChains, connectKeystore]); + + const handleDownloadKeystore = useCallback(() => { + if (!keystore) return; + const blob = new Blob([JSON.stringify(keystore, null, 2)], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "keystore.json"; + a.click(); + URL.revokeObjectURL(url); + }, [keystore]); + + return ( + + + + Import wallet from phrase + + + + + 1 && "!sk-ui-bg-accent")} value="1" variant="stepper" /> + 2 && "!sk-ui-bg-accent")} value="2" variant="stepper" /> + = 3 && "!sk-ui-bg-accent")} value="3" variant="stepper" /> + + + {/* Step 1: Enter Phrase */} + +
+ + Enter your 12 or 24 word recovery phrase to import your wallet. + + +